Using Custom Theme in tailwind dynamically only when user clicks on it

38 Views Asked by At

A file “primitives.json” extends the values found in the default Tailwind config

We treat primitives.json as source

We have additional modifiers which specify distinct values in relation to primitives.json These are aliased, and occupy a higher order (eg Primary color in “Summer theme” is passed to the UI. If the User deselects “Summer theme”, Primary reverts to the lower order instance (eg that found in primitives.json)

file heriarchy

now the question is how should i address it : using tailwind custom variants or class variant authority or css variables?

note that primitive.json is a big file with 4000 loc and summer theme also not only changes color ubt also fontsize, fontfamily, border radius, and many more properties so answer accordingly

not able to find best approach for this

1

There are 1 best solutions below

0
On

Using CSS custom properties would meet your requirements.

First, set your Tailwind configuration to read those custom properties:

{
  theme: {
    colors: {
       primary: 'rgb(var(--primary) / <alpha-value>)',
       secondary: 'rgb(var(--secondary) / <alpha-value>)',
    }
  }
}

From here, you have a number of different options.

Option One

Your themes would be JSON files like:

{
  "--primary": '"91 36 222",
  "--secondary": "22 22 22"
}

You would have a function that gets passed a theme object and injects those properties and values into the stylesheet.

const changeTheme = (theme) => {
  Object.keys(theme).forEach((key) => {
    document.documentElement.style.setProperty(key, theme[key])
  })
}

Option Two

Alternatively, you could programatically create a CSS class for each theme with the CSS custom properties defined in there. The output would look something like:

body {
  --primary: 0 0 0;
  --secondary: 223, 41, 53;
}

body.example-theme {
  --primary: 91 36 222;
  --secondary: 22 22 22;
}

Then, you would just add/remove classes to the <body> element based on the selected theme.