Code Monkey home page Code Monkey logo

tailwindcss-variables's Introduction

Test Status Build Status Total Downloads Latest Release License

Tailwind CSS Variables

This package provides an easy way to define CSS variables for your Tailwind CSS project. You can use this package to create custom variables within your Tailwind configuration. This makes it easier to maintain consistency across your CSS, reduces repetition, allows you to configure variables based on various conditions, and eliminates the need to work directly with your CSS files to determine variables.

Similar to the tailwindcss configurations you are used to. It is also possible to define a different group of variables for Dark Mode. Alternatively, it has an API that you can use for your own plugins.

Highlights

  • Variables are as easy as defining tailwindcss colors...
  • You can designate the variables to :root, :host or custom CSS selectors.
  • Variables can be formed through using nested object notation.
  • Different variables can be composed for the Dark Mode.
  • Dark Mode variables are set automatically through the class or media modes on your configuration.
  • Dark Mode custom selector is inherited from Tailwind configuration
  • It allows you to add custom themes while creating your own plugin via the plugin API.
  • Prefix can be defined for variables. (It is useful when using the plugin API)
  • You can configure your own needs such as multi-themes without needing an additional plugin!

Documentation

Language Documentation link
English Documentation
Turkish Dökümantasyon

Version Compatibility

Tailwind CSS Package
2.x 1.x
3.x 2.x

Installation

npm install -D @mertasan/tailwindcss-variables

Playground

Simple example: https://play.tailwindcss.com/hCpcvnGsPx?file=config

Usage

// tailwind.config.js

module.exports = {
  theme: {
    colors: {
        red: {
            50: 'var(--colors-red-50)'
        }
    },
    variables: {
      DEFAULT: {
        sizes: {
          small: '1rem',
          button: {
            size: '2rem'
          }
        },
        colors: {
          red: {
            50: '#ff3232',
          },
        },
      },
      '.container': {
        sizes: {
          medium: '1.5rem',
        },
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')
  ]
}

Output:

:root {
  --sizes-small: 1rem;
  --sizes-button-size: 2rem;
  --colors-red-50: #ff3232
}

.container {
  --sizes-medium: 1.5rem
}

Dark Mode

with the class mode

// tailwind.config.js

module.exports = {

  darkMode: 'class',

  theme: {
    variables: {
      DEFAULT: {
        sizes: {
          small: '1rem',
        },
        colors: {
          red: {
            50: 'red',
          },
        },
      },
      '.container': {
        colors: {
          red: {
            50: 'indigo',
          },
        },
      },
    },
    darkVariables: {
      DEFAULT: {
        colors: {
          red: {
            50: 'blue',
          },
        },
      },
      '.container': {
        colors: {
          red: {
            50: 'green',
          },
        },
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')
  ]
}

Output:

:root {
  --sizes-small: 1rem;
  --colors-red-50: red
}

.container {
  --colors-red-50: indigo
}

:root.dark {
  --colors-red-50: blue
}

:root.dark .container {
  --colors-red-50: green
}

Custom dark selector

Note that the plugin will use your custom selector if enabled in your Tailwind configuration.

// tailwind.config.js

module.exports = {

  darkMode: ['class', '.custom-dark-selector'],

  theme: {
    variables: {
      DEFAULT: {
        colors: {
          red: {
            50: 'red',
          },
        },
      },
    },
    darkVariables: {
      DEFAULT: {
        colors: {
          red: {
            50: 'blue',
          },
        },
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')
  ]
}

Output:

:root {
  --colors-red-50: red
}

:root.custom-dark-selector {
  --colors-red-50: blue
}

with the darkToRoot configuration

If the darkMode configuration is set as 'class' in your tailwindcss configuration, you can change and customize the darkToRoot setting.

// tailwind.config.js

module.exports = {

  darkMode: ['class', '.custom-dark-selector'],

  theme: {
    variables: {
      DEFAULT: {
        sizes: {
          small: '1rem',
        },
        colors: {
          red: {
            50: 'red',
          },
        },
      },
      '.container': {
        colors: {
          red: {
            50: 'indigo',
          },
        },
      },
    },
    darkVariables: {
      DEFAULT: {
        colors: {
          red: {
            50: 'blue',
          },
        },
      },
      '.container': {
        colors: {
          red: {
            50: 'green',
          },
        },
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')({
      darkToRoot: false,
    })
  ]
}

Output:

:root {
    --sizes-small: 1rem;
    --colors-red-50: red
}

.container {
    --colors-red-50: indigo
}

.custom-dark-selector {
    --colors-red-50: blue
}

.custom-dark-selector .container {
    --colors-red-50: green
}

with the media mode

// tailwind.config.js

module.exports = {

  darkMode: 'media',

  theme: {
    variables: {
      DEFAULT: {
        sizes: {
          small: '1rem',
        },
        colors: {
          red: {
            50: 'red',
          },
        },
      },
      '.container': {
        colors: {
          red: {
            50: 'indigo',
          },
        },
      },
    },
    darkVariables: {
      DEFAULT: {
        colors: {
          red: {
            50: 'blue',
          },
        },
      },
      '.container': {
        colors: {
          red: {
            50: 'green',
          },
        },
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')
  ]
}

Output:

:root {
  --sizes-small: 1rem;
  --colors-red-50: red
}

.container {
    --colors-red-50: indigo
}

@media (prefers-color-scheme: dark) {
  :root {
    --colors-red-50: blue
  }

  .container {
    --colors-red-50: green
  }
}

Prefix

// tailwind.config.js

module.exports = {
  theme: {
    variables: {
      DEFAULT: {
        sizes: {
          small: '1rem',
          button: {
            size: '2rem'
          }
        },
        colors: {
          red: {
            50: '#ff3232',
          },
        },
      },
      '.container': {
        sizes: {
          medium: '1.5rem',
        },
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')({
      variablePrefix: 'admin'
    })
  ]
}

Output:

:root {
  --admin-sizes-small: 1rem;
  --admin-sizes-button-size: 2rem;
  --admin-colors-red-50: #ff3232
}

.container {
    --admin-sizes-medium: 1.5rem
}

Nested object notation

// tailwind.config.js

module.exports = {
  theme: {
    variables: {
      DEFAULT: {
        sizes: {
          DEFAULT: '1px',
          small: '1rem',
          admin: {
            DEFAULT: '2px',
            buttons: {
              colors: {
                red: {
                  DEFAULT: '#ffffff',
                  500: '#ff0000',
                  600: '#e60000',
                }
              }
            }
          }
        },
      }
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')
  ]
}
:root {
  --sizes: 1px;
  --sizes-small: 1rem;
  --sizes-admin: 2px;
  --sizes-admin-buttons-colors-red-500: #ff0000;
  --sizes-admin-buttons-colors-red-600: #e60000;
  --sizes-admin-buttons-colors-red: #ffffff
}

Rules for keys of variables

Variable keys can only include designated characters. Other characters will be automatically removed. Because using underscores (_) on objects is allowed, underscores will be transformed into middle dashes (-).

Rule:

/[^a-zA-Z0-9-.]+/gi
Before After
hello[$&+,:;=?@#'<>-^*()%!]WORLD hello-WORLD
hello__world hello-world
css_variables_for-tailwindcss css-variables-for-tailwindcss
foo-bar-1.0 foo-bar-1\.0

Here's an example:

// tailwind.config.js

module.exports = {
  theme: {
    variables: {
      DEFAULT: {
        colors: {
          'hello[$&+,:;=?@#|\'<>-^*()%!]WORLD': '100%',
          underscore_to_dash: '100%',
          'underscore_to_dash-with-dash': '100%',
          auto_dash: '100%',
        },
        sizes: {
          1.5: '1rem',
          xl: {
            '3.0': '2rem',
          },
        },
      },
      '[type=\'button\']': {
        'hello[$&+,:;=?@#|\'<>-^*()%!]WORLD': '100%',
        underscore_to_dash: '100%',
        'underscore_to_dash-with-dash': '100%',
        auto_dash: '100%',
        nested_auto_dash: {
          color_primary: '100%',
        },
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')
  ]
}

Output:

:root {
  --colors-hello-WORLD: 100%;
  --colors-underscore-to-dash: 100%;
  --colors-underscore-to-dash-with-dash: 100%;
  --colors-auto-dash: 100%;
  --sizes-1\.5: 1rem;
  --sizes-xl-3\.0: 2rem
}

[type='button'] {
  --hello-WORLD: 100%;
  --underscore-to-dash: 100%;
  --underscore-to-dash-with-dash: 100%;
  --auto-dash: 100%;
  --nested-auto-dash-color-primary: 100%
}

Helpers

colorVariable()

You can use the colorVariable helper to add text-opacity or bg-opacity to the variables for which colors are defined.

// tailwind.config.js

const colorVariable = require('@mertasan/tailwindcss-variables/colorVariable')

module.exports = {
  theme: {
    screens: false,
    colors: {
      primary: colorVariable('--colors-primary'), // HEX (3 digits)
      secondary: colorVariable('var(--colors-secondary)'), // HEX (6 digits)
      white: '#ffffff', // no variable
      blue: colorVariable('var(--colors-blue)'), // RGB
      red: {
        400: colorVariable('var(--colors-red-400)'), // RGBA
        500: colorVariable('var(--colors-red-500)'), // RGBA
        600: 'var(--colors-red-500)', // RGBA (without using colorVariable() helper)
      },
      gray: 'var(--colors-gray)', // HEX (6 digits) (without using colorVariable() helper)
      green: 'var(--colors-green)', // RGB (without using colorVariable() helper)
    },
    variables: {
      DEFAULT: {
        colors: {
          primary: '#ff0',
          secondary: '#000000',
          gray: '#6B7280',
          blue: 'rgb(0,0,254)',
          red: {
            400: 'rgba(254,0,0,0.5)',
            500: 'rgba(254,0,0,1)',
          },
          green: 'rgb(0,255,0)',
        },
        sizes: {
          small: '10px',
          medium: '2rem',
          large: '100%',
        },
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')({
      colorVariables: true
    })
  ]
}

Purge:

<div class="text-opacity-50 text-primary"></div>
<div class="bg-opacity-50 bg-secondary"></div>
<div class="bg-opacity-50 bg-gray"></div>
<div class="text-opacity-50 text-blue"></div>
<div class="bg-red-400"></div>
<div class="bg-red-500"></div>
<div class="bg-red-600"></div>
<div class="bg-opacity-50 bg-green"></div>
<div class="bg-white bg-opacity-50"></div>

Output:

:root {
  --colors-primary: #ff0;
  --colors-secondary: #000000;
  --colors-gray: #6B7280;
  --colors-blue: rgb(0,0,254);
  --colors-red-400: rgba(254,0,0,0.5);
  --colors-red-500: rgba(254,0,0,1);
  --colors-red-400-rgb: 254,0,0;
  --colors-red-500-rgb: 254,0,0;
  --colors-green: rgb(0,255,0);
  --colors-primary-rgb: 255,255,0;
  --colors-secondary-rgb: 0,0,0;
  --colors-gray-rgb: 107,114,128;
  --colors-blue-rgb: 0,0,254;
  --colors-green-rgb: 0,255,0;
  --sizes-small: 10px;
  --sizes-medium: 2rem;
  --sizes-large: 100%
}

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

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

.text-opacity-50 {
 --tw-text-opacity: 0.5
}

.bg-secondary {
 --tw-bg-opacity: 1;
 background-color: rgba(var(--colors-secondary-rgb), var(--tw-bg-opacity))
}

.bg-white {
 --tw-bg-opacity: 1;
 background-color: rgba(255, 255, 255, var(--tw-bg-opacity))
}

.bg-red-400 {
 --tw-bg-opacity: 1;
 background-color: rgba(var(--colors-red-400-rgb), var(--tw-bg-opacity))
}

.bg-red-500 {
 --tw-bg-opacity: 1;
 background-color: rgba(var(--colors-red-500-rgb), var(--tw-bg-opacity))
}

.bg-red-600 {
  background-color: var(--colors-red-500)
}

.bg-gray {
 background-color: var(--colors-gray)
}

.bg-green {
 background-color: var(--colors-green)
}

.bg-opacity-50 {
 --tw-bg-opacity: 0.5
}

forceRGB

If forceRGB is set to true, no additional variables are created.

Before

// tailwind.config.js

const colorVariable = require('@mertasan/tailwindcss-variables/colorVariable')

module.exports = {
  theme: {
    screens: false,
    colors: {
      green: colorVariable('var(--colors-green)'),
    },
    variables: {
      DEFAULT: {
        colors: {
          green: '#11ff00',
        },
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')({
      colorVariables: true,
    })
  ]
}

Output:

:root {
  --colors-green: #11ff00;
  --colors-green-rgb: 17,255,0
}

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

After

// tailwind.config.js

const colorVariable = require('@mertasan/tailwindcss-variables/colorVariable')

module.exports = {
  theme: {
    screens: false,
    colors: {
      green: colorVariable('var(--colors-green)', true),
    },
    variables: {
      DEFAULT: {
        colors: {
          green: '#11ff00',
        },
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')({
      colorVariables: true,
      forceRGB: true,
    })
  ]
}

Output:

:root {
  --colors-green: 17,255,0;
}

.text-green {
  --tw-text-opacity: 1;
  color: rgba(var(--colors-green), var(--tw-text-opacity))
}

useHost

If useHost is set to true, :host is used instead of :root for variables injection.

Config

// tailwind.config.js

module.exports = {
  theme: {
    variables: {
      DEFAULT: {
        colors: {
          green: '#11ff00',
        },
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')({
      useHost: true,
    })
  ]
}

Output:

:host {
  --colors-green: #11ff00;
}

extendColors for colorVariable

Instead of using each of the colors between the variables as colorVariable('var(--colors-red)'), You can define colors in the extendColors option.

Example:

// tailwind.config.js

module.exports = {
  theme: {
    screens: false,
    colors: {
      white: '#fff',
      green: 'var(--colors-green)',
    },
    variables: {
      DEFAULT: {
        colors: {
          blue: '#0065ff',
          red: '#ff0000',
          green: '#11ff00',
        },
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')({
      colorVariables: true,
      extendColors: {
        blue: 'var(--colors-blue)',
        red: 'var(--colors-red)',
      }
    })
  ]
}

Output:

:root {
  --colors-blue: #0065ff;
  --colors-red: #ff0000;
  --colors-green: #11ff00;
  --colors-blue-rgb: 0,101,255;
  --colors-red-rgb: 255,0,0;
  --colors-green-rgb: 17,255,0
}

.text-white {
  --tw-text-opacity: 1;
  color: rgba(255, 255, 255, var(--tw-text-opacity))
}

.text-green {
  color: var(--colors-green)
}

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

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

.text-opacity-50 {
  --tw-text-opacity: 0.5
}

Example 2 - Using with forceRGB:

// tailwind.config.js

module.exports = {
  theme: {
    screens: false,
    colors: {
      white: '#fff',
      green: 'var(--colors-green)',
    },
    variables: {
      DEFAULT: {
        colors: {
          blue: '#0065ff',
          red: '#ff0000',
          green: '#11ff00',
        },
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables')({
      colorVariables: true,
      forceRGB: true,
      extendColors: {
        blue: 'var(--colors-blue)',
        red: 'var(--colors-red)',
      }
    })
  ]
}

Output:

:root {
  --colors-blue: 0,101,255;
  --colors-red: 255,0,0;
  --colors-green: 17,255,0
}

.text-white {
  --tw-text-opacity: 1;
  color: rgba(255, 255, 255, var(--tw-text-opacity))
}

.text-green {
  color: var(--colors-green)
}

.text-blue {
  --tw-text-opacity: 1;
  color: rgba(var(--colors-blue), var(--tw-text-opacity))
}

.text-red {
  --tw-text-opacity: 1;
  color: rgba(var(--colors-red), var(--tw-text-opacity))
}

.text-opacity-50 {
  --tw-text-opacity: 0.5
}

toBase

By default, variables are added to @tailwind base; styles. If you don't include @tailwind base; styles in your css, set the toBase option to false. In this case, the variables will be added to the @tailwind components; styles.

//...
plugins: [
  require('@mertasan/tailwindcss-variables')({
    toBase: false, // default: true
  })
]
//...

API example for your own plugins

// tailwind.config.js
const plugin = require('tailwindcss/plugin')
const variablesApi = require('@mertasan/tailwindcss-variables/api')

let variableOptions = {
  variablePrefix: 'myplugin'
}

const pluginVariables = {
  DEFAULT: {
    colors: {
      primary: 'black',
      secondary: 'white',
      warning: 'orange',
    },
  },
}

const pluginDarkVariables = {
  DEFAULT: {
    colors: {
      primary: 'red',
      secondary: 'yellow',
      warning: 'green',
    },
  },
}

module.exports = {
  plugins: [
    plugin(function({ addComponents, config }) {

      addComponents(variablesApi.variables(pluginVariables, variableOptions))

      addComponents(variablesApi.darkVariables(pluginDarkVariables, variableOptions, config('darkMode'))) // darkMode: class

    })
  ]
}

Output:

:root {
  --myplugin-colors-primary: black;
  --myplugin-colors-secondary: white;
  --myplugin-colors-warning: orange
}

:root.dark {
  --myplugin-colors-primary: red;
  --myplugin-colors-secondary: yellow;
  --myplugin-colors-warning: green
}

API component helper

You can also use tailwindcss-variables plugin API to register your components.

// tailwind.config.js
const plugin = require('tailwindcss/plugin')
const variablesApi = require('@mertasan/tailwindcss-variables/api')

let variableOptions = {
  variablePrefix: 'myplugin'
}

const pluginVariables = {
  DEFAULT: {
    colors: {
      primary: 'black',
      secondary: 'white',
      warning: 'orange',
    },
  },
}

const pluginDarkVariables = {
  DEFAULT: {
    colors: {
      primary: 'red',
      secondary: 'yellow',
      warning: 'green',
    },
  },
}

module.exports = {
  plugins: [
    plugin(function({ addComponents, config }) {
      const formComponents = {
        select: {
          DEFAULT: {
            backgroundColor: 'var(--myplugin-colors-primary)',
          },
          multi: {
            '&.default-multi': {
              backgroundColor: 'var(--myplugin-colors-secondary)',
            },
            '&.other-multi': {
              backgroundColor: 'var(--myplugin-colors-warning)',
            },
          },
        },
      }

      addComponents(variablesApi.variables(pluginVariables, variableOptions))

      addComponents(variablesApi.darkVariables(pluginDarkVariables, variableOptions, config('darkMode'))) // darkMode: class

      // Automatically register components via API.
      addComponents(variablesApi.getComponents('.form', formComponents))
    })
  ]
}

Output:

:root {
  --myplugin-colors-primary: black;
  --myplugin-colors-secondary: white;
  --myplugin-colors-warning: orange;
}

:root.dark {
  --myplugin-colors-primary: red;
  --myplugin-colors-secondary: yellow;
  --myplugin-colors-warning: green;
}

.form-select {
    background-color: var(--myplugin-colors-primary);
}

.form-select.default-multi {
    background-color: var(--myplugin-colors-secondary);
}

.form-select.other-multi {
    background-color: var(--myplugin-colors-warning);
}

Detailed example of the API

What are the advantages?

Imagine you are creating a form builder (PHP) package for Laravel. In this case, I am sure there will be a lot of styles to customize. Nonetheless, one of the most necessary things is the colors! You'll develop the components with the colors you pick out. Of course these colors can be customized with the vendor:publish command but you can make it simpler for everyone. Users can customize the colors for their own likings and if they wish they can also configure your plugin for the dark mode as well. This way, users don't have to alter the .css or .blade.php files for some small and simple customizations. Thus, they can use your package with up to date components and can adapt to future version updates. If you have read this statement, it means that now you know why this plugin came about. :)

What are the disadvantages?

If you have any ideas, please don't refrain to send a PR.

Resources on this example:

Your own plugin themes:

// myplugin/themes.js
module.exports = (theme) => ({
  themes: {
    DEFAULT: {
      colors: {
        primary: 'black',
        secondary: 'white',
        warning: 'orange',
      },
    }
  }
})

Your own plugin components:

// myplugin/components.js
module.exports = (theme) => ({
  select: {
    DEFAULT: {
      backgroundColor: 'var(--forms-colors-primary)',
    },
    multi: {
      '.default-multi': {
        backgroundColor: 'var(--forms-colors-secondary)',
      },
      '.other-multi': {
        backgroundColor: 'var(--forms-colors-warning)',
      },
    },
  },
})

Your own plugin source:

// myplugin/index.js
const plugin = require('tailwindcss/plugin')
const _ = require('lodash')
const variablesApi = require('@mertasan/tailwindcss-variables/api')
const pluginComponents = require('./components')
const pluginThemes = require('./themes')

module.exports = plugin.withOptions(
  function (options) {
    return function ({addComponents, theme, config}) {

      let variableOptions = {
        variablePrefix: theme('myPlugin.prefix', 'forms')
      };

      addComponents(variablesApi.variables(_.merge(pluginThemes(theme).themes, {DEFAULT: theme('myPlugin.options', {})}), variableOptions))

      let darkVariables = theme('myPlugin.darkOptions', {});
      if (!_.isEmpty(darkVariables)) {
        addComponents(variablesApi.darkVariables(darkVariables, variableOptions, config('darkMode')))
      }

      // Automatically register components via API.
      addComponents(variablesApi.getComponents('.form', pluginComponents(theme)))

    }
  }
)

User config: (tailwind.config.js)

// tailwind.config.js
module.exports = {
  theme: {
    myPlugin: {
      options: {
        colors: {
          primary: 'indigo', // custom color instead of default color
        }
      }
    },
  },
  plugins: [require('my-plugin')],
}

Output:

:root {
  --forms-colors-primary: indigo; /* <<< default color changed via root configuration */
  --forms-colors-secondary: white;
  --forms-colors-warning: orange;
}

.form-select {
    background-color: var(--forms-colors-primary);
}

.form-select .default-multi {
    background-color: var(--forms-colors-secondary);
}

.form-select .other-multi {
    background-color: var(--forms-colors-warning);
}

Based on these examples, it won't be necessary to publish extra .css files for your plugin styles and also, it won't be necessary for the users to sort out your style files to compile your packages.

Examples and tests

I have prepared examples on both helping with the usage and for testing all of the features that's being offered to make sure it works just fine.

Source State
Examples Examples
Plugin API Examples API Examples
Tests Tests

Documents on examples and tests are re-organized on pull-request, push, release and etc. events. For this reason, file paths like require(../index) have been used on the example files. If you were to use the examples, you need to change the relevant lines as require('@mertasan/tailwindcss-variables').

If You Need Help

Please send any questions and issues through GitHub issues. I will try my best to help you.

Contribution

If you are to improve or/and add new features, please feel free to send pull-requests.

License

The MIT License (MIT). Please see License File for more information.

tailwindcss-variables's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar jak3b0 avatar joris-fonck-loreal avatar mertasan avatar mervedenizovali avatar nlemoine 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

tailwindcss-variables's Issues

Replace created variables from another plugin (UI KIT)

Versions:

  • Package Version: 2.6.1
  • Tailwindcss Version: 3.3.2

Question:

Hi, i have a problem.
I'm using Element Plus and I'm trying with your plugin to overwrite a variable for any element.

Eg:
--el-button-bg-color

But when I try to do:

".el-button": { "el-button": { "bg-color": "#000", }, },

Nothing is generated for me until I set the class "el-button" for the ElButton element (already has the required class), but this element already has it

No variables if base layer not used

Versions:

  • Package Version: latest
  • Tailwindcss Version: latest

Description:

I disabled @layer base because preflight styles conflicts with verdor packages
And I don't see any css variable
Why?

Only Default variables are added to output

Versions:

  • Package Version: 2.3.0
  • Tailwindcss Version: 3.0.24

Description:

When setting up my tailwind.config.js only variables default variables are outputted.

    variables: {
      DEFAULT: {
        'svg-logo-text': '#ECF2F4',
      },
      '.container': {
        'svg-logo-text': '#ECF2F4',
      }
    },
    darkVariables: {
      DEFAULT: {
        'svg-logo-text': '#ECF2F4',
      },
      '.container': {
        'svg-logo-text': '#ECF2F4',
      }
    },

Here I only get this output:

:root {
  --svg-logo-text: #ECF2F4;
}

Thanks for taking a look! <3

Update getComponents API method to support DEFAULT at root level

Summary

The getComponents API method is awesome, however it takes the provided selector and concatenates that with each of the keys passed into the method. Whilst this is great, it would be really handy to be able to pass in a object where it has a DEFAULT property key which is used as the selector itself only.

For example, based on the documentation as it stands now, if you use getComponents('.alert', { danger: { DEFAULT: { background: 'red' } } }); you will get .alert-danger { background: red }.

What I am proposing is the ability to use getComponents('.alert', { DEFAULT: { background: 'gray' } }) which should give you .alert { background: gray }. Currently if you use DEFAULT like this, no CSS is added just for the selector .alert.

Here is a full example:

const alert = {
  DEFAULT: {
    background: grey;
    border: 1px solid darkgrey;
  },
  "&.alert-danger": {
    background: pink;
    borderColor: red;
  }
};

addComponents(variablesApi.getComponents('.alert', alert));

Results in:

.alert {
  background: grey;
  border: 1px solid darkgrey;
}

.alert.alert-danger {
  background: pink;
  border-color: red;
}

If it is already possible to achieve the above, it's not something I can work out from the documentation or from playing around with it. But this would be particularly handy; For now I am just using addComponents and building it up myself rather than using getComponents.

Support for PostCSS 7?

Would it work to run with PostCSS

Thanks for a nice plugin!

The plugin is dependent on PostCSS ^8.2.9.

Vue (vue-cli) is stil dependent on PostCSS 7, so Tailwindcss needs to be used with Tailwind's PostCSS 7 compatibility build.
(Added with npm install -D tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9, see https://tailwindcss.com/docs/installation#post-css-7-compatibility-build)

Is PostCSS 8 strict needed for this plugin, or could the dependency by changed to be PostCSS 7 or 8 instead?

Is it possible to get dots working in the variable names?

Versions:

  • Package Version: 2.3.0
  • Tailwindcss Version: 3.1.6

Question:

I'm trying to generate a variable name called --sizes-3.5 (and others like it – e.g. --sizes-0.5). Here's what I've tried:

{
      "0.5": "2px",
      "3.5": "14px",
}

The output however, ignores the '.' – so I just get:

--sizes-05, --sizes-35, etc.

I also tried escaping the dot, but no luck. Any ideas?

Prevent adding `px` for variables that have unquoted (numeric) values

Versions:

  • Package Version: latest
  • Tailwindcss Version: latest

Description:

Steps To Reproduce:

variables: {
      DEFAULT: {
        // body
        'body-color': '#000',
        'body-bg': '#fff',
        'body-font-family': 'var(--font-primary)',
        'body-font-size': '1rem',
        'body-font-weight': 400,
        'body-line-height': 1.5,
      },

produces

    --body-color: #000;
    --body-bg: #fff;
    --body-font-family: var(--font-primary);
    --body-font-size: 1rem;
    --body-font-weight: 400px;
    --body-line-height: 1.5px;

400px, 1.5px - why?
Hot to fix that?

More permissive license

Summary

I'd like to try tailwindcss-variables on a private project, but the strong copyleft license prevents me of doing so. Would you be open to license this project under a more permissive license, like MIT?

Some props not generate css vars

Versions:

  • Package Version: latest
  • Tailwindcss Version: latest

Description:

Steps To Reproduce:

const shadow = {
  xs: '0 0 0 1px rgba(0, 0, 0, 0.05)',
  sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
  base: '0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06)',
  md: '0 4px 6px -1px rgba(0, 0, 0, 0.1),0 2px 4px -1px rgba(0, 0, 0, 0.06)',
  lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -2px rgba(0, 0, 0, 0.05)',
  xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1),0 10px 10px -5px rgba(0, 0, 0, 0.04)',
  '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
  outline: '0 0 0 3px rgba(var(--primary), 0.6)',
  inner: 'inset 0 2px 4px 0 rgba(0,0,0,0.06)',
  none: 'none',
};

module.exports = {
  theme: {
    variables: {
      DEFAULT: {
        shadow,
      },
    },
  },
  plugins: [
    cssVariablesPlugin({
      darkToRoot: true,
      darkSelector: '[data-mode="dark"]',
      colorVariables: true,
    }),
  ],
};

Code above not generate css variables --shadow-xxx.
Why?
No errors.

Workaround:

...Object.keys(shadow).reduce((acc, curr) => {
          return {
            ...acc,
            [`shadow-${curr}`]: shadow[curr],
          };
        }, {}),

Also I have error with start project if config has values like this

  'dark-lg': 'rgba(0, 0, 0, 0.1) 0px 0px 0px 1px, rgba(0, 0, 0, 0.2) 0px 5px 10px, rgba(0, 0, 0, 0.4) 0px 15px 40px',

image

Seems something wrong happens when colorVariables: true, because I see plugin try to make this variables
--shadow-dark-lg-rgb but this is not a color!

darkToRoot: true doesn't seem to be working.

Versions:

  • Package Version: 2.5.1
  • Tailwindcss Version: 3.2.4

Description:

Can't seem to get this to work:

CleanShot 2022-11-25 at 10 07 51

Steps To Reproduce:

Use the Tailwind Play. Set darkToRoot: true.

Toggle the dark mode button in the tailwind play header.

CleanShot 2022-11-25 at 10 09 16

Which adds the 'dark' class on the html element.

Unless I've misunderstood something that should then use the dark mode variables.

Generate Dynamic Custom Properties in Config

Versions:

  • Package Version: 2.6.1
  • Tailwindcss Version: 3.3.3

Question:

I'm trying to create the full suite of Tailwind classes into custom props for a package I'm working on.

I've already created the full color palette which look like so:

:root {
  --colors-inherit: inherit;
  --colors-current: currentColor;
  --colors-transparent: transparent;
  --colors-black: #000;
  --colors-white: #fff;
  --colors-slate-50: #f8fafc;
  --colors-slate-100: #f1f5f9;
  ...
}

Now I want to generate other elements with color props, but I want to use the variable obviously as opposed to the hex code again:

:root {
  --border-black: var(--colors-black);
  --bg-slate-400: var(--colors-slate-400);
  ...
}

It would be supper unproductive to have to change hexes all over the place wherever the color prop is used.

So in my Tailwind Config I have the variables property as a function passing in theme and colors:

variables: (theme, colors) => ({
  DEFAULT: {
    bg: {
      '': ??? // what to do here to loop through colors
    }
  }
})

If I do the following:

bg: {
  '': theme('colors')
}

I'll get all the colors with hex

:root {
  ...
  --bg-slate-400: #94a3b8;
  ...
}

How can I dynamically loop through the colors array and generate vars:

`var(--colors-${color}-${number})`

Thanks

Feature ability to set variables for specific media query

I would like it, and I don't think that I would only like it, to have the ability to insert variables for different resolutions (media query) directly from tailwind.config.js, to be able to use the function @screen or simply @media in the following way: ( Note already works but does not set to :root level)

const defColors = require("tailwindcss/colors");
module.exports = {
	theme: {
		variables: (theme) => ({
			// default variables on all devices
			DEFAULT: {
				white: defColors.white,
			},
			// override variables on certain media query, can use @screen md|lg|xl or @media (min|max-width: value)
			"@screen md": {
				white: 'red',
			}
		}),

	},

};

Example below how it already works and is wrong

:root {
    --colors-white: #fff;
    --colors-white-rgb: 255,255,255;
}

@media (min-width: 768px) {
    --colors-white:red
}

If we look, it does not set at the level of :root {}

Below is an example of how it should be

:root {
    --colors-white: #fff;
    --colors-white-rgb: 255,255,255;
}

@media (min-width: 768px) {
    :root {
        --colors-white:red
    }
}

Why do I ask for this aspect, because for example I want to make a main menu using variables but at the same time on responsive I would like to modify these variables without having to overwrite the variables in the css file and there will probably be many cases when it is necessary to overwrite the variables on responsive

Thank you and I'm sorry that I don't have code as an example by which we can achieve this aspect, it's beyond my powers

Keys are lowered case

Thanks for this library.

Versions:

  • Package Version: 2.3.0
  • Tailwindcss Version: latest

Description:

When using the following config:

  theme: {
    variables: {
      DEFAULT: {
        UPPER: 'red'
      },
    },
  },

It generates it in lower case: --upper: red. The expected behavior is to generate the same key. Thanks.

Issues with text/bg opacity?

Versions:

  • Package Version: 1.0.3
  • Tailwindcss Version: 2.1.1

Question:

I'm not sure if this would even be possible with how Tailwind as a whole is setup to work, but basically when using this plugin it will create a CSS variable like so

--colors-primary: #7868e6;

Which is great, but when using in conjunction with anything related to opacity it doesn't respect that at all

For example

<div class="bg-primary bg-opacity-50"></div>

Doesn't have a background opacity of 50

Of course this could (theoretically) be fixed in userland by setting the variable in tailwindconfig.js like so

colors: {
	primary: {
		DEFAULT: 'var(--colors-primary), var(--tw-bg-opacity)'
	},
}

But then this won't text into account the text-opacity classes

Has anyone managed to figure this out?

Translate DEFAULT-keyword to nothing in nested object notation

When using nestet object notation, DEFAULT doesn't seems to be acknowledged the same way as with Tailwind.

Tailwind generate the colors in this example as: testblue-light, testblue and testblue-darker.
It would be nice if this plugin did the same.

// tailwind.config.js
const colors = {
	testblue: {
		lighter: '#5883BB',
		DEFAULT: '#265796',
		darker: '#184176',
	},
};

module.exports = {
  theme: {
    colors,
    variables: {
      DEFAULT: {
        colors,
      },
    },
  },
  plugins: [
    require('@mertasan/tailwindcss-variables'),
  ],
};

Current output:

:root {
    --colors-testblue-lighter:#5883bb;
    --colors-testblue--d-e-f-a-u-l-t:#265796;
    --colors-testblue-darker:#184176;
}

Desired output:

:root {
    --colors-testblue-lighter:#5883bb;
    --colors-testblue:#265796;
    --colors-testblue-darker:#184176;
}

I use this setup because my primary development is using TailwindCSS as is, with Vue. I want the colors to be declared so Tailwind CSS IntelliSense works with showing colors in VS-Code. (Which mean I can't use variables as Tailwind-colors)
The exported variables are for some external components where I want to use the same colors. (Using PrimeVue).
This is working, so this feature is really just to make the variable-name prettier.

(And thank you very much for this nice plugin!)

Multiple themes with their colorSchemes (dark/light)

Hi.
I recreated myself approach with theming from react-spectrum
Also, I used tailwind.

So, for this I created UIProvider that receive theme and colorScheme props

import lightVars from 'app/styles/themes/default-theme/default-theme-light.vars.module.scss';
import darkVars from 'app/styles/themes/default-theme/default-theme-dark.vars.module.scss';

<UIProvider
  theme={{ light: lightVars, dark: darkVars, large: {}, medium: {}, global: {} }}
  defaultColorScheme="light"
  colorScheme={colorScheme}
  locale="ru"
>
  <Button type="button" onPress={() => setColorScheme(colorSchemeVariant)}>
    change {colorScheme}
  </Button>

  <UIProvider colorScheme="light">
    <div className="bg-primary"> primary </div>
  </UIProvider>
  <UIProvider colorScheme="dark">
    <div className="bg-primary"> primary </div>
  </UIProvider>
  {children}
</UIProvider>

example of content of css module for one of vars files

// dark colors
.theme-dark {
  // primary
  --primary: #7f6b38;
  --primary-active: #ffe5a1;
  --primary-light: #fff3d4;
  --primary-inverse: #000;
  // secondary
  --secondary: #fe7375;
  --secondary-active: #fc8182;
  --secondary-light: #ffecec;
  --secondary-inverse: #fff;
  // success
  --success: #58dd4d;
  --success-active: #77e06e;
  --success-light: #e5ffe3;
  --success-inverse: #000;
  // danger
  --danger: #fe7375;
  --danger-active: #fc8182;
  --danger-light: #ffecec;
  --danger-inverse: #fff;
}

As result I have

<div class="default-theme-dark_vars_theme-dark__dOXcD" style="color-scheme: dark;" lang="ru" dir="ltr">
  <button class="button_Button__6Eykw button_primary__KnYjr button_md__W4hur button_uppercase__XLVuR button_rounded-full__Tadfr" type="button"><span class="button_ButtonContent__5_eVt c-button__content">change dark</span></button>

  <div class="default-theme-light_vars_theme-light__YfrB6" lang="ru" dir="ltr" style="color-scheme: light;">
    <!-- Uses from child - light color scheme -->
    <div class="bg-primary"> primary </div>
  </div>
  <!-- Uses from root - dark color scheme -->
  <div class="bg-primary"> primary </div>
</div>

Your plugin helps a lot to generate from config r g b variants for all css variabled declared inside config.
But how can you implement this idea with your plugin?
Thanks!

No css variable fallback support.

Versions:

  • Package Version: ?.?.?
  • Tailwindcss Version: ?.?.?

Description:

CSS variable fallback not supported.
e.g. https://developer.mozilla.org/en-US/docs/Web/CSS/var#syntax

Steps To Reproduce:

Try to use css fallbacks as per spec.

/* Fallback */
/* In the component's style: */
.component .header {
  color: var(--header-color, blue); /* header-color isn't set, and so remains blue, the fallback value */
}

.component .text {
  color: var(--text-color, black);
}

/* In the larger application's style: */
.component {
  --text-color: #080;
}

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.