Repository: mertasan/tailwindcss-variables Branch: master Commit: 0743d8bb1a28 Files: 127 Total size: 301.4 KB Directory structure: gitextract_64fxtnd3/ ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── ---bug-report.md │ │ ├── ---support-question.md │ │ └── --feature-request.md │ ├── dependabot.yml │ └── workflows/ │ ├── build.yml │ ├── publish.yml │ └── tests.yml ├── .gitignore ├── .npmignore ├── .prettierignore ├── .prettierrc ├── .run/ │ └── tailwindcss-variables-test.run.xml ├── LICENSE ├── README.md ├── README.tr.md ├── __tests__/ │ ├── basic-usage.test.html │ ├── basic-usage.test.js │ ├── color-variable-helper.test.html │ ├── color-variable-helper.test.js │ ├── color-variable-helper2.test.html │ ├── css-selectors.test.html │ ├── css-selectors.test.js │ ├── dark-mode-to-root.test.html │ ├── dark-mode.test.html │ ├── dark-mode.test.js │ ├── extend-colors.test.html │ ├── extend-colors.test.js │ ├── fallback.test.css │ ├── fallback.test.html │ ├── fallback.test.js │ ├── force-rgb.test.html │ ├── force-rgb.test.js │ ├── format-variables.test.html │ ├── format-variables.test.js │ ├── issues.test.html │ ├── issues.test.js │ ├── nested-variables.test.html │ ├── nested-variables.test.js │ ├── plugin-api.test.html │ ├── plugin-api.test.js │ ├── readme.test.html │ ├── readme.test.js │ ├── test.stub │ ├── to-base.test.html │ ├── to-base.test.js │ ├── use-host.test.html │ ├── use-host.test.js │ ├── util/ │ │ └── _utils.js │ ├── variable-prefix.test.html │ └── variable-prefix.test.js ├── api.js ├── colorVariable.js ├── examples/ │ ├── .npmignore │ ├── api-examples/ │ │ ├── advanced/ │ │ │ ├── components.js │ │ │ ├── index.js │ │ │ └── themes.js │ │ ├── readme-source/ │ │ │ ├── components.js │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── tailwind.config.js │ │ │ └── themes.js │ │ ├── simple/ │ │ │ └── index.js │ │ ├── with-components/ │ │ │ ├── components.js │ │ │ └── index.js │ │ ├── with-components-null-selector/ │ │ │ ├── components.js │ │ │ └── index.js │ │ └── with-themes/ │ │ ├── index.js │ │ └── themes.js │ ├── color-variable-helper/ │ │ ├── clean.css │ │ ├── index.html │ │ ├── package.json │ │ ├── style.css │ │ ├── tailwind.config.js │ │ └── tailwind.css │ ├── dark-custom-selector/ │ │ ├── clean.css │ │ ├── index.html │ │ ├── package.json │ │ ├── style.css │ │ ├── tailwind.config.js │ │ └── tailwind.css │ ├── dark-with-class/ │ │ ├── clean.css │ │ ├── index.html │ │ ├── package.json │ │ ├── style.css │ │ ├── tailwind.config.js │ │ └── tailwind.css │ ├── dark-with-class-to-root/ │ │ ├── clean.css │ │ ├── index.html │ │ ├── package.json │ │ ├── style.css │ │ ├── tailwind.config.js │ │ └── tailwind.css │ ├── dark-with-media/ │ │ ├── clean.css │ │ ├── index.html │ │ ├── package.json │ │ ├── style.css │ │ ├── tailwind.config.js │ │ └── tailwind.css │ ├── prefix/ │ │ ├── clean.css │ │ ├── index.html │ │ ├── package.json │ │ ├── style.css │ │ ├── tailwind.config.js │ │ └── tailwind.css │ ├── simple/ │ │ ├── clean.css │ │ ├── index.html │ │ ├── package.json │ │ ├── style.css │ │ ├── tailwind.config.js │ │ └── tailwind.css │ └── use-host/ │ ├── clean.css │ ├── index.html │ ├── package.json │ ├── style.css │ ├── tailwind.config.js │ └── tailwind.css ├── package.json ├── scripts/ │ └── build.js └── src/ ├── helpers.js ├── index.js ├── pluginApi.js └── utils.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] charset = utf-8 end_of_line = lf indent_size = 2 indent_style = space insert_final_newline = true trim_trailing_whitespace = true max_line_length = 120 [*.php] indent_size = 4 [*.md] trim_trailing_whitespace = true [*.test.js] trim_trailing_whitespace = false ================================================ FILE: .eslintignore ================================================ /__tests__/util/_utils.js *.stub .run *.md ================================================ FILE: .eslintrc.json ================================================ { "env": { "jest": true }, "parserOptions": { "ecmaVersion": 2020, "sourceType": "module" }, "extends": [ "prettier" ], "plugins": [ "prettier" ], "rules": { "camelcase": [ "error", { "allow": [ "^unstable_" ] } ], "no-unused-vars": [ 2, { "args": "none", "argsIgnorePattern": "^_" } ], "no-warning-comments": 0, "prettier/prettier": [ "error", { "semi": false, "singleQuote": true, "printWidth": 120, "tabWidth": 2, "useTabs": false, "trailingComma": "es5", "bracketSpacing": true, "parser": "flow", "overrides": [ { "files": [ "**/*.css", "**/*.scss", "**/*.html" ], "options": { "singleQuote": false } } ] } ] } } ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: mertasan ================================================ FILE: .github/ISSUE_TEMPLATE/---bug-report.md ================================================ --- name: "\U0001F4CC Bug report" about: Create a report to help us improve title: '' labels: bug assignees: '' --- ### Versions: - Package Version: #.#.# - Tailwindcss Version: #.#.# ### Description: ### Steps To Reproduce: - … ================================================ FILE: .github/ISSUE_TEMPLATE/---support-question.md ================================================ --- name: "\U0001F914 Support Question" about: I need assistance or clarification on usage of this library title: '' labels: question assignees: '' --- ### Versions: - Package Version: #.#.# - Tailwindcss Version: #.#.# ### Question: ================================================ FILE: .github/ISSUE_TEMPLATE/--feature-request.md ================================================ --- name: "\U0001F389Feature request" about: Suggest an idea for this project title: '' labels: feature request assignees: '' --- ### Summary ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: - package-ecosystem: npm directory: "/" schedule: interval: daily time: "03:00" open-pull-requests-limit: 10 ================================================ FILE: .github/workflows/build.yml ================================================ name: build on: workflow_dispatch: push: paths: - 'examples/**' pull_request: branches: [ master ] release: types: [ published, edited ] jobs: build: if: ${{ github.event_name != 'pull_request' || (github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true) }} runs-on: ubuntu-latest strategy: matrix: node-version: [16] steps: - uses: actions/checkout@v3 - name: Use Node ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - name: Use cached node_modules id: cache-build uses: actions/cache@v3 with: path: node_modules key: nodeModules-${{ hashFiles('**/package-lock.json') }}-${{ matrix.node-version }}-build restore-keys: | nodeModules- - name: Install dependencies if: steps.cache-build.outputs.cache-hit != 'true' run: npm install env: CI: true - name: Building Examples run: npm run build - name: Clean CSS styles of the Examples are building run: npm run build:clean ================================================ FILE: .github/workflows/publish.yml ================================================ name: npm-publish on: workflow_dispatch: release: types: [published, edited] jobs: publish: runs-on: ubuntu-latest strategy: matrix: node-version: [16] steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} registry-url: 'https://registry.npmjs.org' scope: '@mertasan' - name: Use cached node_modules id: cache-publish uses: actions/cache@v3 with: path: node_modules key: nodeModules-${{ hashFiles('**/package-lock.json') }}-${{ matrix.node-version }}-publish restore-keys: | nodeModules- - name: Install dependencies if: steps.cache-publish.outputs.cache-hit != 'true' run: npm install env: CI: true - name: Test run: npm run test env: CI: true - name: Publish run: npm publish env: CI: true NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} ================================================ FILE: .github/workflows/tests.yml ================================================ name: tests on: push: branches: - "**" paths-ignore: - '**.md' pull_request: types: [ready_for_review, synchronize, opened] schedule: - cron: '0 0 * * *' jobs: tests: runs-on: ubuntu-latest strategy: matrix: node-version: [16] steps: - name: Use Node ${{ matrix.node-version }} uses: actions/checkout@v3 - name: Setup node ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} cache: 'npm' - name: Install dependencies if: steps.npm-cache.outputs.cache-hit != 'true' run: npm install env: CI: true - name: Lint run: npm run lint env: CI: true - name: Tests run: npm run test -- --coverage env: CI: true ================================================ FILE: .gitignore ================================================ node_modules/ **/*/package-lock.json yarn.lock coverage/ .DS_Store .idea cache/ *.log ================================================ FILE: .npmignore ================================================ node_modules/ /coverage /examples yarn.lock yarn-error.log .DS_Store .idea .prettierignore .run cache/ ================================================ FILE: .prettierignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* coverage bower_components package.json package-lock.json node_modules/ .npm .idea/ .DS_Store __tests__/* !__tests__/util/* examples/* !examples/**/*.config.js .run .editorconfig cache/ .github/ .eslintrc.json *.md .prettierrc ================================================ FILE: .prettierrc ================================================ { "semi": false, "singleQuote": true, "printWidth": 120, "tabWidth": 2, "useTabs": false, "trailingComma": "es5", "bracketSpacing": true, "parser": "flow", "overrides": [ { "files": [ "**/*.css", "**/*.scss", "**/*.html" ], "options": { "singleQuote": false } } ] } ================================================ FILE: .run/tailwindcss-variables-test.run.xml ================================================ ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2021 Mert Aşan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================

Test Status Build Status Total Downloads Weekly 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](https://tailwindcss.com/docs/dark-mode#customizing-the-class-name) - 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**](./README.tr.md) | ## Version Compatibility | Tailwind CSS | Package | |--------------|----------------| | 2.x | 1.x | | 3.x | 2.x | ## Installation ```cli npm install -D @mertasan/tailwindcss-variables ``` ## Playground Simple example: https://play.tailwindcss.com/hCpcvnGsPx?file=config ## Usage ```javascript // 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:** ```css :root { --sizes-small: 1rem; --sizes-button-size: 2rem; --colors-red-50: #ff3232 } .container { --sizes-medium: 1.5rem } ``` ## Dark Mode ### with the `class` mode ```javascript // 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:** ```css :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](https://tailwindcss.com/docs/dark-mode#customizing-the-class-name). ```javascript // 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:** ```css :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. ```javascript // 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:** ```css :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 ```javascript // 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:** ```css :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 ```javascript // 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:** ```css :root { --admin-sizes-small: 1rem; --admin-sizes-button-size: 2rem; --admin-colors-red-50: #ff3232 } .container { --admin-sizes-medium: 1.5rem } ``` ## Nested object notation ```javascript // 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') ] } ``` ```css :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: ````jsregexp /[^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: ```javascript // 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:** ```css :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. ```javascript // 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:** ```html
``` **Output:** ```css :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 ```javascript // 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:** ```css :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 ```javascript // 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:** ```css :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 ```javascript // tailwind.config.js module.exports = { theme: { variables: { DEFAULT: { colors: { green: '#11ff00', }, }, }, }, plugins: [ require('@mertasan/tailwindcss-variables')({ useHost: true, }) ] } ``` **Output:** ```css :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:** ```javascript // 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:** ```css :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](#forcergb):** ```javascript // 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:** ```css :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. ```js //... plugins: [ require('@mertasan/tailwindcss-variables')({ toBase: false, // default: true }) ] //... ``` - [tailwindcss.com - Functions and directives](https://tailwindcss.com/docs/functions-and-directives#tailwind) ## API example for your own plugins - [Detailed Explanation](#gerçek-kullanım-örneği-detaylı) ```javascript // 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:** ```css :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. ```javascript // 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:** ```css :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:** - [Source](https://github.com/mertasan/tailwindcss-variables/tree/master/examples/api-examples/readme-source) - [test](https://github.com/mertasan/tailwindcss-variables/tree/master/__tests__/readme.test.js) **Your own plugin themes:** ```javascript // myplugin/themes.js module.exports = (theme) => ({ themes: { DEFAULT: { colors: { primary: 'black', secondary: 'white', warning: 'orange', }, } } }) ``` **Your own plugin components:** ```javascript // 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:** ```javascript // 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`) ```javascript // tailwind.config.js module.exports = { theme: { myPlugin: { options: { colors: { primary: 'indigo', // custom color instead of default color } } }, }, plugins: [require('my-plugin')], } ``` **Output:** ```css :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](https://github.com/mertasan/tailwindcss-variables/tree/master/examples) | ![Examples](https://img.shields.io/github/actions/workflow/status/mertasan/tailwindcss-variables/build.yml?branch=master&label=examples) | | [Plugin API Examples](https://github.com/mertasan/tailwindcss-variables/tree/master/examples/api-examples) | ![API Examples](https://img.shields.io/github/actions/workflow/status/mertasan/tailwindcss-variables/build.yml?branch=master&label=api-examples) | | [Tests](https://github.com/mertasan/tailwindcss-variables/tree/master/__tests__) | ![Tests](https://img.shields.io/github/actions/workflow/status/mertasan/tailwindcss-variables/tests.yml?branch=master&label=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](LICENSE.md) for more information. ================================================ FILE: README.tr.md ================================================

Test Status Build Status Total Downloads Weekly Downloads Latest Release License

# Tailwind CSS Variables Bu paket, Tailwind CSS projeniz için CSS değişkenlerini tanımlamanın kolay bir yolunu sunar. Bu paketi, kuyruk rüzgarı yapılandırmanızda özel değişkenler oluşturmak için kullanabilirsiniz. Bu, CSS'nizde tutarlılığı korumanızı kolaylaştırır, tekrarlamayı azaltır, çeşitli koşullara göre değişkenleri yapılandırmanıza olanak tanır ve değişkenleri belirlemek için CSS dosyalarınızla doğrudan çalışma ihtiyacını ortadan kaldırır. Kullanım şekli, tailwindcss'in varsayılan yapılandırmaları ile benzer şekildedir. Dark Mode için ayrı değişken grubu belirleyebilmek, plugin API aracılığıyla kendi eklentilerinize kolayca entegre edebilmek de mümkün. ## Öne çıkan özellikler - Değişkenler, tailwindcss renklerini tanımlamak kadar basit. - Değişkenleri `:root` ya da custom CSS seçicilere tanımlayabilirsiniz. - Değişkenler iç içe geçmiş obje notasyonu (nested object notation) kullanılarak oluşturulabilir. - Dark Mode için farklı değişkenler oluşturulabilir. - Dark Mode değişkenleri, yapılandırmanızdaki `class` ya da `media` moduna göre otomatik tanımlanır. - Dark Mode özel seçicisi, [Tailwind yapılandırmasını](https://tailwindcss.com/docs/dark-mode#customizing-the-class-name) dikkate alır. - Plugin API aracılığıyla kendi eklentinizi oluştururken tema yapılandırması yapmanıza olanak sağlar. - Değişkenler için prefix tanımlaması yapılabilir. (plugin API için faydalı) - Değişkenler, yapılandırma dosyasında veya .css vb. stil dosyalarında kullanılabilir. - Çoklu tema gibi gereksinimlerinizi ek bir eklentiye gerek kalmadan kendiniz yapılandırabilirsiniz! ## Dökümantasyonlar | Dil | Dökümantasyon linki | | --- | --- | | English | [**Documentation**](./README.md) | | Türkçe | Dokümantasyon | ## Versiyon Uyumluluğu | Tailwind CSS | Paket | |--------------|-------| | 2.x | 1.x | | 3.x | 2.x | ## Kurulum ```cli npm install -D @mertasan/tailwindcss-variables ``` ## Canlı önizleme Basit bir örnek: https://play.tailwindcss.com/hCpcvnGsPx?file=config ## Basit Kullanım ```javascript // 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:** ```css :root { --sizes-small: 1rem; --sizes-button-size: 2rem; --colors-red-50: #ff3232 } .container { --sizes-medium: 1.5rem } ``` ## Dark Mode ### `class` modu ile ```javascript // 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:** ```css :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 } ``` #### Özel Dark Mode Seçicisi [Tailwind yapılandırmanızda](https://tailwindcss.com/docs/dark-mode#customizing-the-class-name) etkinleştirilmiş ise, eklentinin özel seçicinizi kullanacağını unutmayın. ```javascript // 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:** ```css :root { --colors-red-50: red } :root.custom-dark-selector { --colors-red-50: blue } ``` #### `darkToRoot` ayarları ile Eğer tailwindcss yapılandırmanızda `darkMode` eğer `class` olarak tanımlıysa, eklentinin `darkToRoot` ayarını kullanarak özelleştirebilirsiniz. ```javascript // 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:** ```css :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 } ``` ### `media` modu ile ```javascript // 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:** ```css :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 Kullanımı ```javascript // 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:** ```css :root { --admin-sizes-small: 1rem; --admin-sizes-button-size: 2rem; --admin-colors-red-50: #ff3232 } .container { --admin-sizes-medium: 1.5rem } ``` ## İç içe geçmiş obje notasyonu (Nested) ```javascript // 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') ] } ``` ```css :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 } ``` ## Key adlandırma kuralları Değişken keyleri yalnızca belirli karakterlere sahip olabilir. Diğer karakterler otomatik olarak temizlenir. Objelerde alt tire (_) kullanımı mümkün olduğundan, alt tireler de orta çizgiye (-) dönüştürülür. Rule: ````jsregexp /[^a-zA-Z0-9-.]+/gi ```` | öncesi | sonrası | |--------------------------------------|-----------------------------------| | hello[$&+,:;=?@#'<>-^*()%!]WORLD | hello-WORLD | | hello__world | hello-world | | css_variables_for-tailwindcss | css-variables-for-tailwindcss | | foo-bar-1.0 | foo-bar-1\\.0 | İşte bir örnek: ```javascript // 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:** ```css :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% } ``` ## Yardımcı Fonksiyonlar (Helpers) ### `colorVariable()` Renk değişkenlerini `colorVariable` helper fonksiyonunu kullanarak tanımlamanız halinde, renkleri `text-opacity` ya da `bg-opacity` gibi ek classlar ile uyumlu hale getirmeniz mümkün. ```javascript // tailwind.config.js const colorVariable = require('@mertasan/tailwindcss-variables/colorVariable') module.exports = { theme: { screens: false, colors: { primary: colorVariable('--colors-primary'), // HEX (3 haneli) secondary: colorVariable('var(--colors-secondary)'), // HEX (6 haneli) white: '#ffffff', // standart kullanım (output incelemesi için) 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 (colorVariable() yardımcısı kullanmadan) }, gray: 'var(--colors-gray)', // HEX (6 haneli) (colorVariable() yardımcısı kullanmadan) green: 'var(--colors-green)', // RGB (colorVariable() yardımcısı kullanmadan) }, 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:** ```html
``` **Output:** ```css :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 Eğer forceRGB `true` olarak tanımlanırsa ek değişkenler oluşturulmaz. #### Öncesi ```javascript // 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:** ```css :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)) } ``` #### Sonrası ```javascript // 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:** ```css :root { --colors-green: 17,255,0; } .text-green { --tw-text-opacity: 1; color: rgba(var(--colors-green), var(--tw-text-opacity)) } ``` ### colorVariable için extendColors Değişkenler arasındaki renklerin her birisini `colorVariable('var(--colors-red)')` şeklinde kullanmak yerine, renkleri `extendColors` kısmında tanımlayabilirsiniz. **Örnek:** ```javascript // 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:** ```css :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 } ``` **2. Örnek - [forceRGB](#forcergb) ile birlikte kullanımı:** ```javascript // 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:** ```css :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 Varsayılan olarak, değişkenler `@tailwind base;` stillerine eklenir. Eğer projenizin `css` dosyasına `@tailwind base;` stillerini dahil etmiyorsanız, `toBase` seçeneğini `false` durumuna getirebilirsiniz. Bu durumda değişkenler `@tailwind components;` stillerine dahil edilecektir. ```js //... plugins: [ require('@mertasan/tailwindcss-variables')({ toBase: false, // varsayılan: true }) ] //... ``` - [tailwindcss.com - Functions and directives](https://tailwindcss.com/docs/functions-and-directives#tailwind) ## Kendi eklentileriniz için API örneği - [Ayrıntılı açıklama](#gerçek-kullanım-örneği-detaylı) ```javascript // 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:** ```css :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 tailwindcss-variables plugin API'yi bileşenlerinizi kayıt etmek için de kullanabilirsiniz. ```javascript // 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:** ```css :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); } ``` ## Gerçek kullanım örneği (detaylı) **Avantajları neler?** Laravel için bir form oluşturucu (PHP) paketi oluşturduğunuzu hayal edin. Bu durumda özelleştirmeniz gereken birçok stil olacağına eminim. Ancak en gerekli olan şeylerden bir tanesi renkler! Bileşenleri kendi belirlediğiniz renklerle oluşturursunuz. Elbette bu renkler `vendor:publish` komutu ile kullanıcılar tarafından özelleştirilebilir ama bunu herkes için daha basit hale getirebilirsiniz. Kullanıcılar renkleri kendileri yapılandırabilir, isterlerse eklentinizi dark mode için yapılandırabilirler. Böylelikle, kullanıcılar bazı basit değişiklikler için `.css` veya `.blade.php` dosyalarını özelleştirmek zorunda kalmazlar. Bu sayede eklentinizi güncel şablonlarıyla birlikte kullanarak, gelecekteki versiyon güncellemelerine uyum sağlayabilirler. Bu açıklamayı okuduysanız eğer, bu eklentininin ortaya çıkma nedenini artık biliyorsunuz demektir. :) **Dezavantajları neler?** Bir fikriniz varsa eğer, lütfen PR göndermekten çekinmeyin. **Bu örnek ile ilgili kaynaklar:** - [kaynak](https://github.com/mertasan/tailwindcss-variables/tree/master/examples/api-examples/readme-source) - [test](https://github.com/mertasan/tailwindcss-variables/tree/master/__tests__/readme.test.js) **Your own plugin themes:** ```javascript // myplugin/themes.js module.exports = (theme) => ({ themes: { DEFAULT: { colors: { primary: 'black', secondary: 'white', warning: 'orange', }, } } }) ``` **Your own plugin components:** ```javascript // 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:** ```javascript // 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`) ```javascript // tailwind.config.js module.exports = { theme: { myPlugin: { options: { colors: { primary: 'indigo', // custom color instead of default color } } }, }, plugins: [require('my-plugin')], } ``` **Output:** ```css :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); } ``` Bu örnekteki gibi bir kurgu sayesinde, eklentinizin stilleri için, sizin ek .css dosyaları yayınlamanıza, kullanan kişilerin ise paketlerinizi kullanabilmek için stil dosyaları derlemelerine gerek kalmayacak. ## Örnekler ve testler Hem kullanım şekli konusunda yardımcı olması için, hem de sunulan tüm özellikleri test ederek doğru çalıştığından emin olmak için örnekler hazırladım. | Kaynak | Durum | |-------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------| | [Örnekler](https://github.com/mertasan/tailwindcss-variables/tree/master/examples) | ![Örnekler](https://img.shields.io/github/actions/workflow/status/mertasan/tailwindcss-variables/build.yml?branch=master&label=examples) | | [Plugin API örnekleri](https://github.com/mertasan/tailwindcss-variables/tree/master/examples/api-examples) | ![Plugin API örnekleri](https://img.shields.io/github/actions/workflow/status/mertasan/tailwindcss-variables/build.yml?branch=master&label=api-examples) | | [Testler](https://github.com/mertasan/tailwindcss-variables/tree/master/__tests__) | ![Testler](https://img.shields.io/github/actions/workflow/status/mertasan/tailwindcss-variables/tests.yml?branch=master&label=tests) | > Örneklere ve testlere ait dosyalar pull-request, push, release vb. etkinliklerde otomatik olarak yeniden > derlenmektedir. Bu nedenle, örnek dosyalarda `require(../index)` gibi dosya yolları kullanıldı. > Örnekleri kullanacaksanız eğer, ilgili yerleri `require('@mertasan/tailwindcss-variables')` şeklinde değiştirmeniz gerekiyor. ## Yardım Lütfen GitHub issues aracılığıyla tüm soru ve sorunlarınızı iletin. Size yardımcı olmaya çalışacağım. ## Katkı Herhangi bir özelliği iyileştirir veya yeni özellikler eklerseniz eğer, lütfen pull-request göndermekten çekinmeyin. ## License The MIT License (MIT). Please see [License File](LICENSE.md) for more information. ================================================ FILE: __tests__/basic-usage.test.html ================================================
================================================ FILE: __tests__/basic-usage.test.js ================================================ const tailwindcssVariables = require('../src/index') const utils = require('./util/_utils')(__filename) test('basic usage', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: false, theme: { variables: { DEFAULT: { colors: { black: 'rgb(0, 0, 0)', white: '#ffffff', }, sizes: { small: '10px', medium: '2rem', large: '100%', }, }, '.container': { colors: { primary: 'red', secondary: 'var(--colors-primary)', }, }, }, }, plugins: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :root { + --colors-black: rgb(0, 0, 0); + --colors-white: #ffffff; + --sizes-small: 10px; + --sizes-medium: 2rem; + --sizes-large: 100% + } + .container { + --colors-primary: red; + --colors-secondary: var(--colors-primary) + } " `) }) ================================================ FILE: __tests__/color-variable-helper.test.html ================================================
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
================================================ FILE: __tests__/color-variable-helper.test.js ================================================ const tailwindcssVariables = require('../src/index') const utils = require('./util/_utils')(__filename) const colorVariable = require('../colorVariable') test('colorVariable helper', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content()], darkMode: false, 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 yellow: { 400: colorVariable('var(--colors-yellow-400)'), // RGB DEFAULT: colorVariable('var(--colors-yellow)'), // 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)', yellow: { 400: 'rgb(255,255,0)', DEFAULT: 'rgb(255,255,0)', }, }, sizes: { small: '10px', medium: '2rem', large: '100%', }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, }), ], }) ).toMatchInlineSnapshot(` " + :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-yellow-400: rgb(255,255,0); + --colors-yellow: rgb(255,255,0); + --colors-yellow-400-rgb: 255,255,0; + --colors-yellow-rgb: 255,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% + } + .bg-gray { + background-color: var(--colors-gray) + } + .bg-green { + background-color: var(--colors-green) + } + .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-secondary { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-secondary-rgb), var(--tw-bg-opacity)) + } + .bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)) + } + .bg-yellow { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-yellow-rgb), var(--tw-bg-opacity)) + } + .bg-opacity-50 { + --tw-bg-opacity: 0.5 + } + .text-blue { + --tw-text-opacity: 1; + color: rgba(var(--colors-blue-rgb), var(--tw-text-opacity)) + } + .text-primary { + --tw-text-opacity: 1; + color: rgba(var(--colors-primary-rgb), var(--tw-text-opacity)) + } + .text-opacity-50 { + --tw-text-opacity: 0.5 + } " `) }) test('colorVariable - background and text color', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content()], darkMode: false, theme: { screens: false, colors: { indigo: { 400: colorVariable('var(--colors-indigo-400)', true), // RGBA 500: colorVariable('var(--colors-indigo-500)', true), // RGBA 600: colorVariable('var(--colors-indigo-600)', true), // HEX }, }, variables: { DEFAULT: { colors: { indigo: { 400: 'rgba(254,0,0,1)', 500: 'rgba(254,0,0,0.5)', 600: '#a20606', }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, forceRGB: true, }), ], }, }) ).toMatchInlineSnapshot(` " + .bg-indigo-400 { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-indigo-400), var(--tw-bg-opacity)) + } + .bg-indigo-500 { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-indigo-500), var(--tw-bg-opacity)) + } + .bg-indigo-600 { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-indigo-600), var(--tw-bg-opacity)) + } + .bg-opacity-50 { + --tw-bg-opacity: 0.5 + } + .text-indigo-400 { + --tw-text-opacity: 1; + color: rgba(var(--colors-indigo-400), var(--tw-text-opacity)) + } + .text-indigo-500 { + --tw-text-opacity: 1; + color: rgba(var(--colors-indigo-500), var(--tw-text-opacity)) + } + .text-indigo-600 { + --tw-text-opacity: 1; + color: rgba(var(--colors-indigo-600), var(--tw-text-opacity)) + } + .text-opacity-50 { + --tw-text-opacity: 0.5 + } " `) }) /** * a --tw-bg-opacity must be added to the colors even if the bg-opacity-100 class is not present. */ test('colorVariable - background and text color 2', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content('color-variable-helper2')], darkMode: false, theme: { screens: false, colors: { indigo: { 400: colorVariable('var(--colors-indigo-400)', true), // RGBA 500: colorVariable('var(--colors-indigo-500)', true), // RGBA 600: colorVariable('var(--colors-indigo-600)', true), // HEX }, }, variables: { DEFAULT: { colors: { indigo: { 400: 'rgba(254,0,0,1)', 500: 'rgba(254,0,0,0.5)', 600: '#a20606', }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, forceRGB: true, }), ], }, }) ).toMatchInlineSnapshot(` " + .bg-indigo-400 { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-indigo-400), var(--tw-bg-opacity)) + } + .bg-indigo-500 { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-indigo-500), var(--tw-bg-opacity)) + } + .bg-indigo-600 { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-indigo-600), var(--tw-bg-opacity)) + } + .text-indigo-400 { + --tw-text-opacity: 1; + color: rgba(var(--colors-indigo-400), var(--tw-text-opacity)) + } + .text-indigo-500 { + --tw-text-opacity: 1; + color: rgba(var(--colors-indigo-500), var(--tw-text-opacity)) + } + .text-indigo-600 { + --tw-text-opacity: 1; + color: rgba(var(--colors-indigo-600), var(--tw-text-opacity)) + } " `) }) ================================================ FILE: __tests__/color-variable-helper2.test.html ================================================
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
================================================ FILE: __tests__/css-selectors.test.html ================================================
================================================ FILE: __tests__/css-selectors.test.js ================================================ const tailwindcssVariables = require('../src/index') const utils = require('./util/_utils')(__filename) test('css selectors', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: false, theme: { variables: { '#app': { colors: { black: 'rgb(0, 0, 0)', white: '#ffffff', }, }, 'input[type="text"]': { colors: { primary: 'red', secondary: 'yellow', }, }, '.container': { sizes: { medium: '3rem', }, }, '.container.card': { sizes: { medium: '4rem', }, }, '*,\n*::before,\n*::after': { hello: { world: '100%', }, }, "[type='button'],\n[type='reset']": { colors: { primary: 'blue', secondary: 'green', }, }, }, }, plugins: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + #app { + --colors-black: rgb(0, 0, 0); + --colors-white: #ffffff + } + input[type='text'] { + --colors-primary: red; + --colors-secondary: yellow + } + .container { + --sizes-medium: 3rem + } + .container.card { + --sizes-medium: 4rem + } + *, + *::before, + *::after { + --hello-world: 100% + } + [type='button'], + [type='reset'] { + --colors-primary: blue; + --colors-secondary: green + } " `) }) ================================================ FILE: __tests__/dark-mode-to-root.test.html ================================================
================================================ FILE: __tests__/dark-mode.test.html ================================================
================================================ FILE: __tests__/dark-mode.test.js ================================================ const tailwindcssVariables = require('../src/index') const utils = require('./util/_utils')(__filename) test('only dark variables with default options and `class` mode', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'class', theme: { darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :root.dark { + --colors-primary: #ffffff + } + :root.dark .container { + --colors-secondary: #000000 + } " `) }) test('only dark variables with default options and `media` mode', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'media', theme: { darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + @media (prefers-color-scheme: dark) { + :root { + --colors-primary: #ffffff + } + .container { + --colors-secondary: #000000 + } + } " `) }) test('if the `darkMode` is set to `media`, `darkToRoot` options should not work', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'media', theme: { darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [ tailwindcssVariables({ darkToRoot: true, }), ], }) ).toMatchInlineSnapshot(` " + @media (prefers-color-scheme: dark) { + :root { + --colors-primary: #ffffff + } + .container { + --colors-secondary: #000000 + } + } " `) }) test('only dark variables with darkToRoot option and `class` mode', async () => { expect( await utils.diffOnly({ content: [utils.content('dark-mode-to-root')], darkMode: 'class', theme: { darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [ tailwindcssVariables({ darkToRoot: true, }), ], }) ).toMatchInlineSnapshot(` " + :root.dark { + --colors-primary: #ffffff + } + :root.dark .container { + --colors-secondary: #000000 + } " `) }) test('only dark variables with custom options and `class` mode', async () => { expect( await utils.diffOnly({ content: [utils.content('dark-mode-to-root')], darkMode: ['class', '.custom-dark-selector'], theme: { darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [ tailwindcssVariables({ variablePrefix: 'my-prefix', darkToRoot: true, }), ], }) ).toMatchInlineSnapshot(` " + :root.custom-dark-selector { + --my-prefix-colors-primary: #ffffff + } + :root.custom-dark-selector .container { + --my-prefix-colors-secondary: #000000 + } " `) }) test('only dark variables with variablePrefix and `media` mode', async () => { expect( await utils.diffOnly({ content: [utils.content('dark-mode-to-root')], darkMode: 'media', theme: { darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [ tailwindcssVariables({ variablePrefix: 'my-prefix', }), ], }) ).toMatchInlineSnapshot(` " + @media (prefers-color-scheme: dark) { + :root { + --my-prefix-colors-primary: #ffffff + } + .container { + --my-prefix-colors-secondary: #000000 + } + } " `) }) test('variables and dark variables with default options and `class` mode', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'class', theme: { variables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :root { + --colors-primary: #ffffff + } + .container { + --colors-secondary: #000000 + } + :root.dark { + --colors-primary: #ffffff + } + :root.dark .container { + --colors-secondary: #000000 + } " `) }) test('variables and dark variables with default options and `media` mode', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'media', theme: { variables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :root { + --colors-primary: #ffffff + } + .container { + --colors-secondary: #000000 + } + @media (prefers-color-scheme: dark) { + :root { + --colors-primary: #ffffff + } + .container { + --colors-secondary: #000000 + } + } " `) }) test('variables and dark variables with custom selector and `class` mode', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: ['class', '.custom-dark-selector'], theme: { variables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [tailwindcssVariables()], }) ).toMatchInlineSnapshot(` " + :root { + --colors-primary: #ffffff + } + .container { + --colors-secondary: #000000 + } + :root.custom-dark-selector { + --colors-primary: #ffffff + } + :root.custom-dark-selector .container { + --colors-secondary: #000000 + } " `) }) test('deprecated custom darkSelector', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: ['class', '.custom-dark-selector'], theme: { variables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [tailwindcssVariables({ darkSelector: '.foo', })], }) ).toMatchInlineSnapshot(` " + :root { + --colors-primary: #ffffff + } + .container { + --colors-secondary: #000000 + } + :root.custom-dark-selector { + --colors-primary: #ffffff + } + :root.custom-dark-selector .container { + --colors-secondary: #000000 + } " `) }) test('deprecated custom darkSelector [2]', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: ['class', '.custom-dark-selector'], theme: { variables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [tailwindcssVariables({ darkSelector: null, })], }) ).toMatchInlineSnapshot(` " + :root { + --colors-primary: #ffffff + } + .container { + --colors-secondary: #000000 + } + :root.custom-dark-selector { + --colors-primary: #ffffff + } + :root.custom-dark-selector .container { + --colors-secondary: #000000 + } " `) }) test('deprecated custom darkSelector [3]', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: ['class'], theme: { variables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [tailwindcssVariables({ darkSelector: null, })], }) ).toMatchInlineSnapshot(` " + :root { + --colors-primary: #ffffff + } + .container { + --colors-secondary: #000000 + } + :root.dark { + --colors-primary: #ffffff + } + :root.dark .container { + --colors-secondary: #000000 + } " `) }) test('deprecated custom darkSelector [4]', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: ['class'], theme: { variables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [tailwindcssVariables({ darkSelector: '.foo', })], }) ).toMatchInlineSnapshot(` " + :root { + --colors-primary: #ffffff + } + .container { + --colors-secondary: #000000 + } + :root.foo { + --colors-primary: #ffffff + } + :root.foo .container { + --colors-secondary: #000000 + } " `) }) test('variables and dark variables with darkToRoot option and `class` mode', async () => { expect( await utils.diffOnly({ content: [utils.content('dark-mode-to-root')], darkMode: 'class', theme: { variables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [ tailwindcssVariables({ darkToRoot: true, }), ], }) ).toMatchInlineSnapshot(` " + :root { + --colors-primary: #ffffff + } + .container { + --colors-secondary: #000000 + } + :root.dark { + --colors-primary: #ffffff + } + :root.dark .container { + --colors-secondary: #000000 + } " `) }) test('variables and dark variables with custom options and `class` mode', async () => { expect( await utils.diffOnly({ content: [utils.content('dark-mode-to-root')], darkMode: ['class', '.custom-dark-selector'], theme: { variables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, darkVariables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [ tailwindcssVariables({ variablePrefix: 'my-prefix', darkToRoot: true, }), ], }) ).toMatchInlineSnapshot(` " + :root { + --my-prefix-colors-primary: #ffffff + } + .container { + --my-prefix-colors-secondary: #000000 + } + :root.custom-dark-selector { + --my-prefix-colors-primary: #ffffff + } + :root.custom-dark-selector .container { + --my-prefix-colors-secondary: #000000 + } " `) }) ================================================ FILE: __tests__/extend-colors.test.html ================================================
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
================================================ FILE: __tests__/extend-colors.test.js ================================================ const tailwindcssVariables = require('../src/index') const utils = require('./util/_utils')(__filename) test('extendColors', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content()], darkMode: false, theme: { screens: false, colors: { red: { 600: 'var(--colors-red-600)', 700: 'var(--colors-red-700)', }, }, variables: { DEFAULT: { colors: { white: '#ffffff', red: { 400: 'rgba(254,0,0,0.5)', DEFAULT: 'rgba(254,0,0,1)', 500: 'rgba(254,0,0,1)', 600: 'rgba(205,7,7,1)', 700: 'rgb(186,5,5,1)', }, }, sizes: { small: '1rem', }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, extendColors: { black: '#000000', white: 'var(--colors-white)', red: { 400: 'var(--colors-red-400)', DEFAULT: 'var(--colors-red)', 500: 'var(--colors-red-500)', }, }, }), ], }) ).toMatchInlineSnapshot(` " + :root { + --colors-white: #ffffff; + --colors-red-400: rgba(254,0,0,0.5); + --colors-red-500: rgba(254,0,0,1); + --colors-red-600: rgba(205,7,7,1); + --colors-red-700: rgb(186,5,5,1); + --colors-red: rgba(254,0,0,1); + --colors-red-400-rgb: 254,0,0; + --colors-red-500-rgb: 254,0,0; + --colors-red-600-rgb: 205,7,7; + --colors-red-700-rgb: 186,5,5,1; + --colors-red-rgb: 254,0,0; + --colors-white-rgb: 255,255,255; + --sizes-small: 1rem + } + .bg-black { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)) + } + .bg-red { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-red-rgb), 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-600) + } + .bg-red-700 { + background-color: var(--colors-red-700) + } + .bg-white { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-white-rgb), var(--tw-bg-opacity)) + } + .bg-opacity-50 { + --tw-bg-opacity: 0.5 + } + .text-black { + --tw-text-opacity: 1; + color: rgb(0 0 0 / var(--tw-text-opacity)) + } + .text-red { + --tw-text-opacity: 1; + color: rgba(var(--colors-red-rgb), var(--tw-text-opacity)) + } + .text-red-400 { + --tw-text-opacity: 1; + color: rgba(var(--colors-red-400-rgb), var(--tw-text-opacity)) + } + .text-red-500 { + --tw-text-opacity: 1; + color: rgba(var(--colors-red-500-rgb), var(--tw-text-opacity)) + } + .text-red-600 { + color: var(--colors-red-600) + } + .text-red-700 { + color: var(--colors-red-700) + } + .text-white { + --tw-text-opacity: 1; + color: rgba(var(--colors-white-rgb), var(--tw-text-opacity)) + } + .text-opacity-50 { + --tw-text-opacity: 0.5 + } " `) }) test('extendColors with forceRGB', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content()], darkMode: false, theme: { screens: false, colors: { red: { 600: 'var(--colors-red-600)', 700: 'var(--colors-red-700)', }, }, variables: { DEFAULT: { colors: { white: '#ffffff', red: { 400: 'rgba(254,0,0,0.5)', DEFAULT: 'rgba(254,0,0,1)', 500: 'rgba(254,0,0,1)', 600: 'rgba(205,7,7,1)', 700: 'rgb(186,5,5,1)', }, }, sizes: { small: '1rem', }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, forceRGB: true, extendColors: { black: '#000000', white: 'var(--colors-white)', red: { 400: 'var(--colors-red-400)', DEFAULT: 'var(--colors-red)', 500: 'var(--colors-red-500)', }, }, }), ], }) ).toMatchInlineSnapshot(` " + :root { + --colors-white: 255,255,255; + --colors-red-400: 254,0,0; + --colors-red-500: 254,0,0; + --colors-red-600: 205,7,7; + --colors-red-700: 186,5,5,1; + --colors-red: 254,0,0; + --sizes-small: 1rem + } + .bg-black { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)) + } + .bg-red { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-red), var(--tw-bg-opacity)) + } + .bg-red-400 { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-red-400), var(--tw-bg-opacity)) + } + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-red-500), var(--tw-bg-opacity)) + } + .bg-red-600 { + background-color: var(--colors-red-600) + } + .bg-red-700 { + background-color: var(--colors-red-700) + } + .bg-white { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-white), var(--tw-bg-opacity)) + } + .bg-opacity-50 { + --tw-bg-opacity: 0.5 + } + .text-black { + --tw-text-opacity: 1; + color: rgb(0 0 0 / var(--tw-text-opacity)) + } + .text-red { + --tw-text-opacity: 1; + color: rgba(var(--colors-red), var(--tw-text-opacity)) + } + .text-red-400 { + --tw-text-opacity: 1; + color: rgba(var(--colors-red-400), var(--tw-text-opacity)) + } + .text-red-500 { + --tw-text-opacity: 1; + color: rgba(var(--colors-red-500), var(--tw-text-opacity)) + } + .text-red-600 { + color: var(--colors-red-600) + } + .text-red-700 { + color: var(--colors-red-700) + } + .text-white { + --tw-text-opacity: 1; + color: rgba(var(--colors-white), var(--tw-text-opacity)) + } + .text-opacity-50 { + --tw-text-opacity: 0.5 + } " `) }) test('extendColors (readme)', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content()], darkMode: false, theme: { screens: false, colors: { white: '#fff', green: 'var(--colors-green)', }, variables: { DEFAULT: { colors: { blue: '#0065ff', red: '#ff0000', green: '#11ff00', }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, extendColors: { blue: 'var(--colors-blue)', red: 'var(--colors-red)', }, }), ], }) ).toMatchInlineSnapshot(` " + :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 + } + .bg-blue { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-blue-rgb), var(--tw-bg-opacity)) + } + .bg-green { + background-color: var(--colors-green) + } + .bg-red { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-red-rgb), var(--tw-bg-opacity)) + } + .bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)) + } + .bg-opacity-50 { + --tw-bg-opacity: 0.5 + } + .text-blue { + --tw-text-opacity: 1; + color: rgba(var(--colors-blue-rgb), var(--tw-text-opacity)) + } + .text-green { + color: var(--colors-green) + } + .text-red { + --tw-text-opacity: 1; + color: rgba(var(--colors-red-rgb), var(--tw-text-opacity)) + } + .text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)) + } + .text-opacity-50 { + --tw-text-opacity: 0.5 + } " `) }) test('extendColors with forceRGB (readme)', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content()], darkMode: false, theme: { screens: false, colors: { white: '#fff', green: 'var(--colors-green)', }, variables: { DEFAULT: { colors: { blue: '#0065ff', red: '#ff0000', green: '#11ff00', }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, forceRGB: true, extendColors: { blue: 'var(--colors-blue)', red: 'var(--colors-red)', }, }), ], }) ).toMatchInlineSnapshot(` " + :root { + --colors-blue: 0,101,255; + --colors-red: 255,0,0; + --colors-green: 17,255,0 + } + .bg-blue { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-blue), var(--tw-bg-opacity)) + } + .bg-green { + background-color: var(--colors-green) + } + .bg-red { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-red), var(--tw-bg-opacity)) + } + .bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)) + } + .bg-opacity-50 { + --tw-bg-opacity: 0.5 + } + .text-blue { + --tw-text-opacity: 1; + color: rgba(var(--colors-blue), var(--tw-text-opacity)) + } + .text-green { + color: var(--colors-green) + } + .text-red { + --tw-text-opacity: 1; + color: rgba(var(--colors-red), var(--tw-text-opacity)) + } + .text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)) + } + .text-opacity-50 { + --tw-text-opacity: 0.5 + } " `) }) ================================================ FILE: __tests__/fallback.test.css ================================================ @tailwind base; @tailwind components; @tailwind utilities; @layer components { .component .header { @apply text-red-400; } } ================================================ FILE: __tests__/fallback.test.html ================================================
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
================================================ FILE: __tests__/fallback.test.js ================================================ const tailwindcssVariables = require('../src/index') const utils = require('./util/_utils')(__filename) const colorVariable = require('../colorVariable') test('fallback', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content()], darkMode: false, theme: { screens: false, colors: { red: { 400: 'var(--colors-red-400 red)', 500: 'var(--colors-red red)', 600: colorVariable('var(--header-color, black)'), 700: colorVariable('var(--header-color, black)', true), 800: colorVariable('var(--header-color, black)', false), }, gray: 'var(--header-color, blue)', }, variables: { DEFAULT: { header: { color: '#ffffff', }, colors: { red: { DEFAULT: '#ff0000', 400: '#ff3f3f', }, }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, }), ], }) ).toMatchInlineSnapshot(` " - + :root { + --header-color: #ffffff; + --header-color-rgb: 255,255,255; + --colors-red-400: #ff3f3f; + --colors-red: #ff0000; + --colors-red-400-rgb: 255,63,63; + --colors-red-rgb: 255,0,0 + } + .component .header { + color: var(--colors-red-400 red) + } + .bg-gray { + background-color: var(--header-color, blue) + } + .bg-red-400 { + background-color: var(--colors-red-400 red) + } + .bg-red-500 { + background-color: var(--colors-red red) + } + .bg-red-600 { + --tw-bg-opacity: 1; + background-color: rgba(var(--header-color-rgb, black), var(--tw-bg-opacity)) + } + .bg-red-700 { + --tw-bg-opacity: 1; + background-color: rgba(var(--header-color, black), var(--tw-bg-opacity)) + } + .bg-opacity-50 { + --tw-bg-opacity: 0.5 + } + .text-red-800 { + --tw-text-opacity: 1; + color: rgba(var(--header-color-rgb, black), var(--tw-text-opacity)) + } " `) }) ================================================ FILE: __tests__/force-rgb.test.html ================================================
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
tailwindcss-variables
================================================ FILE: __tests__/force-rgb.test.js ================================================ const tailwindcssVariables = require('../src/index') const utils = require('./util/_utils')(__filename) const colorVariable = require('../colorVariable') test('forceRGB option (enabled)', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content()], darkMode: false, theme: { screens: false, colors: { black: '#000000', white: 'var(--colors-white)', red: { 400: colorVariable('var(--colors-red-400)', true), DEFAULT: colorVariable('var(--colors-red)', true), 500: colorVariable('var(--colors-red-500)', true), }, }, variables: { DEFAULT: { colors: { white: '#ffffff', red: { 400: 'rgba(254,0,0,0.5)', DEFAULT: 'rgba(254,0,0,1)', 500: 'rgba(254,0,0,1)', 600: 'rgba(205,7,7,1)', }, }, sizes: { small: '1rem', }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, forceRGB: true, }), ], }) ).toMatchInlineSnapshot(` " + :root { + --colors-white: 255,255,255; + --colors-red-400: 254,0,0; + --colors-red-500: 254,0,0; + --colors-red-600: 205,7,7; + --colors-red: 254,0,0; + --sizes-small: 1rem + } + .bg-black { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)) + } + .bg-red { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-red), var(--tw-bg-opacity)) + } + .bg-red-400 { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-red-400), var(--tw-bg-opacity)) + } + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-red-500), var(--tw-bg-opacity)) + } + .bg-white { + background-color: var(--colors-white) + } + .bg-opacity-50 { + --tw-bg-opacity: 0.5 + } + .text-black { + --tw-text-opacity: 1; + color: rgb(0 0 0 / var(--tw-text-opacity)) + } + .text-red { + --tw-text-opacity: 1; + color: rgba(var(--colors-red), var(--tw-text-opacity)) + } + .text-red-400 { + --tw-text-opacity: 1; + color: rgba(var(--colors-red-400), var(--tw-text-opacity)) + } + .text-red-500 { + --tw-text-opacity: 1; + color: rgba(var(--colors-red-500), var(--tw-text-opacity)) + } + .text-white { + color: var(--colors-white) + } + .text-opacity-50 { + --tw-text-opacity: 0.5 + } " `) }) test('forceRGB option (disabled)', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content()], darkMode: false, theme: { screens: false, colors: { black: '#000000', white: 'var(--colors-white)', red: { 400: colorVariable('var(--colors-red-400)'), 500: '#ff0000', }, }, variables: { DEFAULT: { colors: { white: '#ffffff', red: { 400: 'rgba(254,0,0,0.5)', 500: 'rgba(254,0,0,1)', }, }, sizes: { small: '1rem', }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, forceRGB: false, // default }), ], }) ).toMatchInlineSnapshot(` " + :root { + --colors-white: #ffffff; + --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-white-rgb: 255,255,255; + --sizes-small: 1rem + } + .bg-black { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / 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: rgb(255 0 0 / var(--tw-bg-opacity)) + } + .bg-white { + background-color: var(--colors-white) + } + .bg-opacity-50 { + --tw-bg-opacity: 0.5 + } + .text-black { + --tw-text-opacity: 1; + color: rgb(0 0 0 / var(--tw-text-opacity)) + } + .text-red-400 { + --tw-text-opacity: 1; + color: rgba(var(--colors-red-400-rgb), var(--tw-text-opacity)) + } + .text-red-500 { + --tw-text-opacity: 1; + color: rgb(255 0 0 / var(--tw-text-opacity)) + } + .text-white { + color: var(--colors-white) + } + .text-opacity-50 { + --tw-text-opacity: 0.5 + } " `) }) test('forceRGB option with extendColors', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content()], darkMode: false, theme: { screens: false, colors: { indigo: '#EC4899', extend: { red: { 400: '#000', }, }, }, variables: { DEFAULT: { colors: { white: '#ffffff', red: { 400: 'rgba(254,0,0,0.5)', DEFAULT: 'rgba(254,0,0,1)', 600: 'rgba(254,0,0,1)', }, }, sizes: { small: '1rem', }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, forceRGB: true, extendColors: { black: '#000000', white: 'var(--colors-white)', red: { 400: 'var(--colors-red-400)', DEFAULT: 'var(--colors-red)', 500: 'var(--colors-red-500)', }, }, }), ], }) ).toMatchInlineSnapshot(` " + :root { + --colors-white: 255,255,255; + --colors-red-400: 254,0,0; + --colors-red-600: 254,0,0; + --colors-red: 254,0,0; + --sizes-small: 1rem + } + .bg-black { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)) + } + .bg-indigo { + --tw-bg-opacity: 1; + background-color: rgb(236 72 153 / var(--tw-bg-opacity)) + } + .bg-red { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-red), var(--tw-bg-opacity)) + } + .bg-red-400 { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-red-400), var(--tw-bg-opacity)) + } + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-red-500), var(--tw-bg-opacity)) + } + .bg-white { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-white), var(--tw-bg-opacity)) + } + .bg-opacity-50 { + --tw-bg-opacity: 0.5 + } + .text-black { + --tw-text-opacity: 1; + color: rgb(0 0 0 / var(--tw-text-opacity)) + } + .text-indigo { + --tw-text-opacity: 1; + color: rgb(236 72 153 / var(--tw-text-opacity)) + } + .text-red { + --tw-text-opacity: 1; + color: rgba(var(--colors-red), var(--tw-text-opacity)) + } + .text-red-400 { + --tw-text-opacity: 1; + color: rgba(var(--colors-red-400), var(--tw-text-opacity)) + } + .text-red-500 { + --tw-text-opacity: 1; + color: rgba(var(--colors-red-500), var(--tw-text-opacity)) + } + .text-white { + --tw-text-opacity: 1; + color: rgba(var(--colors-white), var(--tw-text-opacity)) + } + .text-opacity-50 { + --tw-text-opacity: 0.5 + } " `) }) test('extendColors (readme)', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content()], darkMode: false, theme: { screens: false, colors: { white: '#fff', green: 'var(--colors-green)', }, variables: { DEFAULT: { colors: { blue: '#0065ff', red: '#ff0000', green: '#11ff00', }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, extendColors: { blue: 'var(--colors-blue)', red: 'var(--colors-red)', }, }), ], }) ).toMatchInlineSnapshot(` " + :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 + } + .bg-green { + background-color: var(--colors-green) + } + .bg-red { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-red-rgb), var(--tw-bg-opacity)) + } + .bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)) + } + .bg-opacity-50 { + --tw-bg-opacity: 0.5 + } + .text-green { + color: var(--colors-green) + } + .text-red { + --tw-text-opacity: 1; + color: rgba(var(--colors-red-rgb), var(--tw-text-opacity)) + } + .text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)) + } + .text-opacity-50 { + --tw-text-opacity: 0.5 + } " `) }) test('forceRGB for docs', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content()], darkMode: false, theme: { screens: false, colors: { white: '#fff', green: colorVariable('var(--colors-green)', true), }, variables: { DEFAULT: { colors: { green: '#11ff00', }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, forceRGB: true, }), ], }) ).toMatchInlineSnapshot(` " + :root { + --colors-green: 17,255,0 + } + .bg-green { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-green), var(--tw-bg-opacity)) + } + .bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)) + } + .bg-opacity-50 { + --tw-bg-opacity: 0.5 + } + .text-green { + --tw-text-opacity: 1; + color: rgba(var(--colors-green), var(--tw-text-opacity)) + } + .text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)) + } + .text-opacity-50 { + --tw-text-opacity: 0.5 + } " `) }) test('forceRGB (disabled) for docs', async () => { expect( await utils.diffOnly({ corePlugins: ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'], content: [utils.content()], darkMode: false, theme: { screens: false, colors: { white: '#fff', green: colorVariable('var(--colors-green)'), }, variables: { DEFAULT: { colors: { green: '#11ff00', }, }, }, }, plugins: [ tailwindcssVariables({ colorVariables: true, forceRGB: false, }), ], }) ).toMatchInlineSnapshot(` " + :root { + --colors-green: #11ff00; + --colors-green-rgb: 17,255,0 + } + .bg-green { + --tw-bg-opacity: 1; + background-color: rgba(var(--colors-green-rgb), var(--tw-bg-opacity)) + } + .bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)) + } + .bg-opacity-50 { + --tw-bg-opacity: 0.5 + } + .text-green { + --tw-text-opacity: 1; + color: rgba(var(--colors-green-rgb), var(--tw-text-opacity)) + } + .text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)) + } + .text-opacity-50 { + --tw-text-opacity: 0.5 + } " `) }) ================================================ FILE: __tests__/format-variables.test.html ================================================ ================================================ FILE: __tests__/format-variables.test.js ================================================ const tailwindcssVariables = require('../src/index') const utils = require('./util/_utils')(__filename) test('format variables [special characters must be removed from variable names]', async () => { expect( /* eslint-disable camelcase */ await utils.diffOnly({ content: [utils.content()], darkMode: false, theme: { variables: { DEFAULT: { colors: { "hello[$&+,:;=?@#|'<>.-^*()%!]WORLD": '100%', underscore_to_dash: '100%', 'underscore_to_dash-with-dash': '100%', auto_dash: '100%', }, sizes: { 1.5: '1rem', 'foo2.0bar3.0': '2rem', baz: { 'foo3.0bar4.0': '3rem', }, }, }, "[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: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :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-foo2\\.0bar3\\.0: 2rem; + --sizes-baz-foo3\\.0bar4\\.0: 3rem + } + [type='button'] { + --hello-world: 100%; + --underscore-to-dash: 100%; + --underscore-to-dash-with-dash: 100%; + --auto-dash: 100%; + --nested-auto-dash-color--primary: 100% + } " `) }) ================================================ FILE: __tests__/issues.test.html ================================================
================================================ FILE: __tests__/issues.test.js ================================================ const tailwindcssVariables = require('../src/index') const utils = require('./util/_utils')(__filename) test('issue 23', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: false, theme: { 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, 'body-font-weight2': '400', 'body-line-height2': '1.5', }, }, }, plugins: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :root { + --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; + --body-font-weight2: 400; + --body-line-height2: 1.5 + } " `) }) test('issue 25', async () => { 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', } expect( await utils.diffOnly({ content: [utils.content()], darkMode: ['class', '[data-mode="dark"]'], theme: { variables: { DEFAULT: { shadow, }, }, darkVariables: { DEFAULT: { shadow, }, }, }, plugins: [ tailwindcssVariables({ darkToRoot: true, colorVariables: true, }), ], }) ).toMatchInlineSnapshot(` " + :root { + --shadow-xs: 0 0 0 1px rgba(0, 0, 0, 0.05); + --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + --shadow-base: 0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1),0 2px 4px -1px rgba(0, 0, 0, 0.06); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -2px rgba(0, 0, 0, 0.05); + --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1),0 10px 10px -5px rgba(0, 0, 0, 0.04); + --shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + --shadow-outline: 0 0 0 3px rgba(var(--primary), 0.6); + --shadow-inner: inset 0 2px 4px 0 rgba(0,0,0,0.06); + --shadow-none: none + } + :root[data-mode='dark'] { + --shadow-xs: 0 0 0 1px rgba(0, 0, 0, 0.05); + --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + --shadow-base: 0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1),0 2px 4px -1px rgba(0, 0, 0, 0.06); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -2px rgba(0, 0, 0, 0.05); + --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1),0 10px 10px -5px rgba(0, 0, 0, 0.04); + --shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25); + --shadow-outline: 0 0 0 3px rgba(var(--primary), 0.6); + --shadow-inner: inset 0 2px 4px 0 rgba(0,0,0,0.06); + --shadow-none: none + } " `) }) test('issue 37', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'class', theme: { variables: { DEFAULT: { ONE: 'red', TWO: { DEFAULT: 'black', FOObar: 'green', THREE: { FOUR: 'white', five: 'blue', }, }, }, }, }, plugins: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :root { + --ONE: red; + --TWO: black; + --TWO-FOObar: green; + --TWO-THREE-FOUR: white; + --TWO-THREE-five: blue + } " `) }) test('issue 39', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'class', theme: { variables: { DEFAULT: { sizes: { 0.5: '2px', 3.5: '14px', 6.5: '18px', '1.0': { foo: '1rem', 2.4: '2rem', }, }, }, }, }, plugins: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :root { + --sizes-0\\.5: 2px; + --sizes-3\\.5: 14px; + --sizes-6\\.5: 18px; + --sizes-1\\.0-foo: 1rem; + --sizes-1\\.0-2\\.4: 2rem + } " `) }) ================================================ FILE: __tests__/nested-variables.test.html ================================================
================================================ FILE: __tests__/nested-variables.test.js ================================================ const tailwindcssVariables = require('../src/index') const utils = require('./util/_utils')(__filename) test('nested variables', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: false, theme: { variables: { DEFAULT: { colors: { DEFAULT: '#111111', black: '#000000', buttons: { DEFAULT: '#222222', light: { DEFAULT: '#333333', white: '#ffffff', }, moon: { white: 'white', inverse: { DEFAULT: '#444444', white: 'black', }, }, }, }, }, '.container>.card, .card-body': { colors: { DEFAULT: '#555555', black: 'rgb(0, 0, 0)', buttons: { DEFAULT: '#666666', light: { DEFAULT: '#777777', white: '#ffffff', }, moon: { white: 'white', inverse: { DEFAULT: '#888888', white: 'black', }, }, }, }, }, }, }, plugins: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :root { + --colors: #111111; + --colors-black: #000000; + --colors-buttons: #222222; + --colors-buttons-light: #333333; + --colors-buttons-light-white: #ffffff; + --colors-buttons-moon-white: white; + --colors-buttons-moon-inverse: #444444; + --colors-buttons-moon-inverse-white: black + } + .container>.card { + --colors: #555555; + --colors-black: rgb(0, 0, 0); + --colors-buttons: #666666; + --colors-buttons-light: #777777; + --colors-buttons-light-white: #ffffff; + --colors-buttons-moon-white: white; + --colors-buttons-moon-inverse: #888888; + --colors-buttons-moon-inverse-white: black + } + .card-body { + --colors: #555555; + --colors-black: rgb(0, 0, 0); + --colors-buttons: #666666; + --colors-buttons-light: #777777; + --colors-buttons-light-white: #ffffff; + --colors-buttons-moon-white: white; + --colors-buttons-moon-inverse: #888888; + --colors-buttons-moon-inverse-white: black + } " `) }) ================================================ FILE: __tests__/plugin-api.test.html ================================================
================================================ FILE: __tests__/plugin-api.test.js ================================================ const utils = require('./util/_utils')(__filename) test('simple example with dark mode set to `media`', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'media', theme: { variables: { DEFAULT: { colors: { primary: 'indigo', }, }, }, }, plugins: [require('../examples/api-examples/simple/index')], }) ).toMatchInlineSnapshot(` " + :root { + --prefix2-colors-primary: indigo; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: pink + } + .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray + } + @media (prefers-color-scheme: dark) { + :root { + --prefix2-colors-primary: yellow; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: pink + } + .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray + } + } " `) }) test('simple example with dark mode set to `class`', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'class', theme: { variables: { DEFAULT: { colors: { primary: 'indigo', }, }, }, }, plugins: [require('../examples/api-examples/simple/index')], }) ).toMatchInlineSnapshot(` " + :root { + --prefix2-colors-primary: indigo; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: pink + } + .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray + } + .dark { + --prefix2-colors-primary: yellow; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: pink + } + .dark .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray + } " `) }) test('with-components example with dark mode set to `class`', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'class', theme: {}, plugins: [require('../examples/api-examples/with-components/index')], }) ).toMatchInlineSnapshot(` " + :root { + --prefix2-colors-primary: black; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: pink; + } + .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray; + } + .dark { + --prefix2-colors-primary: yellow; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: pink; + } + .dark .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray; + } + .form-select { + background-color: var(--colors-prefix2-primary); + } + .form-select .default-multi { + background-color: var(--prefix2-colors-secondary); + } + .form-select .other-multi { + background-color: var(--prefix2-colors-warning); + } " `) }) test('with-components example with dark mode set to `media`', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'media', theme: {}, plugins: [require('../examples/api-examples/with-components/index')], }) ).toMatchInlineSnapshot(` " + :root { + --prefix2-colors-primary: black; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: pink; + } + .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray; + } + @media (prefers-color-scheme: dark) { + :root { + --prefix2-colors-primary: yellow; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: pink; + } + .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray; + } + } + .form-select { + background-color: var(--colors-prefix2-primary); + } + .form-select .default-multi { + background-color: var(--prefix2-colors-secondary); + } + .form-select .other-multi { + background-color: var(--prefix2-colors-warning); + } " `) }) test('with-components-null-selector example with dark mode set to `class`', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'class', theme: {}, plugins: [require('../examples/api-examples/with-components-null-selector/index')], }) ).toMatchInlineSnapshot(` " + :root { + --prefix2-colors-primary: black; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: pink; + } + .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray; + } + .dark { + --prefix2-colors-primary: yellow; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: pink; + } + .dark .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray; + } + .select { + background-color: var(--colors-prefix2-primary); + } + .select .default-multi { + background-color: var(--prefix2-colors-secondary); + } + .select .other-multi { + background-color: var(--prefix2-colors-warning); + } " `) }) test('with-components-null-selector example with dark mode set to `media`', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'media', theme: {}, plugins: [require('../examples/api-examples/with-components-null-selector/index')], }) ).toMatchInlineSnapshot(` " + :root { + --prefix2-colors-primary: black; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: pink; + } + .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray; + } + @media (prefers-color-scheme: dark) { + :root { + --prefix2-colors-primary: yellow; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: pink; + } + .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray; + } + } + .select { + background-color: var(--colors-prefix2-primary); + } + .select .default-multi { + background-color: var(--prefix2-colors-secondary); + } + .select .other-multi { + background-color: var(--prefix2-colors-warning); + } " `) }) test('with-themes example with dark mode set to `media`', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'media', theme: {}, plugins: [require('../examples/api-examples/with-themes/index')], }) ).toMatchInlineSnapshot(` " + :root { + --prefix2-colors-primary: black; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: indigo + } + .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray + } + @media (prefers-color-scheme: dark) { + :root { + --prefix2-colors-primary: yellow; + --prefix2-colors-secondary: red; + --prefix2-colors-warning: purple + } + .admin { + --prefix2-colors-primary: green; + --prefix2-colors-secondary: orange; + --prefix2-colors-warning: teal + } + } " `) }) test('with-themes example with dark mode set to `class`', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'class', theme: { variables: { DEFAULT: { colors: { primary: 'indigo', }, }, }, }, plugins: [require('../examples/api-examples/with-themes/index')], }) ).toMatchInlineSnapshot(` " + :root { + --prefix2-colors-primary: indigo; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: indigo + } + .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray + } + .dark { + --prefix2-colors-primary: yellow; + --prefix2-colors-secondary: red; + --prefix2-colors-warning: purple + } + .dark .admin { + --prefix2-colors-primary: green; + --prefix2-colors-secondary: orange; + --prefix2-colors-warning: teal + } " `) }) test('advanced example with dark mode set to `media`', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'media', theme: { variables: { DEFAULT: { colors: { primary: 'indigo', }, }, }, }, plugins: [require('../examples/api-examples/advanced/index')], }) ).toMatchInlineSnapshot(` " + :root { + --prefix2-colors-primary: indigo; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: indigo; + } + .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray; + } + @media (prefers-color-scheme: dark) { + :root { + --prefix2-colors-primary: yellow; + --prefix2-colors-secondary: red; + --prefix2-colors-warning: purple; + } + .admin { + --prefix2-colors-primary: green; + --prefix2-colors-secondary: orange; + --prefix2-colors-warning: teal; + } + } + .form-select { + background-color: var(--colors-prefix2-primary); + } + .form-select .default-multi { + background-color: var(--prefix2-colors-secondary); + } + .form-select .other-multi { + background-color: var(--prefix2-colors-warning); + } " `) }) test('advanced example with dark mode set to `class`', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'class', theme: { variables: { DEFAULT: { colors: { primary: 'indigo', }, }, }, }, plugins: [require('../examples/api-examples/advanced/index')], }) ).toMatchInlineSnapshot(` " + :root { + --prefix2-colors-primary: indigo; + --prefix2-colors-secondary: white; + --prefix2-colors-warning: indigo; + } + .admin { + --prefix2-colors-primary: blue; + --prefix2-colors-secondary: green; + --prefix2-colors-warning: gray; + } + .dark { + --prefix2-colors-primary: yellow; + --prefix2-colors-secondary: red; + --prefix2-colors-warning: purple; + } + .dark .admin { + --prefix2-colors-primary: green; + --prefix2-colors-secondary: orange; + --prefix2-colors-warning: teal; + } + .form-select { + background-color: var(--colors-prefix2-primary); + } + .form-select .default-multi { + background-color: var(--prefix2-colors-secondary); + } + .form-select .other-multi { + background-color: var(--prefix2-colors-warning); + } " `) }) ================================================ FILE: __tests__/readme.test.html ================================================
================================================ FILE: __tests__/readme.test.js ================================================ const plugin = require('tailwindcss/plugin') const tailwindcssVariables = require('../src/index') const variablesApi = require('../api') const utils = require('./util/_utils')(__filename) test('basic usage', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: false, theme: { variables: { DEFAULT: { sizes: { small: '1rem', button: { size: '2rem', }, }, colors: { red: { 50: '#ff3232', }, }, }, '.container': { sizes: { medium: '1.5rem', }, }, }, }, plugins: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :root { + --sizes-small: 1rem; + --sizes-button-size: 2rem; + --colors-red-50: #ff3232 + } + .container { + --sizes-medium: 1.5rem + } " `) }) test('dark mode with `class`', async () => { expect( await utils.diffOnly({ content: [utils.content()], 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: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :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 + } " `) }) test('dark mode with `class` and custom options', async () => { expect( await utils.diffOnly({ content: [utils.content()], 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: [ tailwindcssVariables({ darkToRoot: false, }), ], }) ).toMatchInlineSnapshot(` " + :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 + } " `) }) test('dark mode with `media`', async () => { expect( await utils.diffOnly({ content: [utils.content()], 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: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :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 + } + } " `) }) test('variable prefix', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: false, theme: { variables: { DEFAULT: { sizes: { small: '1rem', button: { size: '2rem', }, }, colors: { red: { 50: '#ff3232', }, }, }, '.container': { sizes: { medium: '1.5rem', }, }, }, }, plugins: [ tailwindcssVariables({ variablePrefix: '--admin', }), ], }) ).toMatchInlineSnapshot(` " + :root { + --admin-sizes-small: 1rem; + --admin-sizes-button-size: 2rem; + --admin-colors-red-50: #ff3232 + } + .container { + --admin-sizes-medium: 1.5rem + } " `) }) test('variables with nested objects', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: false, theme: { variables: { DEFAULT: { sizes: { small: '1rem', admin: { buttons: { colors: { red: { 500: '#ff0000', 600: '#e60000', }, }, }, }, }, }, }, }, plugins: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :root { + --sizes-small: 1rem; + --sizes-admin-buttons-colors-red-500: #ff0000; + --sizes-admin-buttons-colors-red-600: #e60000 + } " `) }) test('naming conventions for variable keys', async () => { expect( /* eslint-disable camelcase */ await utils.diffOnly({ content: [utils.content()], darkMode: false, 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: [tailwindcssVariables], }) ).toMatchInlineSnapshot(` " + :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% + } " `) }) test('example api', async () => { let variableOptions = { variablePrefix: '--myplugin', } const pluginVariables = { DEFAULT: { colors: { primary: 'black', secondary: 'white', warning: 'orange', }, }, } const pluginDarkVariables = { DEFAULT: { colors: { primary: 'red', secondary: 'yellow', warning: 'green', }, }, } expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'class', theme: {}, plugins: [ plugin(function ({ addComponents, config }) { addComponents(variablesApi.variables(pluginVariables, variableOptions)) addComponents(variablesApi.darkVariables(pluginDarkVariables, variableOptions, config('darkMode'))) // darkMode: class }), ], }) ).toMatchInlineSnapshot(` " + :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 + } " `) }) test('example api with components helper', async () => { let variableOptions = { variablePrefix: '--myplugin', } const pluginVariables = { DEFAULT: { colors: { primary: 'black', secondary: 'white', warning: 'orange', }, }, } const pluginDarkVariables = { DEFAULT: { colors: { primary: 'red', secondary: 'yellow', warning: 'green', }, }, } expect( await utils.diffOnly({ content: [utils.content()], darkMode: 'class', theme: {}, 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)) }), ], }) ).toMatchInlineSnapshot(` " + :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); + } " `) }) test('detailed example api', async () => { expect( await utils.diffOnly( ...[ { content: [utils.content()], darkMode: 'class', ...require('../examples/api-examples/readme-source/tailwind.config'), }, ] ) ).toMatchInlineSnapshot(` " + :root { + --forms-colors-primary: indigo; + --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); + } " `) }) ================================================ FILE: __tests__/test.stub ================================================ const tailwindcssVariables = require('../src/index') const utils = require('../jest/_utils')(__filename) it('test', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: false, theme: { variables: { DEFAULT: { variable: { key: 'value' }, }, }, }, plugins: [tailwindcssVariables], }) ).toMatchInlineSnapshot( ` " + :root { + --variable-key: '1' + } ` ) }) ================================================ FILE: __tests__/to-base.test.html ================================================
tailwindcss-variables
tailwindcss-variables
================================================ FILE: __tests__/to-base.test.js ================================================ const tailwindcssVariables = require('../src/index') const utils = require('./util/_utils')(__filename) test('toBase - default', async () => { expect( await utils.diffOnly( { content: [utils.content()], darkMode: 'class', corePlugins: ['textColor'], theme: { colors: { red: { 400: 'var(--colors-red-400)', 500: 'var(--colors-red-500)', }, }, variables: { DEFAULT: { colors: { red: { 400: '#000000', 500: '#111111', }, }, }, }, darkVariables: { DEFAULT: { colors: { red: { 400: '#222222', 500: '#333333', }, }, }, }, }, plugins: [tailwindcssVariables], }, true ) ).toMatchInlineSnapshot(` " + :root { + --colors-red-400: #000000; + --colors-red-500: #111111 + } + :root.dark { + --colors-red-400: #222222; + --colors-red-500: #333333 + } + .text-red-400 { + color: var(--colors-red-400) + } + .text-red-500 { + color: var(--colors-red-500) + } " `) }) test('toBase', async () => { expect( await utils.diffOnly( { content: [utils.content()], darkMode: 'class', corePlugins: ['textColor'], theme: { colors: { red: { 400: 'var(--colors-red-400)', 500: 'var(--colors-red-500)', }, }, variables: { DEFAULT: { colors: { red: { 400: '#000000', 500: '#111111', }, }, }, }, darkVariables: { DEFAULT: { colors: { red: { 400: '#222222', 500: '#333333', }, }, }, }, }, plugins: [ tailwindcssVariables({ toBase: true, }), ], }, true ) ).toMatchInlineSnapshot(` " + :root { + --colors-red-400: #000000; + --colors-red-500: #111111 + } + :root.dark { + --colors-red-400: #222222; + --colors-red-500: #333333 + } + .text-red-400 { + color: var(--colors-red-400) + } + .text-red-500 { + color: var(--colors-red-500) + } " `) }) test('if "base" styles are not added then variables should not be added', async () => { expect( await utils.diffOnly( { content: [utils.content()], darkMode: 'class', corePlugins: ['textColor'], theme: { colors: { red: { 400: 'var(--colors-red-400)', 500: 'var(--colors-red-500)', }, }, variables: { DEFAULT: { colors: { red: { 400: '#000000', 500: '#111111', }, }, }, }, darkVariables: { DEFAULT: { colors: { red: { 400: '#222222', 500: '#333333', }, }, }, }, }, plugins: [ tailwindcssVariables({ toBase: true, }), ], }, false ) ).toMatchInlineSnapshot(` " + .text-red-400 { + color: var(--colors-red-400) + } + .text-red-500 { + color: var(--colors-red-500) + } " `) }) test('if "base" styles are not added then variables should be added.', async () => { expect( await utils.diffOnly( { content: [utils.content()], darkMode: 'class', corePlugins: ['textColor'], theme: { colors: { red: { 400: 'var(--colors-red-400)', 500: 'var(--colors-red-500)', }, }, variables: { DEFAULT: { colors: { red: { 400: '#000000', 500: '#111111', }, }, }, }, darkVariables: { DEFAULT: { colors: { red: { 400: '#222222', 500: '#333333', }, }, }, }, }, plugins: [ tailwindcssVariables({ toBase: false, }), ], }, false ) ).toMatchInlineSnapshot(` " + :root { + --colors-red-400: #000000; + --colors-red-500: #111111 + } + :root.dark { + --colors-red-400: #222222; + --colors-red-500: #333333 + } + .text-red-400 { + color: var(--colors-red-400) + } + .text-red-500 { + color: var(--colors-red-500) + } " `) }) test('toComponents', async () => { expect( await utils.diffOnly( { content: [utils.content()], corePlugins: ['textColor'], darkMode: 'class', theme: { colors: { red: { 400: 'var(--colors-red-400)', 500: 'var(--colors-red-500)', }, }, variables: { DEFAULT: { colors: { red: { 400: '#000000', 500: '#111111', }, }, }, }, darkVariables: { DEFAULT: { colors: { red: { 400: '#222222', 500: '#333333', }, }, }, }, }, plugins: [ tailwindcssVariables({ toBase: false, }), ], }, false ) ).toMatchInlineSnapshot(` " + :root { + --colors-red-400: #000000; + --colors-red-500: #111111 + } + :root.dark { + --colors-red-400: #222222; + --colors-red-500: #333333 + } + .text-red-400 { + color: var(--colors-red-400) + } + .text-red-500 { + color: var(--colors-red-500) + } " `) }) ================================================ FILE: __tests__/use-host.test.html ================================================
================================================ FILE: __tests__/use-host.test.js ================================================ const tailwindcssVariables = require('../src/index') const utils = require('./util/_utils')(__filename) test('basic usage with host', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: false, theme: { variables: { DEFAULT: { colors: { black: 'rgb(0, 0, 0)', white: '#ffffff', }, sizes: { small: '10px', medium: '2rem', large: '100%', }, }, '.container': { colors: { primary: 'red', secondary: 'var(--colors-primary)', }, }, }, }, plugins: [tailwindcssVariables({ useHost: true, })], }) ).toMatchInlineSnapshot(` " + :host { + --colors-black: rgb(0, 0, 0); + --colors-white: #ffffff; + --sizes-small: 10px; + --sizes-medium: 2rem; + --sizes-large: 100% + } + .container { + --colors-primary: red; + --colors-secondary: var(--colors-primary) + } " `) }) test('basic usage with host should not work with dark', async () => { expect( await utils.diffOnly({ content: [utils.content('dark-mode-to-root')], darkMode: 'class', theme: { darkVariables: { DEFAULT: { colors: { black: 'rgb(0, 0, 0)', white: '#ffffff', }, sizes: { small: '10px', medium: '2rem', large: '100%', }, }, '.container': { colors: { primary: 'red', secondary: 'var(--colors-primary)', }, }, }, }, plugins: [tailwindcssVariables({ darkToRoot: true, useHost: true })], }) ).toMatchInlineSnapshot(` " + :host.dark { + --colors-black: rgb(0, 0, 0); + --colors-white: #ffffff; + --sizes-small: 10px; + --sizes-medium: 2rem; + --sizes-large: 100% + } + :host.dark .container { + --colors-primary: red; + --colors-secondary: var(--colors-primary) + } " `) }) ================================================ FILE: __tests__/util/_utils.js ================================================ const tailwind = require('tailwindcss') const snapshotDiff = require('snapshot-diff') const postcss = require('postcss') const path = require('path') const fs = require('fs') const atImport = require('postcss-import') module.exports = (contentFile) => { let utils = {} utils.run = function(config = {}, toBase = true) { let { currentTestName } = expect.getState() let filename = currentTestName + '.test.css' if (fs.existsSync(path.resolve(__dirname, '../' + filename))) { return this.runFromFile(filename, config) } return this.runInline(config, toBase) } utils.runInline = (config, toBase) => { let styles if (toBase) { styles = ['@tailwind base;', '@tailwind components;', '@tailwind utilities;'] } else { styles = ['@tailwind components;', '@tailwind utilities;'] } return postcss([tailwind({ corePlugins: [], ...config })]) .process(styles.join('\n'), { from: undefined, }) .then((result) => result.css) } utils.runFromFile = (filename, config) => { const css = fs.readFileSync(path.resolve(__dirname, '../' + filename), 'utf8') return postcss([tailwind({ corePlugins: [], ...config })]) .use(atImport()) .process(css, { from: path.resolve(__dirname, '../' + filename), }) .then((result) => result.css) } utils.diffOnly = async function(options = {}, toBase = true) { const [before, after] = await Promise.all([utils.run({}, toBase), utils.run(options, toBase)]) return `\n\n${snapshotDiff(before, after, { aAnnotation: '__REMOVE_ME__', bAnnotation: '__REMOVE_ME__', contextLines: 0, }) .replace(/\n\n@@([^@@]*)@@/g, '') // Top level @@ signs .replace(/@@([^@@]*)@@/g, '\n---\n') // In between @@ signs .replace(/[-+] __REMOVE_ME__\n/g, '') .replace(/\+ /g, '+ ') // .replace(/\+ \}\n([\s]*)\+/g, '\+ \}\n$1\+') .replace(/\+(\s+?)\}\n(\s+?)\+/g, '\\+$1\\}') .replace(/Snapshot Diff:\n/g, '') .replace(/"/g, '\'') .split('\n') .map((line) => ` ${line}`) .join('\n')}\n\n` } utils.content = (filename, ext) => { if (!ext) { ext = 'html' } if (filename) { return path.resolve(__dirname, '../' + path.parse(filename).name + '.test.' + ext) } else { return path.resolve(__dirname, '../' + path.parse(contentFile).name + '.' + ext) } } return utils } ================================================ FILE: __tests__/variable-prefix.test.html ================================================
================================================ FILE: __tests__/variable-prefix.test.js ================================================ const tailwindcssVariables = require('../src/index') const utils = require('./util/_utils')(__filename) test('variable prefix', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: false, theme: { variables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [ tailwindcssVariables({ variablePrefix: '--prefix', }), ], }) ).toMatchInlineSnapshot(` " + :root { + --prefix-colors-primary: #ffffff + } + .container { + --prefix-colors-secondary: #000000 + } " `) }) test('formatted variable prefix', async () => { expect( await utils.diffOnly({ content: [utils.content()], darkMode: false, theme: { variables: { DEFAULT: { colors: { primary: '#ffffff', }, }, '.container': { colors: { secondary: '#000000', }, }, }, }, plugins: [ tailwindcssVariables({ variablePrefix: '--[hello](_world)1=tail_wind', }), ], }) ).toMatchInlineSnapshot(` " + :root { + --hello-world1tail-wind-colors-primary: #ffffff + } + .container { + --hello-world1tail-wind-colors-secondary: #000000 + } " `) }) ================================================ FILE: api.js ================================================ const pluginApi = require('./src/pluginApi') module.exports = pluginApi ================================================ FILE: colorVariable.js ================================================ const helpers = require('./src/helpers') module.exports = helpers.colorVariable ================================================ FILE: examples/.npmignore ================================================ ================================================ FILE: examples/api-examples/advanced/components.js ================================================ module.exports = (theme) => ({ select: { DEFAULT: { backgroundColor: 'var(--colors-prefix2-primary)', }, multi: { '.default-multi': { backgroundColor: 'var(--prefix2-colors-secondary)', }, '.other-multi': { backgroundColor: 'var(--prefix2-colors-warning)', }, }, }, }) ================================================ FILE: examples/api-examples/advanced/index.js ================================================ const plugin = require('tailwindcss/plugin') const merge = require('lodash/merge') const pluginThemes = require('./themes') const pluginComponents = require('./components') const variablesApi = require('../../../api') // const variablesApi = require('@mertasan/tailwindcss-variables/api') /** * @typedef {Object} plugin * @property {function} withOptions */ module.exports = plugin.withOptions( function(options) { return function({ addComponents, theme, options, config }) { let pluginOptions = merge( { variablePrefix: '--prefix1', darkToRoot: false, // default: true ( :root.dark or .dark ) }, theme('myPlugin.variableOptions', {}), ) let allThemes = pluginThemes(theme) addComponents(variablesApi.variables(merge(allThemes.themes, theme('variables', {})), pluginOptions)) addComponents(variablesApi.darkVariables(merge(allThemes.darkThemes, theme('darkVariables', {})), pluginOptions, config('darkMode'))) let allComponents = pluginComponents(theme) // Automatically register components via API. addComponents(variablesApi.getComponents('.form', allComponents)) } }, function(options) { return { // darkMode: 'class', // or media theme: { myPlugin: (theme) => ({ variableOptions: { variablePrefix: '--prefix2', }, }), }, } }, ) ================================================ FILE: examples/api-examples/advanced/themes.js ================================================ module.exports = (theme) => ({ themes: { DEFAULT: { colors: { primary: 'black', secondary: 'white', warning: 'indigo', }, }, '.admin': { colors: { primary: 'blue', secondary: 'green', warning: 'gray', }, }, }, darkThemes: { DEFAULT: { colors: { primary: 'yellow', secondary: 'red', warning: 'purple', }, }, '.admin': { colors: { primary: 'green', secondary: 'orange', warning: 'teal', }, }, }, }) ================================================ FILE: examples/api-examples/readme-source/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)', }, }, }, }) ================================================ FILE: examples/api-examples/readme-source/index.html ================================================ ================================================ FILE: examples/api-examples/readme-source/index.js ================================================ const plugin = require('tailwindcss/plugin') const _ = require('lodash') const variablesApi = require('../../../api') // 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))) } } ) ================================================ FILE: examples/api-examples/readme-source/tailwind.config.js ================================================ module.exports = { theme: { myPlugin: { options: { colors: { primary: 'indigo', } } }, }, // plugins: [require('my-plugin')], plugins: [require('./index')], } ================================================ FILE: examples/api-examples/readme-source/themes.js ================================================ module.exports = (theme) => ({ themes: { DEFAULT: { colors: { primary: 'black', secondary: 'white', warning: 'orange', }, } } }) ================================================ FILE: examples/api-examples/simple/index.js ================================================ const plugin = require('tailwindcss/plugin') const merge = require('lodash/merge') const variablesApi = require('../../../api') // const variablesApi = require('@mertasan/tailwindcss-variables/api') /** * @typedef {Object} plugin * @property {function} withOptions */ module.exports = plugin.withOptions( function(options) { return function({ addComponents, theme, options, config }) { const myVariables = { DEFAULT: { colors: { primary: 'black', secondary: 'white', warning: 'pink', }, }, '.admin': { colors: { primary: 'blue', secondary: 'green', warning: 'gray', }, }, } let pluginOptions = merge( { variablePrefix: '--prefix1', darkToRoot: false, // default: true ( :root.dark or .dark ) }, theme('myPlugin.variableOptions', {}), ) addComponents(variablesApi.variables(merge(myVariables, theme('variables', {})), pluginOptions)) myVariables.DEFAULT.colors.primary = 'yellow' addComponents(variablesApi.darkVariables(merge(myVariables, theme('darkVariables', {})), pluginOptions, config('darkMode'))) } }, function(options) { return { // darkMode: 'class', // or media theme: { myPlugin: (theme) => ({ variableOptions: { variablePrefix: '--prefix2', }, }), }, } }, ) ================================================ FILE: examples/api-examples/with-components/components.js ================================================ module.exports = (theme) => ({ select: { DEFAULT: { backgroundColor: 'var(--colors-prefix2-primary)', }, multi: { '.default-multi': { backgroundColor: 'var(--prefix2-colors-secondary)', }, '.other-multi': { backgroundColor: 'var(--prefix2-colors-warning)', }, }, }, }) ================================================ FILE: examples/api-examples/with-components/index.js ================================================ const plugin = require('tailwindcss/plugin') const merge = require('lodash/merge') const pluginComponents = require('./components') const variablesApi = require('../../../api') // const variablesApi = require('@mertasan/tailwindcss-variables/api') /** * @typedef {Object} plugin * @property {function} withOptions */ module.exports = plugin.withOptions( function(options) { return function({ addComponents, theme, options, config }) { const myVariables = { DEFAULT: { colors: { primary: 'black', secondary: 'white', warning: 'pink', }, }, '.admin': { colors: { primary: 'blue', secondary: 'green', warning: 'gray', }, }, } let pluginOptions = merge( { variablePrefix: '--prefix1', darkToRoot: false, // default: true ( :root.dark or .dark ) }, theme('myPlugin.variableOptions', {}), ) addComponents(variablesApi.variables(myVariables, pluginOptions)) myVariables.DEFAULT.colors.primary = 'yellow' addComponents(variablesApi.darkVariables(myVariables, pluginOptions, config('darkMode'))) // Automatically register components via API. addComponents(variablesApi.getComponents('.form', theme('myPlugin.components', {}))) } }, function(options) { return { // darkMode: 'class', // or media theme: { myPlugin: (theme) => ({ variableOptions: { variablePrefix: '--prefix2', }, components: pluginComponents(theme), }), }, } }, ) ================================================ FILE: examples/api-examples/with-components-null-selector/components.js ================================================ module.exports = (theme) => ({ '.select': { DEFAULT: { backgroundColor: 'var(--colors-prefix2-primary)', }, multi: { '.default-multi': { backgroundColor: 'var(--prefix2-colors-secondary)', }, '.other-multi': { backgroundColor: 'var(--prefix2-colors-warning)', }, }, }, }) ================================================ FILE: examples/api-examples/with-components-null-selector/index.js ================================================ const plugin = require('tailwindcss/plugin') const merge = require('lodash/merge') const pluginComponents = require('./components') const variablesApi = require('../../../api') // const variablesApi = require('@mertasan/tailwindcss-variables/api') /** * @typedef {Object} plugin * @property {function} withOptions */ module.exports = plugin.withOptions( function(options) { return function({ addComponents, theme, options, config }) { const myVariables = { DEFAULT: { colors: { primary: 'black', secondary: 'white', warning: 'pink', }, }, '.admin': { colors: { primary: 'blue', secondary: 'green', warning: 'gray', }, }, } let pluginOptions = merge( { variablePrefix: '--prefix1', darkToRoot: false, // default: true ( :root.dark or .dark ) }, theme('myPlugin.variableOptions', {}), ) addComponents(variablesApi.variables(myVariables, pluginOptions)) myVariables.DEFAULT.colors.primary = 'yellow' addComponents(variablesApi.darkVariables(myVariables, pluginOptions, config('darkMode'))) // Automatically register components via API. addComponents(variablesApi.getComponents(null, theme('myPlugin.components', {}))) } }, function(options) { return { // darkMode: 'class', // or media theme: { myPlugin: (theme) => ({ variableOptions: { variablePrefix: '--prefix2', }, components: pluginComponents(theme), }), }, } }, ) ================================================ FILE: examples/api-examples/with-themes/index.js ================================================ const plugin = require('tailwindcss/plugin') const merge = require('lodash/merge') const pluginThemes = require('./themes') const variablesApi = require('../../../api') // const variablesApi = require('@mertasan/tailwindcss-variables/api') /** * @typedef {Object} plugin * @property {function} withOptions */ module.exports = plugin.withOptions( function(options) { return function({ addComponents, theme, options, config }) { let pluginOptions = merge( { variablePrefix: '--prefix1', darkToRoot: false, // default: true ( :root.dark or .dark ) }, theme('myPlugin.variableOptions', {}), ) let allThemes = pluginThemes(theme) addComponents(variablesApi.variables(merge(allThemes.themes, theme('variables', {})), pluginOptions)) addComponents(variablesApi.darkVariables(merge(allThemes.darkThemes, theme('darkVariables', {})), pluginOptions, config('darkMode'))) } }, function(options) { return { // darkMode: 'class', // or media theme: { myPlugin: (theme) => ({ variableOptions: { variablePrefix: '--prefix2', }, }), }, } }, ) ================================================ FILE: examples/api-examples/with-themes/themes.js ================================================ module.exports = (theme) => ({ themes: { DEFAULT: { colors: { primary: 'black', secondary: 'white', warning: 'indigo', }, }, '.admin': { colors: { primary: 'blue', secondary: 'green', warning: 'gray', }, }, }, darkThemes: { DEFAULT: { colors: { primary: 'yellow', secondary: 'red', warning: 'purple', }, }, '.admin': { colors: { primary: 'green', secondary: 'orange', warning: 'teal', }, }, }, }) ================================================ FILE: examples/color-variable-helper/clean.css ================================================ :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% } .bg-secondary { --tw-bg-opacity: 1; background-color: rgba(var(--colors-secondary-rgb), var(--tw-bg-opacity)) } .bg-gray { background-color: var(--colors-gray) } .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-green { background-color: var(--colors-green) } .bg-white { --tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity)) } .bg-opacity-50 { --tw-bg-opacity: 0.5 } .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 } ================================================ FILE: examples/color-variable-helper/index.html ================================================ colorVariable() example using @mertasan/tailwindcss-variables

Tailwindcss Variables

[colorVariable() example]

source
feature image
================================================ FILE: examples/color-variable-helper/package.json ================================================ { "name": "color-variable-helper", "version": "1.0.0", "scripts": { "build": "env NODE_ENV=production npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./style.css", "build:clean": "env NODE_ENV=production CLEAN=true npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./clean.css" }, "devDependencies": { "@mertasan/tailwindcss-variables": "latest", "autoprefixer": "^10.4.0", "postcss": "^8.4.4", "tailwindcss": "^3.0.11" }, "license": "MIT" } ================================================ FILE: examples/color-variable-helper/style.css ================================================ /* ! tailwindcss v3.0.0 | MIT License | https://tailwindcss.com *//* 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) */ *, ::before, ::after { box-sizing: border-box; /* 1 */ border-width: 0; /* 2 */ border-style: solid; /* 2 */ border-color: currentColor; /* 2 */ } ::before, ::after { --tw-content: ''; } /* 1. Use a consistent sensible line-height in all browsers. 2. Prevent adjustments of font size after orientation changes in iOS. 3. Use a more readable tab size. 4. Use the user's configured `sans` font-family by default. */ html { line-height: 1.5; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ /* 3 */ tab-size: 4; /* 3 */ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */ } /* 1. Remove the margin in all browsers. 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. */ body { margin: 0; /* 1 */ line-height: inherit; /* 2 */ } /* 1. Add the correct height in Firefox. 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 3. Ensure horizontal rules are visible by default. */ hr { height: 0; /* 1 */ color: inherit; /* 2 */ border-top-width: 1px; /* 3 */ } /* Add the correct text decoration in Chrome, Edge, and Safari. */ abbr[title] { -webkit-text-decoration: underline dotted; text-decoration: underline dotted; } /* Remove the default font size and weight for headings. */ h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; } /* Reset links to optimize for opt-in styling instead of opt-out. */ a { color: inherit; text-decoration: inherit; } /* Add the correct font weight in Edge and Safari. */ b, strong { font-weight: bolder; } /* 1. Use the user's configured `mono` font family by default. 2. Correct the odd `em` font sizing in all browsers. */ code, kbd, samp, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */ font-size: 1em; /* 2 */ } /* Add the correct font size in all browsers. */ small { font-size: 80%; } /* Prevent `sub` and `sup` elements from affecting the line height in all browsers. */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sub { bottom: -0.25em; } sup { top: -0.5em; } /* 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 3. Remove gaps between table borders by default. */ table { text-indent: 0; /* 1 */ border-color: inherit; /* 2 */ border-collapse: collapse; /* 3 */ } /* 1. Change the font styles in all browsers. 2. Remove the margin in Firefox and Safari. 3. Remove default padding in all browsers. */ button, input, optgroup, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 1 */ line-height: inherit; /* 1 */ color: inherit; /* 1 */ margin: 0; /* 2 */ padding: 0; /* 3 */ } /* Remove the inheritance of text transform in Edge and Firefox. */ button, select { text-transform: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Remove default button styles. */ button, [type='button'], [type='reset'], [type='submit'] { -webkit-appearance: button; /* 1 */ background-color: transparent; /* 2 */ background-image: none; /* 2 */ } /* Use the modern Firefox focus style for all focusable elements. */ :-moz-focusring { outline: auto; } /* Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) */ :-moz-ui-invalid { box-shadow: none; } /* Add the correct vertical alignment in Chrome and Firefox. */ progress { vertical-align: baseline; } /* Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; } /* 1. Correct the odd appearance in Chrome and Safari. 2. Correct the outline style in Safari. */ [type='search'] { -webkit-appearance: textfield; /* 1 */ outline-offset: -2px; /* 2 */ } /* Remove the inner padding in Chrome and Safari on macOS. */ ::-webkit-search-decoration { -webkit-appearance: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Change font properties to `inherit` in Safari. */ ::-webkit-file-upload-button { -webkit-appearance: button; /* 1 */ font: inherit; /* 2 */ } /* Add the correct display in Chrome and Safari. */ summary { display: list-item; } /* Removes the default spacing and border for appropriate elements. */ blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre { margin: 0; } fieldset { margin: 0; padding: 0; } legend { padding: 0; } ol, ul, menu { list-style: none; margin: 0; padding: 0; } /* Prevent resizing textareas horizontally by default. */ textarea { resize: vertical; } /* 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 2. Set the default placeholder color to the user's configured gray 400 color. */ input::placeholder, textarea::placeholder { opacity: 1; /* 1 */ color: #9ca3af; /* 2 */ } /* Set the default cursor for buttons. */ button, [role="button"] { cursor: pointer; } /* Make sure disabled buttons don't get the pointer cursor. */ :disabled { cursor: default; } /* 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) This can trigger a poorly considered lint error in some tools but is included by design. */ img, svg, video, canvas, audio, iframe, embed, object { display: block; /* 1 */ vertical-align: middle; /* 2 */ } /* Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) */ img, video { max-width: 100%; height: auto; } /* Ensure the default browser behavior of the `hidden` attribute. */ [hidden] { display: none; } :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%; } .container { width: 100%; } .order-1 { order: 1; } .mx-auto { margin-left: auto; margin-right: auto; } .-mx-3 { margin-left: -0.75rem; margin-right: -0.75rem; } .mb-4 { margin-bottom: 1rem; } .mt-4 { margin-top: 1rem; } .mb-12 { margin-bottom: 3rem; } .flex { display: flex; } .hidden { display: none; } .w-full { width: 100%; } .max-w-6xl { max-width: 72rem; } .flex-wrap { flex-wrap: wrap; } .items-center { align-items: center; } .bg-secondary { --tw-bg-opacity: 1; background-color: rgba(var(--colors-secondary-rgb), var(--tw-bg-opacity)); } .bg-gray { background-color: var(--colors-gray); } .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-green { background-color: var(--colors-green); } .bg-white { --tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity)); } .bg-opacity-50 { --tw-bg-opacity: 0.5; } .py-20 { padding-top: 5rem; padding-bottom: 5rem; } .px-4 { padding-left: 1rem; padding-right: 1rem; } .px-10 { padding-left: 2.5rem; padding-right: 2.5rem; } .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; } .text-3xl { font-size: 1.875rem; line-height: 2.25rem; } .text-2xl { font-size: 1.5rem; line-height: 2rem; } .text-base { font-size: 1rem; line-height: 1.5rem; } .font-bold { font-weight: 700; } .font-semibold { font-weight: 600; } .font-medium { font-weight: 500; } .leading-tight { line-height: 1.25; } .tracking-tight { letter-spacing: -0.025em; } .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; } ================================================ FILE: examples/color-variable-helper/tailwind.config.js ================================================ // const colorVariable = require('@mertasan/tailwindcss-variables/colorVariable') const colorVariable = require('../../colorVariable') /** * Usage: * colorVariable('--colors-primary') * or * colorVariable('var(--colors-primary)') */ module.exports = { corePlugins: process.env.CLEAN ? ['textColor', 'textOpacity', 'backgroundColor', 'backgroundOpacity'] : {}, content: ['./index.html'], darkMode: 'class', 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('../../src/index')({ colorVariables: true }) ], } ================================================ FILE: examples/color-variable-helper/tailwind.css ================================================ @tailwind base; @tailwind components; @tailwind utilities; ================================================ FILE: examples/dark-custom-selector/clean.css ================================================ :root { --sizes-small: 1rem; --sizes-medium: 2rem; --sizes-large: 3rem; --colors-red-50: #ff3232; --colors-red-500: #ff0000; --colors-red-900: #d70000 } .container { --sizes-medium: 1.5rem; --sizes-container: 2rem } :root.custom-dark-selector { --colors-red-50: #c665ff; --colors-red-500: #9433f1; --colors-red-900: #6c0bc9 } :root.custom-dark-selector .container { --colors-red-50: #ff0000 } ================================================ FILE: examples/dark-custom-selector/index.html ================================================ Dark Mode (class) example using tailwindcss-variables

Tailwindcss Variables

[dark mode with "darkSelector" option]

source
feature image
================================================ FILE: examples/dark-custom-selector/package.json ================================================ { "name": "dark-custom-selector", "version": "1.0.0", "scripts": { "build": "env NODE_ENV=production npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./style.css", "build:clean": "env NODE_ENV=production CLEAN=true npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./clean.css" }, "devDependencies": { "@mertasan/tailwindcss-variables": "latest", "autoprefixer": "^10.4.0", "postcss": "^8.4.4", "tailwindcss": "^3.0.11" }, "license": "MIT" } ================================================ FILE: examples/dark-custom-selector/style.css ================================================ /* ! tailwindcss v3.0.0 | MIT License | https://tailwindcss.com *//* 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) */ *, ::before, ::after { box-sizing: border-box; /* 1 */ border-width: 0; /* 2 */ border-style: solid; /* 2 */ border-color: currentColor; /* 2 */ } ::before, ::after { --tw-content: ''; } /* 1. Use a consistent sensible line-height in all browsers. 2. Prevent adjustments of font size after orientation changes in iOS. 3. Use a more readable tab size. 4. Use the user's configured `sans` font-family by default. */ html { line-height: 1.5; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ /* 3 */ tab-size: 4; /* 3 */ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */ } /* 1. Remove the margin in all browsers. 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. */ body { margin: 0; /* 1 */ line-height: inherit; /* 2 */ } /* 1. Add the correct height in Firefox. 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 3. Ensure horizontal rules are visible by default. */ hr { height: 0; /* 1 */ color: inherit; /* 2 */ border-top-width: 1px; /* 3 */ } /* Add the correct text decoration in Chrome, Edge, and Safari. */ abbr[title] { -webkit-text-decoration: underline dotted; text-decoration: underline dotted; } /* Remove the default font size and weight for headings. */ h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; } /* Reset links to optimize for opt-in styling instead of opt-out. */ a { color: inherit; text-decoration: inherit; } /* Add the correct font weight in Edge and Safari. */ b, strong { font-weight: bolder; } /* 1. Use the user's configured `mono` font family by default. 2. Correct the odd `em` font sizing in all browsers. */ code, kbd, samp, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */ font-size: 1em; /* 2 */ } /* Add the correct font size in all browsers. */ small { font-size: 80%; } /* Prevent `sub` and `sup` elements from affecting the line height in all browsers. */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sub { bottom: -0.25em; } sup { top: -0.5em; } /* 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 3. Remove gaps between table borders by default. */ table { text-indent: 0; /* 1 */ border-color: inherit; /* 2 */ border-collapse: collapse; /* 3 */ } /* 1. Change the font styles in all browsers. 2. Remove the margin in Firefox and Safari. 3. Remove default padding in all browsers. */ button, input, optgroup, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 1 */ line-height: inherit; /* 1 */ color: inherit; /* 1 */ margin: 0; /* 2 */ padding: 0; /* 3 */ } /* Remove the inheritance of text transform in Edge and Firefox. */ button, select { text-transform: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Remove default button styles. */ button, [type='button'], [type='reset'], [type='submit'] { -webkit-appearance: button; /* 1 */ background-color: transparent; /* 2 */ background-image: none; /* 2 */ } /* Use the modern Firefox focus style for all focusable elements. */ :-moz-focusring { outline: auto; } /* Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) */ :-moz-ui-invalid { box-shadow: none; } /* Add the correct vertical alignment in Chrome and Firefox. */ progress { vertical-align: baseline; } /* Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; } /* 1. Correct the odd appearance in Chrome and Safari. 2. Correct the outline style in Safari. */ [type='search'] { -webkit-appearance: textfield; /* 1 */ outline-offset: -2px; /* 2 */ } /* Remove the inner padding in Chrome and Safari on macOS. */ ::-webkit-search-decoration { -webkit-appearance: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Change font properties to `inherit` in Safari. */ ::-webkit-file-upload-button { -webkit-appearance: button; /* 1 */ font: inherit; /* 2 */ } /* Add the correct display in Chrome and Safari. */ summary { display: list-item; } /* Removes the default spacing and border for appropriate elements. */ blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre { margin: 0; } fieldset { margin: 0; padding: 0; } legend { padding: 0; } ol, ul, menu { list-style: none; margin: 0; padding: 0; } /* Prevent resizing textareas horizontally by default. */ textarea { resize: vertical; } /* 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 2. Set the default placeholder color to the user's configured gray 400 color. */ input::placeholder, textarea::placeholder { opacity: 1; /* 1 */ color: #9ca3af; /* 2 */ } /* Set the default cursor for buttons. */ button, [role="button"] { cursor: pointer; } /* Make sure disabled buttons don't get the pointer cursor. */ :disabled { cursor: default; } /* 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) This can trigger a poorly considered lint error in some tools but is included by design. */ img, svg, video, canvas, audio, iframe, embed, object { display: block; /* 1 */ vertical-align: middle; /* 2 */ } /* Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) */ img, video { max-width: 100%; height: auto; } /* Ensure the default browser behavior of the `hidden` attribute. */ [hidden] { display: none; } :root { --sizes-small: 1rem; --sizes-medium: 2rem; --sizes-large: 3rem; --colors-red-50: #ff3232; --colors-red-500: #ff0000; --colors-red-900: #d70000; } .container { --sizes-medium: 1.5rem; --sizes-container: 2rem; } :root.custom-dark-selector { --colors-red-50: #c665ff; --colors-red-500: #9433f1; --colors-red-900: #6c0bc9; } :root.custom-dark-selector .container { --colors-red-50: #ff0000; } .container { width: 100%; } @media (min-width: 640px) { .container { max-width: 640px; } } @media (min-width: 768px) { .container { max-width: 768px; } } @media (min-width: 1024px) { .container { max-width: 1024px; } } @media (min-width: 1280px) { .container { max-width: 1280px; } } @media (min-width: 1536px) { .container { max-width: 1536px; } } .order-1 { order: 1; } .mx-auto { margin-left: auto; margin-right: auto; } .-mx-3 { margin-left: -0.75rem; margin-right: -0.75rem; } .mb-4 { margin-bottom: 1rem; } .mt-4 { margin-top: 1rem; } .mb-12 { margin-bottom: 3rem; } .flex { display: flex; } .w-full { width: 100%; } .max-w-6xl { max-width: 72rem; } .flex-wrap { flex-wrap: wrap; } .items-center { align-items: center; } .bg-gray-50 { --tw-bg-opacity: 1; background-color: rgb(249 250 251 / var(--tw-bg-opacity)); } .py-20 { padding-top: 5rem; padding-bottom: 5rem; } .px-4 { padding-left: 1rem; padding-right: 1rem; } .px-10 { padding-left: 2.5rem; padding-right: 2.5rem; } .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; } .text-3xl { font-size: 1.875rem; line-height: 2.25rem; } .text-2xl { font-size: 1.5rem; line-height: 2rem; } .text-base { font-size: 1rem; line-height: 1.5rem; } .font-bold { font-weight: 700; } .font-semibold { font-weight: 600; } .font-medium { font-weight: 500; } .leading-tight { line-height: 1.25; } .tracking-tight { letter-spacing: -0.025em; } .text-green-500 { --tw-text-opacity: 1; color: rgb(34 197 94 / var(--tw-text-opacity)); } .text-blue-500 { --tw-text-opacity: 1; color: rgb(59 130 246 / var(--tw-text-opacity)); } .hover\:text-blue-600:hover { --tw-text-opacity: 1; color: rgb(37 99 235 / var(--tw-text-opacity)); } @media (min-width: 640px) { .sm\:max-w-sm { max-width: 24rem; } .sm\:px-20 { padding-left: 5rem; padding-right: 5rem; } .sm\:text-5xl { font-size: 3rem; line-height: 1; } .sm\:text-3xl { font-size: 1.875rem; line-height: 2.25rem; } } @media (min-width: 768px) { .md\:px-32 { padding-left: 8rem; padding-right: 8rem; } } @media (min-width: 1024px) { .lg\:order-1 { order: 1; } .lg\:mb-0 { margin-bottom: 0px; } .lg\:w-1\/2 { width: 50%; } .lg\:max-w-md { max-width: 28rem; } .lg\:max-w-full { max-width: 100%; } .lg\:px-16 { padding-left: 4rem; padding-right: 4rem; } } @media (min-width: 1280px) { .xl\:mb-6 { margin-bottom: 1.5rem; } .xl\:mt-6 { margin-top: 1.5rem; } } ================================================ FILE: examples/dark-custom-selector/tailwind.config.js ================================================ module.exports = { content: ['./index.html'], corePlugins: process.env.CLEAN ? [] : {}, darkMode: ['class', '.custom-dark-selector'], theme: { variables: (theme) => ({ DEFAULT: { sizes: { small: '1rem', medium: '2rem', large: '3rem', }, colors: { red: { 50: '#ff3232', 500: '#ff0000', 900: '#d70000', }, }, }, '.container': { sizes: { medium: '1.5rem', container: '2rem', }, }, }), darkVariables: (theme) => ({ DEFAULT: { colors: { red: { 50: '#c665ff', 500: '#9433f1', 900: '#6c0bc9', }, }, }, '.container': { colors: { red: { 50: '#ff0000', }, }, }, }), }, plugins: [ require('../../src/index')({ darkToRoot: true, }), ], } ================================================ FILE: examples/dark-custom-selector/tailwind.css ================================================ @tailwind base; @tailwind components; @tailwind utilities; ================================================ FILE: examples/dark-with-class/clean.css ================================================ :root { --sizes-small: 1rem; --sizes-medium: 2rem; --sizes-large: 3rem; --colors-red-50: #ff3232; --colors-red-500: #ff0000; --colors-red-900: #d70000 } .container { --sizes-medium: 1.5rem; --sizes-container: 2rem } .dark { --colors-red-50: #c665ff; --colors-red-500: #9433f1; --colors-red-900: #6c0bc9 } .dark .container { --colors-red-50: #ff0000 } ================================================ FILE: examples/dark-with-class/index.html ================================================ Dark Mode (class) example using tailwindcss-variables

Tailwindcss Variables

[dark mode with "class"]

source
feature image
================================================ FILE: examples/dark-with-class/package.json ================================================ { "name": "dark-with-class", "version": "1.0.0", "scripts": { "build": "env NODE_ENV=production npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./style.css", "build:clean": "env NODE_ENV=production CLEAN=true npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./clean.css" }, "devDependencies": { "@mertasan/tailwindcss-variables": "latest", "autoprefixer": "^10.4.0", "postcss": "^8.4.4", "tailwindcss": "^3.0.11" }, "license": "MIT" } ================================================ FILE: examples/dark-with-class/style.css ================================================ /* ! tailwindcss v3.0.0 | MIT License | https://tailwindcss.com *//* 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) */ *, ::before, ::after { box-sizing: border-box; /* 1 */ border-width: 0; /* 2 */ border-style: solid; /* 2 */ border-color: currentColor; /* 2 */ } ::before, ::after { --tw-content: ''; } /* 1. Use a consistent sensible line-height in all browsers. 2. Prevent adjustments of font size after orientation changes in iOS. 3. Use a more readable tab size. 4. Use the user's configured `sans` font-family by default. */ html { line-height: 1.5; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ /* 3 */ tab-size: 4; /* 3 */ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */ } /* 1. Remove the margin in all browsers. 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. */ body { margin: 0; /* 1 */ line-height: inherit; /* 2 */ } /* 1. Add the correct height in Firefox. 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 3. Ensure horizontal rules are visible by default. */ hr { height: 0; /* 1 */ color: inherit; /* 2 */ border-top-width: 1px; /* 3 */ } /* Add the correct text decoration in Chrome, Edge, and Safari. */ abbr[title] { -webkit-text-decoration: underline dotted; text-decoration: underline dotted; } /* Remove the default font size and weight for headings. */ h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; } /* Reset links to optimize for opt-in styling instead of opt-out. */ a { color: inherit; text-decoration: inherit; } /* Add the correct font weight in Edge and Safari. */ b, strong { font-weight: bolder; } /* 1. Use the user's configured `mono` font family by default. 2. Correct the odd `em` font sizing in all browsers. */ code, kbd, samp, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */ font-size: 1em; /* 2 */ } /* Add the correct font size in all browsers. */ small { font-size: 80%; } /* Prevent `sub` and `sup` elements from affecting the line height in all browsers. */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sub { bottom: -0.25em; } sup { top: -0.5em; } /* 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 3. Remove gaps between table borders by default. */ table { text-indent: 0; /* 1 */ border-color: inherit; /* 2 */ border-collapse: collapse; /* 3 */ } /* 1. Change the font styles in all browsers. 2. Remove the margin in Firefox and Safari. 3. Remove default padding in all browsers. */ button, input, optgroup, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 1 */ line-height: inherit; /* 1 */ color: inherit; /* 1 */ margin: 0; /* 2 */ padding: 0; /* 3 */ } /* Remove the inheritance of text transform in Edge and Firefox. */ button, select { text-transform: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Remove default button styles. */ button, [type='button'], [type='reset'], [type='submit'] { -webkit-appearance: button; /* 1 */ background-color: transparent; /* 2 */ background-image: none; /* 2 */ } /* Use the modern Firefox focus style for all focusable elements. */ :-moz-focusring { outline: auto; } /* Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) */ :-moz-ui-invalid { box-shadow: none; } /* Add the correct vertical alignment in Chrome and Firefox. */ progress { vertical-align: baseline; } /* Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; } /* 1. Correct the odd appearance in Chrome and Safari. 2. Correct the outline style in Safari. */ [type='search'] { -webkit-appearance: textfield; /* 1 */ outline-offset: -2px; /* 2 */ } /* Remove the inner padding in Chrome and Safari on macOS. */ ::-webkit-search-decoration { -webkit-appearance: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Change font properties to `inherit` in Safari. */ ::-webkit-file-upload-button { -webkit-appearance: button; /* 1 */ font: inherit; /* 2 */ } /* Add the correct display in Chrome and Safari. */ summary { display: list-item; } /* Removes the default spacing and border for appropriate elements. */ blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre { margin: 0; } fieldset { margin: 0; padding: 0; } legend { padding: 0; } ol, ul, menu { list-style: none; margin: 0; padding: 0; } /* Prevent resizing textareas horizontally by default. */ textarea { resize: vertical; } /* 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 2. Set the default placeholder color to the user's configured gray 400 color. */ input::placeholder, textarea::placeholder { opacity: 1; /* 1 */ color: #9ca3af; /* 2 */ } /* Set the default cursor for buttons. */ button, [role="button"] { cursor: pointer; } /* Make sure disabled buttons don't get the pointer cursor. */ :disabled { cursor: default; } /* 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) This can trigger a poorly considered lint error in some tools but is included by design. */ img, svg, video, canvas, audio, iframe, embed, object { display: block; /* 1 */ vertical-align: middle; /* 2 */ } /* Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) */ img, video { max-width: 100%; height: auto; } /* Ensure the default browser behavior of the `hidden` attribute. */ [hidden] { display: none; } :root { --sizes-small: 1rem; --sizes-medium: 2rem; --sizes-large: 3rem; --colors-red-50: #ff3232; --colors-red-500: #ff0000; --colors-red-900: #d70000; } .container { --sizes-medium: 1.5rem; --sizes-container: 2rem; } .dark { --colors-red-50: #c665ff; --colors-red-500: #9433f1; --colors-red-900: #6c0bc9; } .dark .container { --colors-red-50: #ff0000; } .container { width: 100%; } @media (min-width: 640px) { .container { max-width: 640px; } } @media (min-width: 768px) { .container { max-width: 768px; } } @media (min-width: 1024px) { .container { max-width: 1024px; } } @media (min-width: 1280px) { .container { max-width: 1280px; } } @media (min-width: 1536px) { .container { max-width: 1536px; } } .order-1 { order: 1; } .mx-auto { margin-left: auto; margin-right: auto; } .-mx-3 { margin-left: -0.75rem; margin-right: -0.75rem; } .mb-4 { margin-bottom: 1rem; } .mt-4 { margin-top: 1rem; } .mb-12 { margin-bottom: 3rem; } .flex { display: flex; } .w-full { width: 100%; } .max-w-6xl { max-width: 72rem; } .flex-wrap { flex-wrap: wrap; } .items-center { align-items: center; } .bg-gray-50 { --tw-bg-opacity: 1; background-color: rgb(249 250 251 / var(--tw-bg-opacity)); } .py-20 { padding-top: 5rem; padding-bottom: 5rem; } .px-4 { padding-left: 1rem; padding-right: 1rem; } .px-10 { padding-left: 2.5rem; padding-right: 2.5rem; } .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; } .text-3xl { font-size: 1.875rem; line-height: 2.25rem; } .text-2xl { font-size: 1.5rem; line-height: 2rem; } .text-base { font-size: 1rem; line-height: 1.5rem; } .font-bold { font-weight: 700; } .font-semibold { font-weight: 600; } .font-medium { font-weight: 500; } .leading-tight { line-height: 1.25; } .tracking-tight { letter-spacing: -0.025em; } .text-green-500 { --tw-text-opacity: 1; color: rgb(34 197 94 / var(--tw-text-opacity)); } .text-blue-500 { --tw-text-opacity: 1; color: rgb(59 130 246 / var(--tw-text-opacity)); } .hover\:text-blue-600:hover { --tw-text-opacity: 1; color: rgb(37 99 235 / var(--tw-text-opacity)); } @media (min-width: 640px) { .sm\:max-w-sm { max-width: 24rem; } .sm\:px-20 { padding-left: 5rem; padding-right: 5rem; } .sm\:text-5xl { font-size: 3rem; line-height: 1; } .sm\:text-3xl { font-size: 1.875rem; line-height: 2.25rem; } } @media (min-width: 768px) { .md\:px-32 { padding-left: 8rem; padding-right: 8rem; } } @media (min-width: 1024px) { .lg\:order-1 { order: 1; } .lg\:mb-0 { margin-bottom: 0px; } .lg\:w-1\/2 { width: 50%; } .lg\:max-w-md { max-width: 28rem; } .lg\:max-w-full { max-width: 100%; } .lg\:px-16 { padding-left: 4rem; padding-right: 4rem; } } @media (min-width: 1280px) { .xl\:mb-6 { margin-bottom: 1.5rem; } .xl\:mt-6 { margin-top: 1.5rem; } } ================================================ FILE: examples/dark-with-class/tailwind.config.js ================================================ module.exports = { content: ['./index.html'], corePlugins: process.env.CLEAN ? [] : {}, darkMode: 'class', theme: { variables: (theme) => ({ DEFAULT: { sizes: { small: '1rem', medium: '2rem', large: '3rem', }, colors: { red: { 50: '#ff3232', 500: '#ff0000', 900: '#d70000', }, }, }, '.container': { sizes: { medium: '1.5rem', container: '2rem', }, }, }), darkVariables: (theme) => ({ DEFAULT: { colors: { red: { 50: '#c665ff', 500: '#9433f1', 900: '#6c0bc9', }, }, }, '.container': { colors: { red: { 50: '#ff0000', }, }, }, }), }, plugins: [ require('../../src/index')({ darkToRoot: false, }), ], } ================================================ FILE: examples/dark-with-class/tailwind.css ================================================ @tailwind base; @tailwind components; @tailwind utilities; ================================================ FILE: examples/dark-with-class-to-root/clean.css ================================================ :root { --sizes-small: 1rem; --sizes-medium: 2rem; --sizes-large: 3rem; --colors-red-50: #ff3232; --colors-red-500: #ff0000; --colors-red-900: #d70000 } .container { --sizes-medium: 1.5rem; --sizes-container: 2rem } :root.dark { --colors-red-50: #c665ff; --colors-red-500: #9433f1; --colors-red-900: #6c0bc9 } :root.dark .container { --colors-red-50: #ff0000 } ================================================ FILE: examples/dark-with-class-to-root/index.html ================================================ Dark Mode (class) example using tailwindcss-variables

Tailwindcss Variables

[dark mode with "class" mode and darkToRoot option]

source
feature image
================================================ FILE: examples/dark-with-class-to-root/package.json ================================================ { "name": "dark-with-class-to-root", "version": "1.0.0", "scripts": { "build": "env NODE_ENV=production npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./style.css", "build:clean": "env NODE_ENV=production CLEAN=true npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./clean.css" }, "devDependencies": { "@mertasan/tailwindcss-variables": "latest", "autoprefixer": "^10.4.0", "postcss": "^8.4.4", "tailwindcss": "^3.0.11" }, "license": "MIT" } ================================================ FILE: examples/dark-with-class-to-root/style.css ================================================ /* ! tailwindcss v3.0.0 | MIT License | https://tailwindcss.com *//* 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) */ *, ::before, ::after { box-sizing: border-box; /* 1 */ border-width: 0; /* 2 */ border-style: solid; /* 2 */ border-color: currentColor; /* 2 */ } ::before, ::after { --tw-content: ''; } /* 1. Use a consistent sensible line-height in all browsers. 2. Prevent adjustments of font size after orientation changes in iOS. 3. Use a more readable tab size. 4. Use the user's configured `sans` font-family by default. */ html { line-height: 1.5; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ /* 3 */ tab-size: 4; /* 3 */ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */ } /* 1. Remove the margin in all browsers. 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. */ body { margin: 0; /* 1 */ line-height: inherit; /* 2 */ } /* 1. Add the correct height in Firefox. 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 3. Ensure horizontal rules are visible by default. */ hr { height: 0; /* 1 */ color: inherit; /* 2 */ border-top-width: 1px; /* 3 */ } /* Add the correct text decoration in Chrome, Edge, and Safari. */ abbr[title] { -webkit-text-decoration: underline dotted; text-decoration: underline dotted; } /* Remove the default font size and weight for headings. */ h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; } /* Reset links to optimize for opt-in styling instead of opt-out. */ a { color: inherit; text-decoration: inherit; } /* Add the correct font weight in Edge and Safari. */ b, strong { font-weight: bolder; } /* 1. Use the user's configured `mono` font family by default. 2. Correct the odd `em` font sizing in all browsers. */ code, kbd, samp, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */ font-size: 1em; /* 2 */ } /* Add the correct font size in all browsers. */ small { font-size: 80%; } /* Prevent `sub` and `sup` elements from affecting the line height in all browsers. */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sub { bottom: -0.25em; } sup { top: -0.5em; } /* 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 3. Remove gaps between table borders by default. */ table { text-indent: 0; /* 1 */ border-color: inherit; /* 2 */ border-collapse: collapse; /* 3 */ } /* 1. Change the font styles in all browsers. 2. Remove the margin in Firefox and Safari. 3. Remove default padding in all browsers. */ button, input, optgroup, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 1 */ line-height: inherit; /* 1 */ color: inherit; /* 1 */ margin: 0; /* 2 */ padding: 0; /* 3 */ } /* Remove the inheritance of text transform in Edge and Firefox. */ button, select { text-transform: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Remove default button styles. */ button, [type='button'], [type='reset'], [type='submit'] { -webkit-appearance: button; /* 1 */ background-color: transparent; /* 2 */ background-image: none; /* 2 */ } /* Use the modern Firefox focus style for all focusable elements. */ :-moz-focusring { outline: auto; } /* Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) */ :-moz-ui-invalid { box-shadow: none; } /* Add the correct vertical alignment in Chrome and Firefox. */ progress { vertical-align: baseline; } /* Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; } /* 1. Correct the odd appearance in Chrome and Safari. 2. Correct the outline style in Safari. */ [type='search'] { -webkit-appearance: textfield; /* 1 */ outline-offset: -2px; /* 2 */ } /* Remove the inner padding in Chrome and Safari on macOS. */ ::-webkit-search-decoration { -webkit-appearance: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Change font properties to `inherit` in Safari. */ ::-webkit-file-upload-button { -webkit-appearance: button; /* 1 */ font: inherit; /* 2 */ } /* Add the correct display in Chrome and Safari. */ summary { display: list-item; } /* Removes the default spacing and border for appropriate elements. */ blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre { margin: 0; } fieldset { margin: 0; padding: 0; } legend { padding: 0; } ol, ul, menu { list-style: none; margin: 0; padding: 0; } /* Prevent resizing textareas horizontally by default. */ textarea { resize: vertical; } /* 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 2. Set the default placeholder color to the user's configured gray 400 color. */ input::placeholder, textarea::placeholder { opacity: 1; /* 1 */ color: #9ca3af; /* 2 */ } /* Set the default cursor for buttons. */ button, [role="button"] { cursor: pointer; } /* Make sure disabled buttons don't get the pointer cursor. */ :disabled { cursor: default; } /* 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) This can trigger a poorly considered lint error in some tools but is included by design. */ img, svg, video, canvas, audio, iframe, embed, object { display: block; /* 1 */ vertical-align: middle; /* 2 */ } /* Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) */ img, video { max-width: 100%; height: auto; } /* Ensure the default browser behavior of the `hidden` attribute. */ [hidden] { display: none; } :root { --sizes-small: 1rem; --sizes-medium: 2rem; --sizes-large: 3rem; --colors-red-50: #ff3232; --colors-red-500: #ff0000; --colors-red-900: #d70000; } .container { --sizes-medium: 1.5rem; --sizes-container: 2rem; } :root.dark { --colors-red-50: #c665ff; --colors-red-500: #9433f1; --colors-red-900: #6c0bc9; } :root.dark .container { --colors-red-50: #ff0000; } .container { width: 100%; } @media (min-width: 640px) { .container { max-width: 640px; } } @media (min-width: 768px) { .container { max-width: 768px; } } @media (min-width: 1024px) { .container { max-width: 1024px; } } @media (min-width: 1280px) { .container { max-width: 1280px; } } @media (min-width: 1536px) { .container { max-width: 1536px; } } .order-1 { order: 1; } .mx-auto { margin-left: auto; margin-right: auto; } .-mx-3 { margin-left: -0.75rem; margin-right: -0.75rem; } .mb-4 { margin-bottom: 1rem; } .mt-4 { margin-top: 1rem; } .mb-12 { margin-bottom: 3rem; } .flex { display: flex; } .w-full { width: 100%; } .max-w-6xl { max-width: 72rem; } .flex-wrap { flex-wrap: wrap; } .items-center { align-items: center; } .bg-gray-50 { --tw-bg-opacity: 1; background-color: rgb(249 250 251 / var(--tw-bg-opacity)); } .py-20 { padding-top: 5rem; padding-bottom: 5rem; } .px-4 { padding-left: 1rem; padding-right: 1rem; } .px-10 { padding-left: 2.5rem; padding-right: 2.5rem; } .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; } .text-3xl { font-size: 1.875rem; line-height: 2.25rem; } .text-2xl { font-size: 1.5rem; line-height: 2rem; } .text-base { font-size: 1rem; line-height: 1.5rem; } .font-bold { font-weight: 700; } .font-semibold { font-weight: 600; } .font-medium { font-weight: 500; } .leading-tight { line-height: 1.25; } .tracking-tight { letter-spacing: -0.025em; } .text-green-500 { --tw-text-opacity: 1; color: rgb(34 197 94 / var(--tw-text-opacity)); } .text-blue-500 { --tw-text-opacity: 1; color: rgb(59 130 246 / var(--tw-text-opacity)); } .hover\:text-blue-600:hover { --tw-text-opacity: 1; color: rgb(37 99 235 / var(--tw-text-opacity)); } @media (min-width: 640px) { .sm\:max-w-sm { max-width: 24rem; } .sm\:px-20 { padding-left: 5rem; padding-right: 5rem; } .sm\:text-5xl { font-size: 3rem; line-height: 1; } .sm\:text-3xl { font-size: 1.875rem; line-height: 2.25rem; } } @media (min-width: 768px) { .md\:px-32 { padding-left: 8rem; padding-right: 8rem; } } @media (min-width: 1024px) { .lg\:order-1 { order: 1; } .lg\:mb-0 { margin-bottom: 0px; } .lg\:w-1\/2 { width: 50%; } .lg\:max-w-md { max-width: 28rem; } .lg\:max-w-full { max-width: 100%; } .lg\:px-16 { padding-left: 4rem; padding-right: 4rem; } } @media (min-width: 1280px) { .xl\:mb-6 { margin-bottom: 1.5rem; } .xl\:mt-6 { margin-top: 1.5rem; } } ================================================ FILE: examples/dark-with-class-to-root/tailwind.config.js ================================================ module.exports = { content: ['./index.html'], corePlugins: process.env.CLEAN ? [] : {}, darkMode: 'class', theme: { variables: (theme) => ({ DEFAULT: { sizes: { small: '1rem', medium: '2rem', large: '3rem', }, colors: { red: { 50: '#ff3232', 500: '#ff0000', 900: '#d70000', }, }, }, '.container': { sizes: { medium: '1.5rem', container: '2rem', }, }, }), darkVariables: (theme) => ({ DEFAULT: { colors: { red: { 50: '#c665ff', 500: '#9433f1', 900: '#6c0bc9', }, }, }, '.container': { colors: { red: { 50: '#ff0000', }, }, }, }), }, plugins: [ require('../../src/index')({ darkToRoot: true, }), ], } ================================================ FILE: examples/dark-with-class-to-root/tailwind.css ================================================ @tailwind base; @tailwind components; @tailwind utilities; ================================================ FILE: examples/dark-with-media/clean.css ================================================ :root { --sizes-small: 1rem; --sizes-medium: 2rem; --sizes-large: 3rem; --colors-red-50: #ff3232; --colors-red-500: #ff0000; --colors-red-900: #d70000 } .container { --sizes-medium: 1.5rem; --sizes-container: 2rem } @media (prefers-color-scheme: dark) { :root { --colors-red-50: #c665ff; --colors-red-500: #9433f1; --colors-red-900: #6c0bc9 } .container { --colors-red-50: #ff0000 } } ================================================ FILE: examples/dark-with-media/index.html ================================================ Dark Mode (media) example using @mertasan/tailwindcss-variables

Tailwindcss Variables

[dark mode with "media"]

source
feature image
================================================ FILE: examples/dark-with-media/package.json ================================================ { "name": "dark-with-media", "version": "1.0.0", "scripts": { "build": "env NODE_ENV=production npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./style.css", "build:clean": "env NODE_ENV=production CLEAN=true npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./clean.css" }, "devDependencies": { "@mertasan/tailwindcss-variables": "latest", "autoprefixer": "^10.4.0", "postcss": "^8.4.4", "tailwindcss": "^3.0.11" }, "license": "MIT" } ================================================ FILE: examples/dark-with-media/style.css ================================================ /* ! tailwindcss v3.0.0 | MIT License | https://tailwindcss.com *//* 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) */ *, ::before, ::after { box-sizing: border-box; /* 1 */ border-width: 0; /* 2 */ border-style: solid; /* 2 */ border-color: currentColor; /* 2 */ } ::before, ::after { --tw-content: ''; } /* 1. Use a consistent sensible line-height in all browsers. 2. Prevent adjustments of font size after orientation changes in iOS. 3. Use a more readable tab size. 4. Use the user's configured `sans` font-family by default. */ html { line-height: 1.5; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ /* 3 */ tab-size: 4; /* 3 */ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */ } /* 1. Remove the margin in all browsers. 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. */ body { margin: 0; /* 1 */ line-height: inherit; /* 2 */ } /* 1. Add the correct height in Firefox. 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 3. Ensure horizontal rules are visible by default. */ hr { height: 0; /* 1 */ color: inherit; /* 2 */ border-top-width: 1px; /* 3 */ } /* Add the correct text decoration in Chrome, Edge, and Safari. */ abbr[title] { -webkit-text-decoration: underline dotted; text-decoration: underline dotted; } /* Remove the default font size and weight for headings. */ h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; } /* Reset links to optimize for opt-in styling instead of opt-out. */ a { color: inherit; text-decoration: inherit; } /* Add the correct font weight in Edge and Safari. */ b, strong { font-weight: bolder; } /* 1. Use the user's configured `mono` font family by default. 2. Correct the odd `em` font sizing in all browsers. */ code, kbd, samp, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */ font-size: 1em; /* 2 */ } /* Add the correct font size in all browsers. */ small { font-size: 80%; } /* Prevent `sub` and `sup` elements from affecting the line height in all browsers. */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sub { bottom: -0.25em; } sup { top: -0.5em; } /* 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 3. Remove gaps between table borders by default. */ table { text-indent: 0; /* 1 */ border-color: inherit; /* 2 */ border-collapse: collapse; /* 3 */ } /* 1. Change the font styles in all browsers. 2. Remove the margin in Firefox and Safari. 3. Remove default padding in all browsers. */ button, input, optgroup, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 1 */ line-height: inherit; /* 1 */ color: inherit; /* 1 */ margin: 0; /* 2 */ padding: 0; /* 3 */ } /* Remove the inheritance of text transform in Edge and Firefox. */ button, select { text-transform: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Remove default button styles. */ button, [type='button'], [type='reset'], [type='submit'] { -webkit-appearance: button; /* 1 */ background-color: transparent; /* 2 */ background-image: none; /* 2 */ } /* Use the modern Firefox focus style for all focusable elements. */ :-moz-focusring { outline: auto; } /* Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) */ :-moz-ui-invalid { box-shadow: none; } /* Add the correct vertical alignment in Chrome and Firefox. */ progress { vertical-align: baseline; } /* Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; } /* 1. Correct the odd appearance in Chrome and Safari. 2. Correct the outline style in Safari. */ [type='search'] { -webkit-appearance: textfield; /* 1 */ outline-offset: -2px; /* 2 */ } /* Remove the inner padding in Chrome and Safari on macOS. */ ::-webkit-search-decoration { -webkit-appearance: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Change font properties to `inherit` in Safari. */ ::-webkit-file-upload-button { -webkit-appearance: button; /* 1 */ font: inherit; /* 2 */ } /* Add the correct display in Chrome and Safari. */ summary { display: list-item; } /* Removes the default spacing and border for appropriate elements. */ blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre { margin: 0; } fieldset { margin: 0; padding: 0; } legend { padding: 0; } ol, ul, menu { list-style: none; margin: 0; padding: 0; } /* Prevent resizing textareas horizontally by default. */ textarea { resize: vertical; } /* 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 2. Set the default placeholder color to the user's configured gray 400 color. */ input::placeholder, textarea::placeholder { opacity: 1; /* 1 */ color: #9ca3af; /* 2 */ } /* Set the default cursor for buttons. */ button, [role="button"] { cursor: pointer; } /* Make sure disabled buttons don't get the pointer cursor. */ :disabled { cursor: default; } /* 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) This can trigger a poorly considered lint error in some tools but is included by design. */ img, svg, video, canvas, audio, iframe, embed, object { display: block; /* 1 */ vertical-align: middle; /* 2 */ } /* Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) */ img, video { max-width: 100%; height: auto; } /* Ensure the default browser behavior of the `hidden` attribute. */ [hidden] { display: none; } :root { --sizes-small: 1rem; --sizes-medium: 2rem; --sizes-large: 3rem; --colors-red-50: #ff3232; --colors-red-500: #ff0000; --colors-red-900: #d70000; } .container { --sizes-medium: 1.5rem; --sizes-container: 2rem; } @media (prefers-color-scheme: dark) { :root { --colors-red-50: #c665ff; --colors-red-500: #9433f1; --colors-red-900: #6c0bc9; } .container { --colors-red-50: #ff0000; } } .container { width: 100%; } @media (min-width: 640px) { .container { max-width: 640px; } } @media (min-width: 768px) { .container { max-width: 768px; } } @media (min-width: 1024px) { .container { max-width: 1024px; } } @media (min-width: 1280px) { .container { max-width: 1280px; } } @media (min-width: 1536px) { .container { max-width: 1536px; } } .order-1 { order: 1; } .mx-auto { margin-left: auto; margin-right: auto; } .-mx-3 { margin-left: -0.75rem; margin-right: -0.75rem; } .mb-4 { margin-bottom: 1rem; } .mt-4 { margin-top: 1rem; } .mb-12 { margin-bottom: 3rem; } .flex { display: flex; } .w-full { width: 100%; } .max-w-6xl { max-width: 72rem; } .flex-wrap { flex-wrap: wrap; } .items-center { align-items: center; } .bg-gray-50 { --tw-bg-opacity: 1; background-color: rgb(249 250 251 / var(--tw-bg-opacity)); } .py-20 { padding-top: 5rem; padding-bottom: 5rem; } .px-4 { padding-left: 1rem; padding-right: 1rem; } .px-10 { padding-left: 2.5rem; padding-right: 2.5rem; } .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; } .text-3xl { font-size: 1.875rem; line-height: 2.25rem; } .text-2xl { font-size: 1.5rem; line-height: 2rem; } .text-base { font-size: 1rem; line-height: 1.5rem; } .font-bold { font-weight: 700; } .font-semibold { font-weight: 600; } .font-medium { font-weight: 500; } .leading-tight { line-height: 1.25; } .tracking-tight { letter-spacing: -0.025em; } .text-green-500 { --tw-text-opacity: 1; color: rgb(34 197 94 / var(--tw-text-opacity)); } .text-blue-500 { --tw-text-opacity: 1; color: rgb(59 130 246 / var(--tw-text-opacity)); } .hover\:text-blue-600:hover { --tw-text-opacity: 1; color: rgb(37 99 235 / var(--tw-text-opacity)); } @media (min-width: 640px) { .sm\:max-w-sm { max-width: 24rem; } .sm\:px-20 { padding-left: 5rem; padding-right: 5rem; } .sm\:text-5xl { font-size: 3rem; line-height: 1; } .sm\:text-3xl { font-size: 1.875rem; line-height: 2.25rem; } } @media (min-width: 768px) { .md\:px-32 { padding-left: 8rem; padding-right: 8rem; } } @media (min-width: 1024px) { .lg\:order-1 { order: 1; } .lg\:mb-0 { margin-bottom: 0px; } .lg\:w-1\/2 { width: 50%; } .lg\:max-w-md { max-width: 28rem; } .lg\:max-w-full { max-width: 100%; } .lg\:px-16 { padding-left: 4rem; padding-right: 4rem; } } @media (min-width: 1280px) { .xl\:mb-6 { margin-bottom: 1.5rem; } .xl\:mt-6 { margin-top: 1.5rem; } } ================================================ FILE: examples/dark-with-media/tailwind.config.js ================================================ module.exports = { content: ['./index.html'], corePlugins: process.env.CLEAN ? [] : {}, darkMode: 'media', theme: { variables: (theme) => ({ DEFAULT: { sizes: { small: '1rem', medium: '2rem', large: '3rem', }, colors: { red: { 50: '#ff3232', 500: '#ff0000', 900: '#d70000', }, }, }, '.container': { sizes: { medium: '1.5rem', container: '2rem', }, }, }), darkVariables: (theme) => ({ DEFAULT: { colors: { red: { 50: '#c665ff', 500: '#9433f1', 900: '#6c0bc9', }, }, }, '.container': { colors: { red: { 50: '#ff0000', }, }, }, }), }, plugins: [require('../../src/index')], } ================================================ FILE: examples/dark-with-media/tailwind.css ================================================ @tailwind base; @tailwind components; @tailwind utilities; ================================================ FILE: examples/prefix/clean.css ================================================ :root { --prefix-sizes-small: 1rem; --prefix-sizes-medium: 2rem; --prefix-sizes-large: 3rem; --prefix-colors-red-50: #ff3232; --prefix-colors-red-500: #ff0000; --prefix-colors-red-900: #d70000 } .container { --prefix-sizes-medium: 1.5rem; --prefix-sizes-container: 2rem } ================================================ FILE: examples/prefix/index.html ================================================ variablePrefix example using @mertasan/tailwindcss-variables

Tailwindcss Variables

[variablePrefix example]

source
feature image
================================================ FILE: examples/prefix/package.json ================================================ { "name": "prefix", "version": "1.0.0", "scripts": { "build": "env NODE_ENV=production npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./style.css", "build:clean": "env NODE_ENV=production CLEAN=true npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./clean.css" }, "devDependencies": { "@mertasan/tailwindcss-variables": "latest", "autoprefixer": "^10.4.0", "postcss": "^8.4.4", "tailwindcss": "^3.0.11" }, "license": "MIT" } ================================================ FILE: examples/prefix/style.css ================================================ /* ! tailwindcss v3.0.0 | MIT License | https://tailwindcss.com *//* 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) */ *, ::before, ::after { box-sizing: border-box; /* 1 */ border-width: 0; /* 2 */ border-style: solid; /* 2 */ border-color: currentColor; /* 2 */ } ::before, ::after { --tw-content: ''; } /* 1. Use a consistent sensible line-height in all browsers. 2. Prevent adjustments of font size after orientation changes in iOS. 3. Use a more readable tab size. 4. Use the user's configured `sans` font-family by default. */ html { line-height: 1.5; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ /* 3 */ tab-size: 4; /* 3 */ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */ } /* 1. Remove the margin in all browsers. 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. */ body { margin: 0; /* 1 */ line-height: inherit; /* 2 */ } /* 1. Add the correct height in Firefox. 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 3. Ensure horizontal rules are visible by default. */ hr { height: 0; /* 1 */ color: inherit; /* 2 */ border-top-width: 1px; /* 3 */ } /* Add the correct text decoration in Chrome, Edge, and Safari. */ abbr[title] { -webkit-text-decoration: underline dotted; text-decoration: underline dotted; } /* Remove the default font size and weight for headings. */ h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; } /* Reset links to optimize for opt-in styling instead of opt-out. */ a { color: inherit; text-decoration: inherit; } /* Add the correct font weight in Edge and Safari. */ b, strong { font-weight: bolder; } /* 1. Use the user's configured `mono` font family by default. 2. Correct the odd `em` font sizing in all browsers. */ code, kbd, samp, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */ font-size: 1em; /* 2 */ } /* Add the correct font size in all browsers. */ small { font-size: 80%; } /* Prevent `sub` and `sup` elements from affecting the line height in all browsers. */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sub { bottom: -0.25em; } sup { top: -0.5em; } /* 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 3. Remove gaps between table borders by default. */ table { text-indent: 0; /* 1 */ border-color: inherit; /* 2 */ border-collapse: collapse; /* 3 */ } /* 1. Change the font styles in all browsers. 2. Remove the margin in Firefox and Safari. 3. Remove default padding in all browsers. */ button, input, optgroup, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 1 */ line-height: inherit; /* 1 */ color: inherit; /* 1 */ margin: 0; /* 2 */ padding: 0; /* 3 */ } /* Remove the inheritance of text transform in Edge and Firefox. */ button, select { text-transform: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Remove default button styles. */ button, [type='button'], [type='reset'], [type='submit'] { -webkit-appearance: button; /* 1 */ background-color: transparent; /* 2 */ background-image: none; /* 2 */ } /* Use the modern Firefox focus style for all focusable elements. */ :-moz-focusring { outline: auto; } /* Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) */ :-moz-ui-invalid { box-shadow: none; } /* Add the correct vertical alignment in Chrome and Firefox. */ progress { vertical-align: baseline; } /* Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; } /* 1. Correct the odd appearance in Chrome and Safari. 2. Correct the outline style in Safari. */ [type='search'] { -webkit-appearance: textfield; /* 1 */ outline-offset: -2px; /* 2 */ } /* Remove the inner padding in Chrome and Safari on macOS. */ ::-webkit-search-decoration { -webkit-appearance: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Change font properties to `inherit` in Safari. */ ::-webkit-file-upload-button { -webkit-appearance: button; /* 1 */ font: inherit; /* 2 */ } /* Add the correct display in Chrome and Safari. */ summary { display: list-item; } /* Removes the default spacing and border for appropriate elements. */ blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre { margin: 0; } fieldset { margin: 0; padding: 0; } legend { padding: 0; } ol, ul, menu { list-style: none; margin: 0; padding: 0; } /* Prevent resizing textareas horizontally by default. */ textarea { resize: vertical; } /* 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 2. Set the default placeholder color to the user's configured gray 400 color. */ input::placeholder, textarea::placeholder { opacity: 1; /* 1 */ color: #9ca3af; /* 2 */ } /* Set the default cursor for buttons. */ button, [role="button"] { cursor: pointer; } /* Make sure disabled buttons don't get the pointer cursor. */ :disabled { cursor: default; } /* 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) This can trigger a poorly considered lint error in some tools but is included by design. */ img, svg, video, canvas, audio, iframe, embed, object { display: block; /* 1 */ vertical-align: middle; /* 2 */ } /* Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) */ img, video { max-width: 100%; height: auto; } /* Ensure the default browser behavior of the `hidden` attribute. */ [hidden] { display: none; } :root { --prefix-sizes-small: 1rem; --prefix-sizes-medium: 2rem; --prefix-sizes-large: 3rem; --prefix-colors-red-50: #ff3232; --prefix-colors-red-500: #ff0000; --prefix-colors-red-900: #d70000; } .container { --prefix-sizes-medium: 1.5rem; --prefix-sizes-container: 2rem; width: 100%; } @media (min-width: 640px) { .container { max-width: 640px; } } @media (min-width: 768px) { .container { max-width: 768px; } } @media (min-width: 1024px) { .container { max-width: 1024px; } } @media (min-width: 1280px) { .container { max-width: 1280px; } } @media (min-width: 1536px) { .container { max-width: 1536px; } } .order-1 { order: 1; } .mx-auto { margin-left: auto; margin-right: auto; } .-mx-3 { margin-left: -0.75rem; margin-right: -0.75rem; } .mb-4 { margin-bottom: 1rem; } .mt-4 { margin-top: 1rem; } .mb-12 { margin-bottom: 3rem; } .flex { display: flex; } .w-full { width: 100%; } .max-w-6xl { max-width: 72rem; } .flex-wrap { flex-wrap: wrap; } .items-center { align-items: center; } .bg-gray-50 { --tw-bg-opacity: 1; background-color: rgb(249 250 251 / var(--tw-bg-opacity)); } .py-20 { padding-top: 5rem; padding-bottom: 5rem; } .px-4 { padding-left: 1rem; padding-right: 1rem; } .px-10 { padding-left: 2.5rem; padding-right: 2.5rem; } .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; } .text-3xl { font-size: 1.875rem; line-height: 2.25rem; } .text-2xl { font-size: 1.5rem; line-height: 2rem; } .text-base { font-size: 1rem; line-height: 1.5rem; } .font-bold { font-weight: 700; } .font-semibold { font-weight: 600; } .font-medium { font-weight: 500; } .leading-tight { line-height: 1.25; } .tracking-tight { letter-spacing: -0.025em; } .text-green-500 { --tw-text-opacity: 1; color: rgb(34 197 94 / var(--tw-text-opacity)); } .text-blue-500 { --tw-text-opacity: 1; color: rgb(59 130 246 / var(--tw-text-opacity)); } .hover\:text-blue-600:hover { --tw-text-opacity: 1; color: rgb(37 99 235 / var(--tw-text-opacity)); } @media (min-width: 640px) { .sm\:max-w-sm { max-width: 24rem; } .sm\:px-20 { padding-left: 5rem; padding-right: 5rem; } .sm\:text-5xl { font-size: 3rem; line-height: 1; } .sm\:text-3xl { font-size: 1.875rem; line-height: 2.25rem; } } @media (min-width: 768px) { .md\:px-32 { padding-left: 8rem; padding-right: 8rem; } } @media (min-width: 1024px) { .lg\:order-1 { order: 1; } .lg\:mb-0 { margin-bottom: 0px; } .lg\:w-1\/2 { width: 50%; } .lg\:max-w-md { max-width: 28rem; } .lg\:max-w-full { max-width: 100%; } .lg\:px-16 { padding-left: 4rem; padding-right: 4rem; } } @media (min-width: 1280px) { .xl\:mb-6 { margin-bottom: 1.5rem; } .xl\:mt-6 { margin-top: 1.5rem; } } ================================================ FILE: examples/prefix/tailwind.config.js ================================================ module.exports = { content: ['./index.html'], corePlugins: process.env.CLEAN ? [] : {}, darkMode: 'class', theme: { variables: (theme) => ({ DEFAULT: { sizes: { small: '1rem', medium: '2rem', large: '3rem', }, colors: { red: { 50: '#ff3232', 500: '#ff0000', 900: '#d70000', }, }, }, '.container': { sizes: { medium: '1.5rem', container: '2rem', }, }, }), }, plugins: [ require('../../src/index')({ variablePrefix: '--prefix', }), ], } ================================================ FILE: examples/prefix/tailwind.css ================================================ @tailwind base; @tailwind components; @tailwind utilities; ================================================ FILE: examples/simple/clean.css ================================================ :root { --sizes-small: 1rem; --sizes-medium: 2rem; --sizes-large: 3rem; --sizes-0\.5: 2px; --sizes-1\.0-foo: 1rem; --sizes-1\.0-2\.4: 2rem; --colors-red-50: #ff3232; --colors-red-500: #ff0000; --colors-red-900: #d70000 } .container { --sizes-medium: 1.5rem; --sizes-container: 2rem } ================================================ FILE: examples/simple/index.html ================================================ Simple example using @mertasan/tailwindcss-variables

Tailwindcss Variables

[simple example]

source
feature image
================================================ FILE: examples/simple/package.json ================================================ { "name": "simple", "version": "1.0.0", "scripts": { "build": "env NODE_ENV=production npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./style.css", "build:clean": "env NODE_ENV=production CLEAN=true npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./clean.css" }, "devDependencies": { "@mertasan/tailwindcss-variables": "latest", "autoprefixer": "^10.4.0", "postcss": "^8.4.4", "tailwindcss": "^3.0.11" }, "license": "MIT" } ================================================ FILE: examples/simple/style.css ================================================ /* ! tailwindcss v3.0.0 | MIT License | https://tailwindcss.com *//* 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) */ *, ::before, ::after { box-sizing: border-box; /* 1 */ border-width: 0; /* 2 */ border-style: solid; /* 2 */ border-color: currentColor; /* 2 */ } ::before, ::after { --tw-content: ''; } /* 1. Use a consistent sensible line-height in all browsers. 2. Prevent adjustments of font size after orientation changes in iOS. 3. Use a more readable tab size. 4. Use the user's configured `sans` font-family by default. */ html { line-height: 1.5; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ /* 3 */ tab-size: 4; /* 3 */ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */ } /* 1. Remove the margin in all browsers. 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. */ body { margin: 0; /* 1 */ line-height: inherit; /* 2 */ } /* 1. Add the correct height in Firefox. 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 3. Ensure horizontal rules are visible by default. */ hr { height: 0; /* 1 */ color: inherit; /* 2 */ border-top-width: 1px; /* 3 */ } /* Add the correct text decoration in Chrome, Edge, and Safari. */ abbr[title] { -webkit-text-decoration: underline dotted; text-decoration: underline dotted; } /* Remove the default font size and weight for headings. */ h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; } /* Reset links to optimize for opt-in styling instead of opt-out. */ a { color: inherit; text-decoration: inherit; } /* Add the correct font weight in Edge and Safari. */ b, strong { font-weight: bolder; } /* 1. Use the user's configured `mono` font family by default. 2. Correct the odd `em` font sizing in all browsers. */ code, kbd, samp, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */ font-size: 1em; /* 2 */ } /* Add the correct font size in all browsers. */ small { font-size: 80%; } /* Prevent `sub` and `sup` elements from affecting the line height in all browsers. */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sub { bottom: -0.25em; } sup { top: -0.5em; } /* 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 3. Remove gaps between table borders by default. */ table { text-indent: 0; /* 1 */ border-color: inherit; /* 2 */ border-collapse: collapse; /* 3 */ } /* 1. Change the font styles in all browsers. 2. Remove the margin in Firefox and Safari. 3. Remove default padding in all browsers. */ button, input, optgroup, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 1 */ line-height: inherit; /* 1 */ color: inherit; /* 1 */ margin: 0; /* 2 */ padding: 0; /* 3 */ } /* Remove the inheritance of text transform in Edge and Firefox. */ button, select { text-transform: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Remove default button styles. */ button, [type='button'], [type='reset'], [type='submit'] { -webkit-appearance: button; /* 1 */ background-color: transparent; /* 2 */ background-image: none; /* 2 */ } /* Use the modern Firefox focus style for all focusable elements. */ :-moz-focusring { outline: auto; } /* Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) */ :-moz-ui-invalid { box-shadow: none; } /* Add the correct vertical alignment in Chrome and Firefox. */ progress { vertical-align: baseline; } /* Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; } /* 1. Correct the odd appearance in Chrome and Safari. 2. Correct the outline style in Safari. */ [type='search'] { -webkit-appearance: textfield; /* 1 */ outline-offset: -2px; /* 2 */ } /* Remove the inner padding in Chrome and Safari on macOS. */ ::-webkit-search-decoration { -webkit-appearance: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Change font properties to `inherit` in Safari. */ ::-webkit-file-upload-button { -webkit-appearance: button; /* 1 */ font: inherit; /* 2 */ } /* Add the correct display in Chrome and Safari. */ summary { display: list-item; } /* Removes the default spacing and border for appropriate elements. */ blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre { margin: 0; } fieldset { margin: 0; padding: 0; } legend { padding: 0; } ol, ul, menu { list-style: none; margin: 0; padding: 0; } /* Prevent resizing textareas horizontally by default. */ textarea { resize: vertical; } /* 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 2. Set the default placeholder color to the user's configured gray 400 color. */ input::placeholder, textarea::placeholder { opacity: 1; /* 1 */ color: #9ca3af; /* 2 */ } /* Set the default cursor for buttons. */ button, [role="button"] { cursor: pointer; } /* Make sure disabled buttons don't get the pointer cursor. */ :disabled { cursor: default; } /* 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) This can trigger a poorly considered lint error in some tools but is included by design. */ img, svg, video, canvas, audio, iframe, embed, object { display: block; /* 1 */ vertical-align: middle; /* 2 */ } /* Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) */ img, video { max-width: 100%; height: auto; } /* Ensure the default browser behavior of the `hidden` attribute. */ [hidden] { display: none; } :root { --sizes-small: 1rem; --sizes-medium: 2rem; --sizes-large: 3rem; --colors-red-50: #ff3232; --colors-red-500: #ff0000; --colors-red-900: #d70000; } .container { --sizes-medium: 1.5rem; --sizes-container: 2rem; width: 100%; } @media (min-width: 640px) { .container { max-width: 640px; } } @media (min-width: 768px) { .container { max-width: 768px; } } @media (min-width: 1024px) { .container { max-width: 1024px; } } @media (min-width: 1280px) { .container { max-width: 1280px; } } @media (min-width: 1536px) { .container { max-width: 1536px; } } .order-1 { order: 1; } .mx-auto { margin-left: auto; margin-right: auto; } .-mx-3 { margin-left: -0.75rem; margin-right: -0.75rem; } .mb-4 { margin-bottom: 1rem; } .mt-4 { margin-top: 1rem; } .mb-12 { margin-bottom: 3rem; } .flex { display: flex; } .w-full { width: 100%; } .max-w-6xl { max-width: 72rem; } .flex-wrap { flex-wrap: wrap; } .items-center { align-items: center; } .bg-gray-50 { --tw-bg-opacity: 1; background-color: rgb(249 250 251 / var(--tw-bg-opacity)); } .py-20 { padding-top: 5rem; padding-bottom: 5rem; } .px-4 { padding-left: 1rem; padding-right: 1rem; } .px-10 { padding-left: 2.5rem; padding-right: 2.5rem; } .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; } .text-3xl { font-size: 1.875rem; line-height: 2.25rem; } .text-2xl { font-size: 1.5rem; line-height: 2rem; } .text-base { font-size: 1rem; line-height: 1.5rem; } .font-bold { font-weight: 700; } .font-semibold { font-weight: 600; } .font-medium { font-weight: 500; } .leading-tight { line-height: 1.25; } .tracking-tight { letter-spacing: -0.025em; } .text-green-500 { --tw-text-opacity: 1; color: rgb(34 197 94 / var(--tw-text-opacity)); } .text-blue-500 { --tw-text-opacity: 1; color: rgb(59 130 246 / var(--tw-text-opacity)); } .hover\:text-blue-600:hover { --tw-text-opacity: 1; color: rgb(37 99 235 / var(--tw-text-opacity)); } @media (min-width: 640px) { .sm\:max-w-sm { max-width: 24rem; } .sm\:px-20 { padding-left: 5rem; padding-right: 5rem; } .sm\:text-5xl { font-size: 3rem; line-height: 1; } .sm\:text-3xl { font-size: 1.875rem; line-height: 2.25rem; } } @media (min-width: 768px) { .md\:px-32 { padding-left: 8rem; padding-right: 8rem; } } @media (min-width: 1024px) { .lg\:order-1 { order: 1; } .lg\:mb-0 { margin-bottom: 0px; } .lg\:w-1\/2 { width: 50%; } .lg\:max-w-md { max-width: 28rem; } .lg\:max-w-full { max-width: 100%; } .lg\:px-16 { padding-left: 4rem; padding-right: 4rem; } } @media (min-width: 1280px) { .xl\:mb-6 { margin-bottom: 1.5rem; } .xl\:mt-6 { margin-top: 1.5rem; } } ================================================ FILE: examples/simple/tailwind.config.js ================================================ module.exports = { content: ['./index.html'], corePlugins: process.env.CLEAN ? [] : {}, darkMode: 'class', theme: { variables: (theme) => ({ DEFAULT: { sizes: { small: '1rem', medium: '2rem', large: '3rem', '0.5': '2px', '1.0': { foo: '1rem', 2.4: '2rem', }, }, colors: { red: { 50: '#ff3232', 500: '#ff0000', 900: '#d70000', }, }, }, '.container': { sizes: { medium: '1.5rem', container: '2rem', }, }, }), }, plugins: [require('../../src/index')], } ================================================ FILE: examples/simple/tailwind.css ================================================ @tailwind base; @tailwind components; @tailwind utilities; ================================================ FILE: examples/use-host/clean.css ================================================ :host { --sizes-small: 1rem; --sizes-medium: 2rem; --sizes-large: 3rem; --sizes-0\.5: 2px; --sizes-1\.0-foo: 1rem; --sizes-1\.0-2\.4: 2rem; --colors-red-50: #ff3232; --colors-red-500: #ff0000; --colors-red-900: #d70000 } .container { --sizes-medium: 1.5rem; --sizes-container: 2rem } ================================================ FILE: examples/use-host/index.html ================================================ Use host example using @mertasan/tailwindcss-variables

Tailwindcss Variables

[simple example]

source
feature image
================================================ FILE: examples/use-host/package.json ================================================ { "name": "use-host", "version": "1.0.0", "scripts": { "build": "env NODE_ENV=production npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./style.css", "build:clean": "env NODE_ENV=production CLEAN=true npx tailwindcss build ./tailwind.css -c ./tailwind.config.js -o ./clean.css" }, "devDependencies": { "@mertasan/tailwindcss-variables": "latest", "autoprefixer": "^10.4.0", "postcss": "^8.4.4", "tailwindcss": "^3.0.11" }, "license": "MIT" } ================================================ FILE: examples/use-host/style.css ================================================ /* ! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com */ /* 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) */ *, ::before, ::after { box-sizing: border-box; /* 1 */ border-width: 0; /* 2 */ border-style: solid; /* 2 */ border-color: #e5e7eb; /* 2 */ } ::before, ::after { --tw-content: ''; } /* 1. Use a consistent sensible line-height in all browsers. 2. Prevent adjustments of font size after orientation changes in iOS. 3. Use a more readable tab size. 4. Use the user's configured `sans` font-family by default. 5. Use the user's configured `sans` font-feature-settings by default. 6. Use the user's configured `sans` font-variation-settings by default. */ html { line-height: 1.5; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ /* 3 */ tab-size: 4; /* 3 */ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */ font-feature-settings: normal; /* 5 */ font-variation-settings: normal; /* 6 */ } /* 1. Remove the margin in all browsers. 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. */ body { margin: 0; /* 1 */ line-height: inherit; /* 2 */ } /* 1. Add the correct height in Firefox. 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 3. Ensure horizontal rules are visible by default. */ hr { height: 0; /* 1 */ color: inherit; /* 2 */ border-top-width: 1px; /* 3 */ } /* Add the correct text decoration in Chrome, Edge, and Safari. */ abbr:where([title]) { -webkit-text-decoration: underline dotted; text-decoration: underline dotted; } /* Remove the default font size and weight for headings. */ h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; } /* Reset links to optimize for opt-in styling instead of opt-out. */ a { color: inherit; text-decoration: inherit; } /* Add the correct font weight in Edge and Safari. */ b, strong { font-weight: bolder; } /* 1. Use the user's configured `mono` font family by default. 2. Correct the odd `em` font sizing in all browsers. */ code, kbd, samp, pre { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */ font-size: 1em; /* 2 */ } /* Add the correct font size in all browsers. */ small { font-size: 80%; } /* Prevent `sub` and `sup` elements from affecting the line height in all browsers. */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sub { bottom: -0.25em; } sup { top: -0.5em; } /* 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 3. Remove gaps between table borders by default. */ table { text-indent: 0; /* 1 */ border-color: inherit; /* 2 */ border-collapse: collapse; /* 3 */ } /* 1. Change the font styles in all browsers. 2. Remove the margin in Firefox and Safari. 3. Remove default padding in all browsers. */ button, input, optgroup, select, textarea { font-family: inherit; /* 1 */ font-feature-settings: inherit; /* 1 */ font-variation-settings: inherit; /* 1 */ font-size: 100%; /* 1 */ font-weight: inherit; /* 1 */ line-height: inherit; /* 1 */ color: inherit; /* 1 */ margin: 0; /* 2 */ padding: 0; /* 3 */ } /* Remove the inheritance of text transform in Edge and Firefox. */ button, select { text-transform: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Remove default button styles. */ button, [type='button'], [type='reset'], [type='submit'] { -webkit-appearance: button; /* 1 */ background-color: transparent; /* 2 */ background-image: none; /* 2 */ } /* Use the modern Firefox focus style for all focusable elements. */ :-moz-focusring { outline: auto; } /* Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) */ :-moz-ui-invalid { box-shadow: none; } /* Add the correct vertical alignment in Chrome and Firefox. */ progress { vertical-align: baseline; } /* Correct the cursor style of increment and decrement buttons in Safari. */ ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; } /* 1. Correct the odd appearance in Chrome and Safari. 2. Correct the outline style in Safari. */ [type='search'] { -webkit-appearance: textfield; /* 1 */ outline-offset: -2px; /* 2 */ } /* Remove the inner padding in Chrome and Safari on macOS. */ ::-webkit-search-decoration { -webkit-appearance: none; } /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Change font properties to `inherit` in Safari. */ ::-webkit-file-upload-button { -webkit-appearance: button; /* 1 */ font: inherit; /* 2 */ } /* Add the correct display in Chrome and Safari. */ summary { display: list-item; } /* Removes the default spacing and border for appropriate elements. */ blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre { margin: 0; } fieldset { margin: 0; padding: 0; } legend { padding: 0; } ol, ul, menu { list-style: none; margin: 0; padding: 0; } /* Reset default styling for dialogs. */ dialog { padding: 0; } /* Prevent resizing textareas horizontally by default. */ textarea { resize: vertical; } /* 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 2. Set the default placeholder color to the user's configured gray 400 color. */ input::placeholder, textarea::placeholder { opacity: 1; /* 1 */ color: #9ca3af; /* 2 */ } /* Set the default cursor for buttons. */ button, [role="button"] { cursor: pointer; } /* Make sure disabled buttons don't get the pointer cursor. */ :disabled { cursor: default; } /* 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) This can trigger a poorly considered lint error in some tools but is included by design. */ img, svg, video, canvas, audio, iframe, embed, object { display: block; /* 1 */ vertical-align: middle; /* 2 */ } /* Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) */ img, video { max-width: 100%; height: auto; } /* Make elements with the HTML hidden attribute stay hidden by default */ [hidden] { display: none; } :host { --sizes-small: 1rem; --sizes-medium: 2rem; --sizes-large: 3rem; --sizes-0\.5: 2px; --sizes-1\.0-foo: 1rem; --sizes-1\.0-2\.4: 2rem; --colors-red-50: #ff3232; --colors-red-500: #ff0000; --colors-red-900: #d70000; } .container { --sizes-medium: 1.5rem; --sizes-container: 2rem; } *, ::before, ::after { --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; } ::backdrop { --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-pan-x: ; --tw-pan-y: ; --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; --tw-gradient-from-position: ; --tw-gradient-via-position: ; --tw-gradient-to-position: ; --tw-ordinal: ; --tw-slashed-zero: ; --tw-numeric-figure: ; --tw-numeric-spacing: ; --tw-numeric-fraction: ; --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; --tw-blur: ; --tw-brightness: ; --tw-contrast: ; --tw-grayscale: ; --tw-hue-rotate: ; --tw-invert: ; --tw-saturate: ; --tw-sepia: ; --tw-drop-shadow: ; --tw-backdrop-blur: ; --tw-backdrop-brightness: ; --tw-backdrop-contrast: ; --tw-backdrop-grayscale: ; --tw-backdrop-hue-rotate: ; --tw-backdrop-invert: ; --tw-backdrop-opacity: ; --tw-backdrop-saturate: ; --tw-backdrop-sepia: ; } .container { width: 100%; } @media (min-width: 640px) { .container { max-width: 640px; } } @media (min-width: 768px) { .container { max-width: 768px; } } @media (min-width: 1024px) { .container { max-width: 1024px; } } @media (min-width: 1280px) { .container { max-width: 1280px; } } @media (min-width: 1536px) { .container { max-width: 1536px; } } .order-1 { order: 1; } .-mx-3 { margin-left: -0.75rem; margin-right: -0.75rem; } .mx-auto { margin-left: auto; margin-right: auto; } .mb-12 { margin-bottom: 3rem; } .mb-4 { margin-bottom: 1rem; } .mt-4 { margin-top: 1rem; } .flex { display: flex; } .w-full { width: 100%; } .max-w-6xl { max-width: 72rem; } .flex-wrap { flex-wrap: wrap; } .items-center { align-items: center; } .bg-gray-50 { --tw-bg-opacity: 1; background-color: rgb(249 250 251 / var(--tw-bg-opacity)); } .px-10 { padding-left: 2.5rem; padding-right: 2.5rem; } .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; } .py-20 { padding-top: 5rem; padding-bottom: 5rem; } .text-2xl { font-size: 1.5rem; line-height: 2rem; } .text-3xl { font-size: 1.875rem; line-height: 2.25rem; } .text-base { font-size: 1rem; line-height: 1.5rem; } .font-bold { font-weight: 700; } .font-medium { font-weight: 500; } .font-semibold { font-weight: 600; } .leading-tight { line-height: 1.25; } .tracking-tight { letter-spacing: -0.025em; } .text-blue-500 { --tw-text-opacity: 1; color: rgb(59 130 246 / var(--tw-text-opacity)); } .text-green-500 { --tw-text-opacity: 1; color: rgb(34 197 94 / var(--tw-text-opacity)); } .hover\:text-blue-600:hover { --tw-text-opacity: 1; color: rgb(37 99 235 / var(--tw-text-opacity)); } @media (min-width: 640px) { .sm\:max-w-sm { max-width: 24rem; } .sm\:px-20 { padding-left: 5rem; padding-right: 5rem; } .sm\:text-3xl { font-size: 1.875rem; line-height: 2.25rem; } .sm\:text-5xl { font-size: 3rem; line-height: 1; } } @media (min-width: 768px) { .md\:px-32 { padding-left: 8rem; padding-right: 8rem; } } @media (min-width: 1024px) { .lg\:order-1 { order: 1; } .lg\:mb-0 { margin-bottom: 0px; } .lg\:w-1\/2 { width: 50%; } .lg\:max-w-full { max-width: 100%; } .lg\:max-w-md { max-width: 28rem; } .lg\:px-16 { padding-left: 4rem; padding-right: 4rem; } } @media (min-width: 1280px) { .xl\:mb-6 { margin-bottom: 1.5rem; } .xl\:mt-6 { margin-top: 1.5rem; } } ================================================ FILE: examples/use-host/tailwind.config.js ================================================ module.exports = { content: ['./index.html'], corePlugins: process.env.CLEAN ? [] : {}, theme: { variables: (theme) => ({ DEFAULT: { sizes: { small: '1rem', medium: '2rem', large: '3rem', '0.5': '2px', '1.0': { foo: '1rem', 2.4: '2rem', }, }, colors: { red: { 50: '#ff3232', 500: '#ff0000', 900: '#d70000', }, }, }, '.container': { sizes: { medium: '1.5rem', container: '2rem', }, }, }), }, plugins: [require('../../src/index')({ useHost: true })], } ================================================ FILE: examples/use-host/tailwind.css ================================================ @tailwind base; @tailwind components; @tailwind utilities; ================================================ FILE: package.json ================================================ { "name": "@mertasan/tailwindcss-variables", "version": "2.7.0", "description": "Easily create css variables without the need for a css file!", "main": "src/index.js", "license": "MIT", "repository": "https://github.com/mertasan/tailwindcss-variables", "bugs": { "url": "https://github.com/mertasan/tailwindcss-variables/issues" }, "homepage": "https://github.com/mertasan/tailwindcss-variables", "author": "Mert Aşan (https://github.com/mertasan)", "publishConfig": { "access": "public" }, "scripts": { "test": "jest", "test:update-snapshots": "jest -u", "test:coverage": "jest --coverage", "build": "env NODE_ENV=production node scripts/build.js", "build:clean": "env NODE_ENV=production CLEAN=true node scripts/build.js", "style": "eslint .", "lint": "npm run style", "format": "prettier --write ." }, "keywords": [ "tailwindcss", "tailwindcss variables", "tailwind variables", "css variables", "tailwind css variables", "tailwindcss css variables", "tailwindcss dark mode", "tailwindcss multi theme" ], "dependencies": { "lodash": "^4.17.21" }, "devDependencies": { "autoprefixer": "^10.4.13", "cross-env": "^7.0.3", "eslint": "^8.23.1", "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.2.1", "fs-extra": "^10.0.0", "jest": "^29.4.3", "postcss": "^8.4.21", "postcss-import": "^14.1.0", "prettier": "^2.5.0", "snapshot-diff": "^0.10.0", "tailwindcss": "^3.2.7" }, "peerDependencies": { "autoprefixer": "^10.0.2", "postcss": "^8.0.9" }, "prettier": { "semi": false, "singleQuote": true, "printWidth": 120, "tabWidth": 2, "useTabs": false, "trailingComma": "es5", "bracketSpacing": true, "parser": "flow", "overrides": [ { "files": [ "**/*.css", "**/*.scss", "**/*.html" ], "options": { "singleQuote": false } } ] }, "jest": { "testTimeout": 30000, "testMatch": [ "/__tests__/**/*.test.js" ], "collectCoverageFrom": [ "src/**/*.js", "!**/node_modules/**" ], "testPathIgnorePatterns": [ "/__tests__/util/" ], "collectCoverage": true, "coverageReporters": [ "json", "html" ] }, "browserslist": [ "> 1%", "not edge <= 18", "not ie 11", "not op_mini all" ], "engines": { "node": ">=12.13.0" } } ================================================ FILE: scripts/build.js ================================================ const fs = require('fs') const postcss = require('postcss') const tailwind = require('tailwindcss') function buildDistFile(examplePath, message) { console.info('Building: ' + message + '...') let styleFilename = 'style' if (process.env.CLEAN) { styleFilename = 'clean' } return postcss([ tailwind({ ...require('../' + examplePath + '/tailwind.config'), content: ['./' + examplePath + '/*.html'], }), require('autoprefixer'), ]) .process(['@tailwind base;', '@tailwind components;', '@tailwind utilities;'].join('\n'), { from: undefined, to: `./${examplePath}/${styleFilename}.css`, map: false, }) .then((result) => { fs.writeFileSync(`./${examplePath}/${styleFilename}.css`, result.css) return result }) .catch((error) => { console.log(error) }) } console.info('Building...') Promise.all([ buildDistFile('examples/simple', 'Examples -> simple'), buildDistFile('examples/prefix', 'Examples -> prefix'), buildDistFile('examples/dark-custom-selector', 'Examples -> dark-custom-selector'), buildDistFile('examples/dark-with-class', 'Examples -> dark-with-class'), buildDistFile('examples/dark-with-class-to-root', 'Examples -> dark-with-class-to-root'), buildDistFile('examples/dark-with-media', 'Examples -> dark-with-media'), buildDistFile('examples/color-variable-helper', 'Examples -> color-variable-helper'), ]).then(() => { console.log('Finished building.') }) ================================================ FILE: src/helpers.js ================================================ const startsWith = require('lodash/startsWith') const mapValues = require('lodash/mapValues') const isPlainObject = require('lodash/isPlainObject') const includes = require('lodash/includes') const withFallback = (variable, startsWithVar = false) => { if (includes(variable, ',')) { variable = variable.replace(',', '-rgb,') return startsWithVar ? variable : variable + ')' } else { return startsWithVar ? variable.replace(')', '-rgb)') : variable + '-rgb' } } const withRgb = (variable, forceRGB) => { if (forceRGB) { return startsWith(variable, 'var') ? variable : 'var(' + variable + ')' } return startsWith(variable, 'var') ? withFallback(variable, true) : 'var(' + withFallback(variable) + ')' } const colorVariable = (variable, forceRGB = false) => { return function ({ opacityVariable, opacityValue }) { if (opacityValue !== undefined) { return `rgba(${withRgb(variable, forceRGB)}, ${opacityValue})` } if (opacityVariable !== undefined) { return `rgba(${withRgb(variable, forceRGB)}, var(${opacityVariable}, 1))` } return `rgb(${withRgb(variable, forceRGB)})` } } const setColorVariable = (color, forceRGB) => { return startsWith(color, 'var') ? colorVariable(color, forceRGB) : color } const convertColorVariables = (colors, forceRGB) => { return mapValues(colors, (color) => isPlainObject(color) ? mapValues(color, (subColor) => setColorVariable(subColor, forceRGB)) : setColorVariable(color, forceRGB) ) } module.exports.colorVariable = colorVariable module.exports.convertColorVariables = convertColorVariables ================================================ FILE: src/index.js ================================================ const plugin = require('tailwindcss/plugin') const isEmpty = require('lodash/isEmpty') const isUndefined = require('lodash/isUndefined') const api = require('./pluginApi') const has = require('lodash/has') const get = require('lodash/get') const { convertColorVariables } = require('./helpers') /** * @typedef pluginOptions * @property {Boolean} darkToRoot * @property {Boolean} useHost * @property {Object} extendColors * @property {Boolean} forceRGB * @property {Boolean} toBase * @property {Boolean} colorVariables * @property {String} variablePrefix * @property {String} darkSelector - @deprecated */ /** * @typedef {Object} plugin * @property {function} withOptions */ module.exports = plugin.withOptions( /** * @param {pluginOptions} options */ function (options) { return function ({ addBase, addComponents, theme, config }) { let variables = theme('variables', {}) let darkVariables = theme('darkVariables', {}) let toBase = get(options, 'toBase', true) if (!isEmpty(variables)) { let getVariables = api.variables(variables, options) toBase ? addBase(getVariables) : addComponents(getVariables) } if (isUndefined(options)) { options = {} } let [mode, darkSelector = get(options, 'darkSelector', '.dark') ?? '.dark'] = [].concat( config('darkMode', 'media') ) options.darkSelector = darkSelector if (!isEmpty(darkVariables) && ['class', 'media'].includes(mode)) { let getDarkVariables = api.darkVariables(darkVariables, options, mode) toBase ? addBase(getDarkVariables) : addComponents(getDarkVariables) } } }, (options) => ({ theme: { extend: { colors: has(options, 'extendColors') ? convertColorVariables(options.extendColors, options.forceRGB ? options.forceRGB : false) : {}, }, }, }) ) ================================================ FILE: src/pluginApi.js ================================================ const fromPairs = require('lodash/fromPairs') const toPairs = require('lodash/toPairs') const merge = require('lodash/merge') const isEmpty = require('lodash/isEmpty') const _forEach = require('lodash/forEach') const has = require('lodash/has') const { setVariable, setDarkMediaVariable, setComponent, build, darkBuild, flattenOptions } = require('./utils') const variables = (variables, options) => { let variableList = {} let data = build(options, variables) _forEach(data, (value, key) => merge(variableList, setVariable(key, fromPairs(value)))) return variableList } const darkVariables = (variables, options, darkMode = 'media') => { let variableList = {} if (darkMode === 'class' || darkMode === 'media') { if (!has(options, 'darkSelector')) { options.darkSelector = '.dark' } let data = darkBuild(options, darkMode, variables) _forEach(data, (value, key) => merge( variableList, darkMode === 'media' ? setDarkMediaVariable(key, fromPairs(value)) : setVariable(key, fromPairs(value)) ) ) } return variableList } const getComponents = (selector, components) => { let componentList = {} selector = isEmpty(selector) ? '' : selector toPairs(flattenOptions(components)).forEach(([key, config]) => { const modifier = key === 'DEFAULT' ? '' : isEmpty(selector) ? `${key}` : `-${key}` toPairs(config) .filter(([, options]) => !isEmpty(options)) .forEach(([subKey, options]) => merge(componentList, setComponent(selector, modifier, options))) }) return componentList } module.exports.getComponents = getComponents module.exports.variables = variables module.exports.darkVariables = darkVariables ================================================ FILE: src/utils.js ================================================ const merge = require('lodash/merge') const fromPairs = require('lodash/fromPairs') const toPairs = require('lodash/toPairs') const assign = require('lodash/assign') const entries = require('lodash/entries') const indexOf = require('lodash/indexOf') const isPlainObject = require('lodash/isPlainObject') const hasOwn = require('lodash/has') const _forEach = require('lodash/forEach') const _replace = require('lodash/replace') const startsWith = require('lodash/startsWith') const trimStart = require('lodash/trimStart') const trimEnd = require('lodash/trimEnd') const get = require('lodash/get') const setComponent = (component, modifier, options) => { return { [`${component}${modifier}`]: options } } const setVariable = (themeName, options) => { return { [`${themeName}`]: options } } const setDarkMediaVariable = (themeName, options) => { return { ['@media (prefers-color-scheme: dark)']: { [`${themeName}`]: options, }, } } const flattenOptions = (options) => { return merge( {}, ...toPairs(options).map(([keys, value]) => { const flattenValue = isPlainObject(value) ? flattenOptions(value) : value return fromPairs(keys.split(', ').map((key) => [key, flattenValue])) }) ) } const formatVariableKey = (key) => { if (key === 'DEFAULT') { return '' } key = key.toString() return key .replace(/_/g, '-') .replace(/[^a-zA-Z0-9-.]+/gi, '') .replace(/\./gi, '\\.') .replace('---', '--') } const splitVars = (source) => { let results = {} ;(function recurse(obj, current) { for (let key in obj) { let newKey = formatVariableKey(current ? current + '-' + key : key) if (indexOf(obj, key) && isPlainObject(obj[key])) { recurse(value, newKey) } else { results[newKey] = obj[key] } } })(source) return entries(results) } const parseVariables = (object, varPrefix) => { let newObject = {} let results = [] function recurse(object, varPrefix) { for (let key in object) { let pre = _replace(varPrefix === undefined ? '' : varPrefix + '-', '---', '--') let formattedKey = formatVariableKey(key) if (hasOwn(object, key) && isPlainObject(object[key])) { newObject = recurse(object[key], formattedKey ? pre + formattedKey : pre.slice(0, -1)) } else { newObject[formattedKey ? pre + formattedKey : pre.slice(0, -1)] = `${object[key]}` } } return newObject } _forEach(splitVars(recurse(object, '--' + varPrefix)), ([key, items]) => results.push([key, items])) return results } const RGBAtoRGB = (rgba) => { rgba = trimStart(rgba, 'rgba(') rgba = trimEnd(rgba, ')') return rgba.substring(0, rgba.lastIndexOf(',')) } const getRGBKey = (key, forceRGB) => { if (forceRGB) { return key } if (key === 'DEFAULT') { return 'rgb' } else { return key + '-rgb' } } const hexToRGB = (key, h, forceRGB) => { if (startsWith(h, 'rgba')) { return [getRGBKey(key, forceRGB), RGBAtoRGB(h)] } else if (startsWith(h, 'rgb')) { h = trimStart(h, 'rgb(') h = trimEnd(h, ')') return [getRGBKey(key, forceRGB), h] } else if (!startsWith(h, '#')) { return [key, h] } let r = 0, g = 0, b = 0 // 3 digits if (h.length === 4) { r = '0x' + h[1] + h[1] g = '0x' + h[2] + h[2] b = '0x' + h[3] + h[3] // 6 digits } else if (h.length === 7) { r = '0x' + h[1] + h[2] g = '0x' + h[3] + h[4] b = '0x' + h[5] + h[6] } return [getRGBKey(key, forceRGB), '' + +r + ',' + +g + ',' + +b + ''] } const setColorVariables = (source, forceRGB) => { return merge( source, ...toPairs(source).map(([keys, value]) => { const flattenValue = isPlainObject(value) ? setColorVariables(value, forceRGB) : value return fromPairs(keys.split(', ').map((key) => hexToRGB(key, flattenValue, forceRGB))) }) ) } const build = (options, source) => { let varPrefix = formatVariableKey(get(options, 'variablePrefix', '')) let colorVariables = get(options, 'colorVariables', false) let forceRGB = get(options, 'forceRGB', false) let cssBaseKey = get(options, 'useHost', false) ? `:host` : `:root` if (colorVariables) { source = setColorVariables(source, forceRGB) } if (!varPrefix) { varPrefix = '' } let componentOptions = {} _forEach(toPairs(flattenOptions(source)), ([key, config]) => { let block = key === 'DEFAULT' ? cssBaseKey : `${key}` if (!hasOwn(componentOptions, block)) { componentOptions[block] = [] } assign(componentOptions[block], parseVariables(config, varPrefix)) }) return componentOptions } const darkBuild = (options, darkMode, source) => { let varPrefix = formatVariableKey(get(options, 'variablePrefix', '')) if (!varPrefix) { varPrefix = '' } let colorVariables = get(options, 'colorVariables', false) let forceRGB = get(options, 'forceRGB', false) if (colorVariables) { source = setColorVariables(source, forceRGB) } let darkSelector = get(options, 'darkSelector') let darkToRoot = hasOwn(options, 'darkToRoot') ? options.darkToRoot : true let cssBaseKey = get(options, 'useHost', false) ? `:host` : `:root` let componentOptions = {} _forEach(toPairs(flattenOptions(source)), ([key, config]) => { let block if (key === 'DEFAULT') { if (darkMode === 'class') { block = darkToRoot ? `${cssBaseKey}${darkSelector}` : `${darkSelector}` } else { block = `${cssBaseKey}` } } else { if (darkMode === 'class') { block = darkToRoot ? `${cssBaseKey}${darkSelector} ${key}` : `${darkSelector} ${key}` } else { block = `${key}` } } if (!hasOwn(componentOptions, block)) { componentOptions[block] = [] } assign(componentOptions[block], parseVariables(config, varPrefix)) }) return componentOptions } module.exports.build = build module.exports.darkBuild = darkBuild module.exports.flattenOptions = flattenOptions module.exports.setComponent = setComponent module.exports.setVariable = setVariable module.exports.setDarkMediaVariable = setDarkMediaVariable