A method to contain theme-ui styles & others with SliceMachine Slices

Reece May • August 19, 2021 • 3 min read

tips prismic nextjs

I have been making use of theme-ui for developing my slices in Prismic's SliceMachine. In addition to TailwindCSS I actually find the two work well in this case, as well as being similar.

Granted theme-ui is probably more React than Vue directed, but in the case of Vue I will use Tailwind or Bulma, which will give the same result and ability to split stuff.

Splitting files to target slices. (not splitting hairs)

So there is a way that I noticed early on that you can place all the slice styles in the central theme-ui file theme.js

Basically, you create a new slice, Hero. You make a style entry for that variation. You make a new slice, Features and make that entry. And so on. Noting that you might want to add more variations each slice type.

So what you might end up having, and I did a little bit and why I want/have been moving to this style:


export default { slices: { hero: { default: { // ... a whole bunch of styles }, variation1: { // ... a whole bunch of styles }, variation2: { // ... a whole bunch of styles }, }, feature: { default: { // ... a whole bunch of styles }, variation1: { // ... a whole bunch of styles }, variation2: { // ... a whole bunch of styles }, }, anotherSlice: { default: { // ... a whole bunch of styles }, variation1: { // ... a whole bunch of styles }, variation2: { // ... a whole bunch of styles }, }, content: { default: { // ... a whole bunch of styles }, variation1: { // ... a whole bunch of styles }, variation2: { // ... a whole bunch of styles }, }, } }

So it might get rather long winded. 😐

A solution to the problem

This solution might not tickle the fancy of everyone, but I like it :). So to explain my solution to the problem of too many variations for each slice in the main theme-ui file.

Basically, it is mimicking the pattern of Next.js (by extension React) by placing a style definition inside the slice folder.

export const highlight = {
    default: {
        wrapper: {
            paddingX: ['2', '4'],
            paddingY: ['1', '2'],
            background: `linear-gradient(95deg, var(--distributor-highlight) 30%, rgba(255, 255, 255, 0) 66%)`,
            margin: 'auto',
            textAlign: 'center',
            position: 'relative',
            overflow: 'hidden',
            width: '100%',
        },
    },
}

This is a two fold benefit from my perspective.

Benefit 1

You know where to look if you want to edit that slices styles or need to reference what is going on. You can place some overrides you can reference onto the other styles and so forth.

You don't need to then scroll (or search, I know) for the correct section.

So you end up with a neat directory structure like so:

.
└── slices/
    ├── Hero
    ├── index.js{x}
    ├── model.json
    └── module.theme.js *

You can then import module.theme.js the new file in the directory. Name it what you prefer though.

Benefit 2 !

Your slice is now independent of the rest of the slice library and more reusable.

Why? you ask...

Simple, people are inherently lazy.

And if you have a design pattern or would like a good base to work of for your new slice library, you can just pull a slice in.

Also maybe it works better for some ideas I have too, LOL... 💭 (Let's see how many get this far)

How to make use of this pattern then

You would make use of these individual styles like you would if you split your theme-ui colors, typography and other styles into separate files in the base styles directory.

You would do the following maybe in the main file theme.js:

import { highlight } from "slices/highlight/module.theme";

export default {

    // ... other styles.
    slices: {
        ...highlight,
    },
    //... other styles.
}
/**
 * And when you are using it, it's like this:
 */

<Flex 
    variant="slices.highlight.wrapper" 
>
    Something Here :)
</Flex>

Basic as that. Import, destructure and enjoy.

I hope you enjoyed this short thing, maybe message if you see something wrong.