Giter Club home page Giter Club logo

tailwindcss-theme-swapper's Introduction

tailwindcss-theme-swapper

Extend your tailwind config with CSS Custom Properties and trigger the updating of them with any type of selector or media query.

Requirements

  • Tailwind 1.2

Browser Support

Just needs to support CSS Custom Properties. IE11 can kind of work but only the base theme with something like postcss-preset-env.

Installation

yarn add tailwindcss-theme-swapper
# or
npm install tailwindcss-theme-swapper --save-dev

Try It Out

Minimal

https://play.tailwindcss.com/Gt21fePNvv

Fancier (radix colors, multiple themes)

https://play.tailwindcss.com/jskI9McL20

Usage Example

In your tailwind.config.js:

const themeSwapper = require('tailwindcss-theme-swapper')

module.exports = {
  plugins: [
    themeSwapper({
      themes: [
        // The only required theme is `base`. Every property used in
        // other themes must exist in here.
        {
          name: 'base',
          selectors: [':root'],
          theme: {
            colors: {
              primary: '#f00',
            },
          },
        },
        {
          name: 'dark',
          selectors: ['.dark'],
          mediaQuery: '@media (prefers-color-scheme: dark)',
          theme: {
            colors: {
              primary: '#fff',
            },
          },
        },
        {
          name: 'matrix',
          selectors: ['.matrix'],
          theme: {
            colors: {
              primary: '#0f0',
            },
          },
        },
      ],
    }),
  ],
}

Theme Swapper Properties

{
  // The name of the theme. You only have to name `base`.
  name: 'dark',

  // Apply one of these selectors(?) to an element and all of its children to use that theme.
  // `<div class="dark">`, `<div data-theme="dark">`, `<div dark>`
  selectors: ['.dark', '[data-theme="dark"]', '[dark]', ],

  // If this media query matches the theme will apply to the entire page.
  mediaQuery: '@media (prefers-color-scheme: dark)',

  // This extends your tailwind theme.
  // Only keys/values defined here will be made into custom properties.
  theme: {
    colors: {
      // ...
    },
    spacing: {
      // ...
    },
    borderRadius: {
      // ...
    },
  },
}

Example I:O

Themes Input

const themes = [
  {
    name: 'base',
    selectors: [':root'],
    theme: {
      colors: {
        primary: 'hsl(0 100% 50%)',
      },
      spacing: {
        sm: '3px',
      },
    },
  },
  {
    name: 'dark',
    selectors: [
      '.dark',
      '[dark]',
      '[data-theme="dark"]'
    ],
    mediaQuery: '@media (prefers-color-scheme: dark)',
    theme: {
      colors: {
        primary: 'darkslateblue',
      },
    },
  },
  {
    selectors: ['.lime']
    theme: {
      colors: {
        primary: '#0f0',
      },
    },
  },
]

CSS Output

:root {
  --colors-primary: hsl(0 100% 50%);
  --spacing-sm: 3px
}

.dark, [dark], [data-theme="dark"] {
  --colors-primary: darkslateblue
}

@media (prefers-color-scheme: dark) {
  :root{
    --colors-primary: darkslateblue
  }
}

.lime {
  --colors-primary: #0f0
}

/* ... */

.bg-primary {
  --tw-bg-opacity: 1;
  background-color: color-mix(in srgb, var(--colors-primary), transparent calc(100% - 100% * var(--tw-bg-opacity)))
}

.text-primary {
  --tw-text-opacity: 1;
  background-color: color-mix(in srgb, var(--colors-primary), transparent calc(100% - 100% * var(--tw-text-opacity)))
}

.p-sm {
  padding: var(--spacing-sm)
}

tailwindcss-theme-swapper's People

Contributors

crswll avatar dependabot[bot] avatar rcouto-eiq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

tailwindcss-theme-swapper's Issues

Make it play along with opacity utilities...

With tailwind you can do something like:

{
  primary: '#f00',
}

Which gives you something like:

.text-primary {
  --tw-text-opacity: 1;
  color: rgb(255 0 0 / var(--tw-text-opacity, 1))
}

With custom properties this is more difficult to do. We'd need to essentially translate the hex colors to r g b and do something like this but I don't know if this is too much magic or not (especially if things aren't defined as hex).

:root {
  --colors-primary: 255 0 0;
}

.text-primary {
  --tw-text-opacity: 1;
  color: rgb(var(--colors-primary) / var(--tw-text-opacity, 1));
}

This will be useful. Will definitely need some logic around if we should do this for a given value or not.

const colorNameWithVariable = name => ({ opacityVariable, opacityValue }) => {
  if (opacityValue !== undefined) {
    return `rgb(var(--${name}) / ${opacityValue})`
  }
  if (opacityVariable !== undefined) {
    return `rgb(var(--${name}) / var(${opacityVariable}, 1))`
  }
  return `rgb(var(--${name}))`
}

How to use the opacity variant?

Hey, I tried to use your variant with the opacity for the colors. But I don't get it to work.

error in ./src/assets/styles/tailwind.css Syntax Error: TypeError: value.charCodeAt is not a function

Setup:
Tailwindcss 2.0.3 (tried it with 2.0.2)
Postcss: latest (tried it with the versions 7.0.35 and 8.0.0)

TypeScript

Thank you for this plugin!

I was wondering, have you considered converting the plugin to TypeScript or adding types to this repo to support Tailwind's TypeScript configuration?

Screenshot 2024-01-01 at 10 50 30 AM

how to use the swapper

Do you mind sharing how to apply theme swapper to a nuxt.js website or rather provide link to source of the demo so that I can get some hint from there?

npm package

Hey,
would it be an opportunity to publish it via NPM? To me it seems to be a good solution to change themes with tailwindcss.
Greetings

Hex and RGBA values cause one theme not to work

When tailwindcss-theme-swapper gets HEX value for dark theme, and rgba for light theme, dark theme will not work.

For example, with the following tailwindPreset:

import themeSwapper from 'tailwindcss-theme-swapper';
...
plugins: [
themeSwapper({
  themes: [
    {
      name: 'base',
      selectors: ['.light-theme'],
      theme: {
        backgroundColor: {

          'ds-menu': '#ff0000',
        },
      },
      default: true,
    },
    {
      name: 'dark',
      selectors: ['.dark-theme'],
      theme: {
        backgroundColor: {
          'ds-menu': 'rgba(255,255,1,1)',
        },
      },
    },
  ],
})],

This will generate following CSS Custom Properties

.light-theme {
  --background-color-ds-menu: 255 0 0
}

.dark-theme {
  --background-color-ds-menu: rgba(255,255,1,1)
}

and this class

.bg-ds-menu {
  --tw-bg-opacity: 1;
  background-color: rgb(var(--background-color-ds-menu) / var(--tw-bg-opacity))
}

rgb(rgba(...)) is not valid syntax, therefore the dark theme would not work as expected - it would have rgb(0,0,0) value instead of rgba(255,255,1,1).

Safari 10/11 support by using rgb with alpha values

This plugin breaks on Safari 10/11 because those browsers don't support alpha channels inside rgb().
I've taken a look at your code and you choose to use rgb() but also add the alpha value to it in this notation: /[alpha] which older browsers don't understand.

Why not use rgba()? That's supported by all browsers.

Those browsers also don't support the notation with spaces you use, they only support comma's in the rgb value.

Safari 15 support, color-mix over RGB

Hi there! Thanks for creating a beautiful package!

Description

In the past there was a PR Use color-mix over translating color to RGB #47

And we got an issue with Safari 15 support

image
ref: https://caniuse.com/?search=%20color-mix

Question

Is it possible to keep Safari 15 compatibilities? Or make this setting configurable?
Otherwise, we'll have to jump to older version

color used for fill

Without the plugin we can use fill-color in Tailwind and the system will generate css like:
.fill-color { fill: #b9d7fd; }
But using the plugin for the same color will result in the following css entry:
.fill-color { fill: color-mix(in srgb,var(--colors-color),#0000 0); }
where the --colors-color variable is #b9d7fd;
The resulting color is a mix between black and the variable color, which is not the expected result.
It should output the simple color as the fill and not use color-mix. Or if it can't be done without color mix, then the mixing color should be white and not black.

Theme doesn’t get applied to programmatic popovers

Hi there ☺️

For some reason, tailwindcss-theme-swapper doesn’t seem to be applying the theme on popovers that are created programmatically (for example, a datetime picker popover).

In the DOM, the popover creates a new component that lives outside NextJS’ <div id="_next">.
CleanShot 2023-10-25 at 11 53 37@2x

Even if I wrap the component in my theme...
CleanShot 2023-10-25 at 11 55 12@2x

...it doesn’t apply to the popover.
CleanShot 2023-10-25 at 11 55 44@2x

How can this be fixed?

Bug with boxShadow and some properties

If i want override boxShadow properties like :

  • DEFAULT , lg ,layout

Only if this class has used in html :o (like shadow-lg )

if i rename shadow-lg to shadow-test

then lg to test , bug to.

the build bug then my container and lot of other properties doesn't work

My theme :

{ name: 'base', selectors: [':root'], theme: { boxShadow: { xs: '0px 0px 0px 1px rgba(0, 0, 0, 0.05)', sm: '0px 1px 2px rgba(0, 0, 0, 0.05)', base: '0px 1px 3px rgba(0, 0, 0, 0.1), 0px 1px 2px rgba(0, 0, 0, 0.06)', md: '0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -1px rgba(0, 0, 0, 0.06)', lg: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)', xl: '0px 20px 25px -5px rgba(0, 0, 0, 0.1), 0px 10px 10px -5px rgba(0, 0, 0, 0.04)', card: '0px 4px 15px -3px rgba(0, 0, 0, 0.1), 0px 4px 6px -2px rgba(0, 0, 0, 0.05)', none: 'none' }, }, },

    after investigation any boxShadow style generated is like : 

Capture d’écran 2022-05-11 à 15 36 59

JIT support

This plugin doesn't seem to work with the new JIT compiler.
Any ideas how to make this work?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.