├── .husky ├── pre-commit └── commit-msg ├── src └── cli │ ├── lib │ ├── non-configurable │ │ ├── svg.ts │ │ ├── sizing.ts │ │ ├── spacing.ts │ │ ├── transitionsAndAnimations.ts │ │ ├── accessibility.ts │ │ ├── transforms.ts │ │ ├── filters.ts │ │ ├── tables.ts │ │ ├── grid.ts │ │ ├── borders.ts │ │ ├── backgrounds.ts │ │ ├── effects.ts │ │ ├── interactivity.ts │ │ ├── index.ts │ │ ├── typography.ts │ │ ├── flexbox.ts │ │ └── layout.ts │ ├── tailwindlabs-plugins │ │ └── index.ts │ └── defaultTailwindConfig.ts │ ├── types │ ├── config.ts │ └── classes.ts │ ├── core │ ├── constants │ │ ├── baseVariants.ts │ │ ├── regularClassGroupKeys.ts │ │ └── tailwindColors.ts │ ├── GeneratedFileWriter.ts │ ├── TailwindConfigParser.ts │ ├── FileContentGenerator.ts │ └── ClassnamesGenerator.ts │ └── index.ts ├── .prettierignore ├── commitlint.config.js ├── discover.png ├── lint-staged.config.js ├── .github ├── dependabot.yaml ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── 1-feature-request.md │ └── 0-bug-report.md ├── workflows │ ├── lint.yml │ ├── semantic.yml │ ├── release.yml │ └── publish.yml └── FUNDING.yml ├── CODE_OF_CONDUCT.md ├── .prettierrc ├── .editorconfig ├── tsconfig.json ├── rollup.config.js ├── jest.config.js ├── scripts └── updateDefaultConfig.js ├── LICENSE ├── .gitignore ├── CONTRIBUTING.md ├── eslint.config.mjs ├── package.json ├── README.md └── CHANGELOG.md /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | lint-staged 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | commitlint --edit $1 2 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/svg.ts: -------------------------------------------------------------------------------- 1 | export default {}; 2 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/sizing.ts: -------------------------------------------------------------------------------- 1 | export default {}; 2 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/spacing.ts: -------------------------------------------------------------------------------- 1 | export default {}; 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | dist 4 | es 5 | /lib 6 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/transitionsAndAnimations.ts: -------------------------------------------------------------------------------- 1 | export default {}; 2 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { extends: ["@commitlint/config-conventional"] }; 2 | -------------------------------------------------------------------------------- /discover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muhammadsammy/tailwindcss-classnames/HEAD/discover.png -------------------------------------------------------------------------------- /lint-staged.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "*.ts": ["eslint"], 3 | "**/*.+(json|ts|yml|yaml|md|mdx)": ["prettier --write", "git add"], 4 | }; 5 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/accessibility.ts: -------------------------------------------------------------------------------- 1 | const screenReaders = ["sr-only", "not-sr-only"]; 2 | 3 | export default { 4 | screenReaders, 5 | }; 6 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/transforms.ts: -------------------------------------------------------------------------------- 1 | const hardwareAcceleration = ["transform-gpu"]; 2 | 3 | export default { 4 | hardwareAcceleration, 5 | }; 6 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | open-pull-requests-limit: 5 8 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/filters.ts: -------------------------------------------------------------------------------- 1 | const filter = ["filter", "filter-none"]; 2 | const backdropFilter = ["backdrop-filter", "backdrop-filter-none"]; 3 | 4 | export default { 5 | filter, 6 | backdropFilter, 7 | }; 8 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/tables.ts: -------------------------------------------------------------------------------- 1 | const borderCollapse = ["border-collapse", "border-separate"]; 2 | 3 | const tableLayout = ["table-auto", "table-fixed"]; 4 | 5 | export default { 6 | borderCollapse, 7 | tableLayout, 8 | }; 9 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/grid.ts: -------------------------------------------------------------------------------- 1 | const gridAutoFlow = [ 2 | "grid-flow-row", 3 | "grid-flow-col", 4 | "grid-flow-dense", 5 | "grid-flow-row-dense", 6 | "grid-flow-col-dense", 7 | ]; 8 | 9 | export default { 10 | gridAutoFlow, 11 | }; 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | 3 | contact_links: 4 | - name: Questions 5 | url: https://github.com/muhammadsammy/tailwindcss-classnames/discussions/new 6 | about: Please ask and answer questions or any discussions here. 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1-feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest a feature or an improvement to the project. 4 | labels: "enhancement" 5 | --- 6 | 7 | # Summary 8 | 9 | - [ ] I'm willing to implement this feature 10 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | This project adheres to No Code of Conduct. We are all adults. We accept anyone's contributions. Nothing else matters. 4 | 5 | For more information please visit the [No Code of Conduct](https://github.com/domgetter/NCoC) homepage. 6 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": false, 3 | "arrowParens": "avoid", 4 | "endOfLine": "lf", 5 | "quoteProps": "as-needed", 6 | "semi": true, 7 | "useTabs": true, 8 | "tabWidth": 4, 9 | "trailingComma": "all", 10 | "printWidth": 120, 11 | "bracketSpacing": true 12 | } 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.{yml,yaml}] 12 | indent_style = space 13 | indent_size = 4 14 | 15 | [*.{js,ts,json}] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /src/cli/lib/tailwindlabs-plugins/index.ts: -------------------------------------------------------------------------------- 1 | const pluginTypography = ["prose", "prose-sm", "prose-lg", "prose-xl", "prose-2xl"]; 2 | 3 | const pluginCustomForms = [ 4 | "form-input", 5 | "form-textarea", 6 | "form-select", 7 | "form-multiselect", 8 | "form-checkbox", 9 | "form-radio", 10 | ]; 11 | 12 | export const tailwindLabsPlugins = { 13 | pluginTypography, 14 | pluginCustomForms, 15 | }; 16 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | lint: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v4 9 | with: 10 | fetch-depth: 0 11 | - uses: oven-sh/setup-bun@v2 12 | 13 | - run: bun install 14 | - name: lint 15 | run: bun run lint 16 | -------------------------------------------------------------------------------- /.github/workflows/semantic.yml: -------------------------------------------------------------------------------- 1 | name: "Semantic PR" 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | - edited 8 | - reopened 9 | 10 | jobs: 11 | main: 12 | name: Validate PR title 13 | runs-on: ubuntu-latest 14 | permissions: 15 | pull-requests: read 16 | steps: 17 | - uses: amannn/action-semantic-pull-request@v5 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/borders.ts: -------------------------------------------------------------------------------- 1 | const borderStyle = ["border-solid", "border-dashed", "border-dotted", "border-double", "border-hidden", "border-none"]; 2 | 3 | const divideStyle = ["divide-solid", "divide-dashed", "divide-dotted", "divide-double", "divide-none"]; 4 | 5 | const outlineStyle = [ 6 | "outline", 7 | "outline-dashed", 8 | "outline-dotted", 9 | "outline-double", 10 | "outline-hidden", 11 | "outline-none", 12 | ]; 13 | 14 | export default { 15 | borderStyle, 16 | divideStyle, 17 | outlineStyle, 18 | }; 19 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | 6 | permissions: 7 | contents: write 8 | pull-requests: write 9 | 10 | name: release-please 11 | 12 | jobs: 13 | release-please: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: googleapis/release-please-action@v4 17 | with: 18 | token: ${{ secrets.GITHUB_TOKEN }} 19 | release-type: node 20 | package-name: tailwindcss-classnames 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "rootDir": "src", 6 | "outDir": ".code", 7 | "lib": ["dom", "es2019"], 8 | "moduleResolution": "node", 9 | "importHelpers": true, 10 | "declaration": true, 11 | "pretty": true, 12 | "sourceMap": true, 13 | "inlineSources": true, 14 | "esModuleInterop": true, 15 | "resolveJsonModule": true, 16 | "strict": true, 17 | "skipLibCheck": true 18 | }, 19 | "include": ["src"], 20 | "exclude": ["node_modules", "dist", "es", "lib"] 21 | } 22 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/backgrounds.ts: -------------------------------------------------------------------------------- 1 | const backgroundAttachment = ["bg-fixed", "bg-local", "bg-scroll"]; 2 | 3 | const backgroundClip = ["bg-clip-border", "bg-clip-padding", "bg-clip-content", "bg-clip-text"]; 4 | 5 | const backgroundOrigin = ["bg-origin-border", "bg-origin-padding", "bg-origin-content"]; 6 | 7 | const backgroundRepeat = [ 8 | "bg-repeat", 9 | "bg-no-repeat", 10 | "bg-repeat-x", 11 | "bg-repeat-y", 12 | "bg-repeat-round", 13 | "bg-repeat-space", 14 | ]; 15 | 16 | export default { 17 | backgroundAttachment, 18 | backgroundClip, 19 | backgroundOrigin, 20 | backgroundRepeat, 21 | }; 22 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | on: 2 | release: 3 | types: 4 | - released 5 | 6 | name: Publish to NPM 7 | 8 | jobs: 9 | publish: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: actions/setup-node@v4 14 | with: 15 | node-version: 22 16 | registry-url: "https://registry.npmjs.org" 17 | - run: npm i -g dts-bundle 18 | - run: npm install 19 | - run: npm publish 20 | env: 21 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/0-bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Something is not working correctly. 4 | labels: "bug" 5 | --- 6 | 7 | ## Environment: 8 | 9 | - `TailwindCSS` version: 10 | - `tailwindcss-classnames` version: 11 | - `Node.js` version: 12 | 13 | ## Current Behavior 14 | 15 | ## Expected Behavior 16 | 17 | ## How to Reproduce 18 | 19 | ## Possible solutions (Optional) 20 | 21 | 22 | 23 | ## Additional Questions 24 | 25 | - [ ] I've searched the issues list and this is not a duplicate 26 | - [ ] I'm willing to fix this error 27 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: tailwindcss-classnames 6 | liberapay: muhammadsammy 7 | ko_fi: # Replace with a single Ko-fi username 8 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 9 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import sourcemaps from "rollup-plugin-sourcemaps"; 2 | import nodeResolve from "rollup-plugin-node-resolve"; 3 | import nodeGlobals from "rollup-plugin-node-globals"; 4 | import nodeBuiltins from "rollup-plugin-node-builtins"; 5 | import commonjs from "rollup-plugin-commonjs"; 6 | import { terser } from "rollup-plugin-terser"; 7 | import { pascalCase } from "pascal-case"; 8 | import pkg from "./package.json"; 9 | 10 | export default { 11 | input: "es/index.js", 12 | output: { 13 | name: pascalCase(pkg.name), 14 | file: "dist/bundle.js", 15 | format: "umd", 16 | exports: "named", 17 | sourcemap: true, 18 | amd: { 19 | id: pkg.name, 20 | }, 21 | }, 22 | plugins: [sourcemaps(), nodeResolve(), nodeGlobals(), nodeBuiltins(), commonjs(), terser()], 23 | }; 24 | -------------------------------------------------------------------------------- /src/cli/types/config.ts: -------------------------------------------------------------------------------- 1 | import { baseVariants } from "../core/constants/baseVariants"; 2 | import { defaultTailwindConfig } from "../lib/defaultTailwindConfig"; 3 | 4 | export type TTailwindCSSConfig = Partial< 5 | typeof defaultTailwindConfig & Record<"separator" | "prefix" | "mode", string> 6 | >; 7 | 8 | export type TConfigDarkMode = false | "media" | "class" | ["media" | "class", string]; 9 | 10 | export type TConfigTheme = TThemeItems & { extend?: TThemeItems }; 11 | 12 | export type TConfigVariants = TVariantsItems & { 13 | extend?: Partial; 14 | }; 15 | 16 | export type TConfigPlugins = Partial>; 17 | 18 | export type TThemeItems = typeof defaultTailwindConfig.theme; 19 | 20 | type TVariantsItems = typeof baseVariants; 21 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const semver = require("semver"); 3 | 4 | function getSupportedTypescriptTarget() { 5 | const nodeVersion = process.versions.node; 6 | 7 | if (semver.gt(nodeVersion, "10.0.0")) { 8 | return "es2018"; 9 | } else if (semver.gt(nodeVersion, "7.6.0")) { 10 | return "es2017"; 11 | } else if (semver.gt(nodeVersion, "7.0.0")) { 12 | return "es2016"; 13 | } else if (semver.gt(nodeVersion, "6.0.0")) { 14 | return "es2015"; 15 | } else { 16 | return "es5"; 17 | } 18 | } 19 | 20 | module.exports = { 21 | testURL: "http://localhost", 22 | preset: "ts-jest", 23 | collectCoverageFrom: ["src/**/*.{t,j}s?(x)", "!src/**/*.d.ts"], 24 | globals: { 25 | "ts-jest": { 26 | tsConfig: { 27 | target: getSupportedTypescriptTarget(), 28 | }, 29 | }, 30 | }, 31 | }; 32 | -------------------------------------------------------------------------------- /scripts/updateDefaultConfig.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs").promises; 2 | const colors = require("@colors/colors"); 3 | 4 | // updates 'defaultTailwindConfig' in src/cli/lib/defaultTailwindConfig.ts 5 | // with the latest config from tailwindcss. used in npm scripts 6 | async function updateDefaultTailwindConfig() { 7 | try { 8 | let data = await fs.readFile("./tailwind.config.js"); 9 | data = data.toString().replace("module.exports =", "export const defaultTailwindConfig ="); 10 | await fs.writeFile( 11 | "./src/cli/lib/defaultTailwindConfig.ts", 12 | "/* eslint-disable */" + "\n" + "// @ts-nocheck" + "\n\n" + data, 13 | ); 14 | console.log(("\n\n" + "Successfully updated defaultTailwindConfig.ts" + "\n").bgGreen.black + "\n\n"); 15 | } catch (error) { 16 | const msg = "\n\n" + "Failed updating defaultTailwindConfig.ts:".bold + "\n" + error.message + "\n"; 17 | console.error(msg.bgRed.white); 18 | } 19 | } 20 | 21 | updateDefaultTailwindConfig(); 22 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/effects.ts: -------------------------------------------------------------------------------- 1 | const mixBlendMode = [ 2 | "mix-blend-normal", 3 | "mix-blend-multiply", 4 | "mix-blend-screen", 5 | "mix-blend-overlay", 6 | "mix-blend-darken", 7 | "mix-blend-lighten", 8 | "mix-blend-color-dodge", 9 | "mix-blend-color-burn", 10 | "mix-blend-hard-light", 11 | "mix-blend-soft-light", 12 | "mix-blend-difference", 13 | "mix-blend-exclusion", 14 | "mix-blend-hue", 15 | "mix-blend-saturation", 16 | "mix-blend-color", 17 | "mix-blend-luminosity", 18 | "mix-blend-plus-lighter", 19 | ]; 20 | 21 | const backgroundBlendMode = [ 22 | "bg-blend-normal", 23 | "bg-blend-multiply", 24 | "bg-blend-screen", 25 | "bg-blend-overlay", 26 | "bg-blend-darken", 27 | "bg-blend-lighten", 28 | "bg-blend-color-dodge", 29 | "bg-blend-color-burn", 30 | "bg-blend-hard-light", 31 | "bg-blend-soft-light", 32 | "bg-blend-difference", 33 | "bg-blend-exclusion", 34 | "bg-blend-hue", 35 | "bg-blend-saturation", 36 | "bg-blend-color", 37 | "bg-blend-luminosity", 38 | ]; 39 | 40 | export default { 41 | mixBlendMode, 42 | backgroundBlendMode, 43 | }; 44 | -------------------------------------------------------------------------------- /src/cli/core/constants/baseVariants.ts: -------------------------------------------------------------------------------- 1 | export const baseVariants = [ 2 | // 'responsive', 3 | "motion-safe", 4 | "motion-reduce", 5 | "first", 6 | "last", 7 | "odd", 8 | "even", 9 | "visited", 10 | "checked", 11 | "group", // 12 | "group-hover", 13 | "group-focus", 14 | "focus-within", 15 | "hover", 16 | "focus", 17 | "focus-visible", 18 | "active", 19 | "disabled", 20 | "enabled", 21 | "backdrop", 22 | "contrast-more", 23 | "contrast-less", 24 | // Exhaustive pseudo-classess 25 | "only", 26 | "first-of-type", 27 | "last-of-type", 28 | "only-of-type", 29 | "target", 30 | "default", 31 | "indeterminate", 32 | "placeholder-shown", 33 | "autofill", 34 | "optional", 35 | "required", 36 | "valid", 37 | "invalid", 38 | "in-range", 39 | "out-of-range", 40 | // New peer-*, selection & marker variants and before/after 41 | "peer", // 42 | "peer-hover", 43 | "peer-checked", 44 | "peer-focus", 45 | "selection", 46 | "marker", 47 | "before", 48 | "after", 49 | "portrait", 50 | "landscape", 51 | "open", 52 | "file", 53 | "placeholder", 54 | "print", 55 | "ltr", 56 | "rtl", 57 | // dark mode utility 58 | // 'dark', // 59 | ]; 60 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/interactivity.ts: -------------------------------------------------------------------------------- 1 | const appearance = ["appearance-none"]; 2 | 3 | const pointerEvents = ["pointer-events-none", "pointer-events-auto"]; 4 | 5 | const resize = ["resize-none", "resize", "resize-y", "resize-x"]; 6 | 7 | const userSelect = ["select-none", "select-text", "select-all", "select-auto"]; 8 | 9 | const scrollSnap = [ 10 | // scroll snap align 11 | "snap-start", 12 | "snap-end", 13 | "snap-center", 14 | "snap-align-none", 15 | // scroll snap stop 16 | "snap-normal", 17 | "snap-always", 18 | // scroll snap type 19 | "snap-none", 20 | "snap-x", 21 | "snap-y", 22 | "snap-both", 23 | "snap-mandatory", 24 | "snap-proximity", 25 | ]; 26 | 27 | const scrollBehavior = ["scroll-auto", "scroll-smooth"]; 28 | 29 | const touchAction = [ 30 | "touch-auto", 31 | "touch-none", 32 | "touch-pan-x", 33 | "touch-pan-left", 34 | "touch-pan-right", 35 | "touch-pan-y", 36 | "touch-pan-up", 37 | "touch-pan-down", 38 | "touch-pinch-zoom", 39 | "touch-manipulation", 40 | ]; 41 | 42 | export default { 43 | appearance, 44 | pointerEvents, 45 | resize, 46 | userSelect, 47 | scrollSnap, 48 | scrollBehavior, 49 | touchAction, 50 | }; 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Christian Alfoni, Muhammad Sammy and the contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/index.ts: -------------------------------------------------------------------------------- 1 | import accessibility from "./accessibility"; 2 | import backgrounds from "./backgrounds"; 3 | import borders from "./borders"; 4 | import effects from "./effects"; 5 | import filters from "./filters"; 6 | import flexBox from "./flexbox"; 7 | import grid from "./grid"; 8 | import interactivity from "./interactivity"; 9 | import layout from "./layout"; 10 | import sizing from "./sizing"; 11 | import spacing from "./spacing"; 12 | import svg from "./svg"; 13 | import tables from "./tables"; 14 | import transforms from "./transforms"; 15 | import transitionsAndAnimations from "./transitionsAndAnimations"; 16 | import typography from "./typography"; 17 | 18 | // These utility classes are classes that their names does not change. Their names are not 19 | // configured by the `tailwind.config.js` file. e.g. 'flex-start', 'object-cover' etc. 20 | // the only configuration that is applicable to these classes are pseudo-class variants. 21 | export const nonConfigurableClassNames = { 22 | accessibility, 23 | backgrounds, 24 | borders, 25 | effects, 26 | filters, 27 | flexBox, 28 | grid, 29 | interactivity, 30 | layout, 31 | sizing, 32 | spacing, 33 | svg, 34 | tables, 35 | transforms, 36 | transitionsAndAnimations, 37 | typography, 38 | }; 39 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/typography.ts: -------------------------------------------------------------------------------- 1 | const fontSmoothing = ["antialiased", "subpixel-antialiased"]; 2 | 3 | const fontStyle = ["italic", "non-italic"]; 4 | 5 | const fontVariantNumeric = [ 6 | "normal-nums", 7 | "ordinal", 8 | "slashed-zero", 9 | "lining-nums", 10 | "oldstyle-nums", 11 | "proportional-nums", 12 | "tabular-nums", 13 | "diagonal-fractions", 14 | "stacked-fractions", 15 | ]; 16 | 17 | const listStylePosition = ["list-inside", "list-outside"]; 18 | 19 | const textAlign = ["text-left", "text-center", "text-right", "text-justify", "text-start", "text-end"]; 20 | 21 | const textDecoration = ["underline", "line-through", "no-underline"]; 22 | 23 | const textTransform = ["uppercase", "lowercase", "capitalize", "normal-case"]; 24 | 25 | const textOverflow = ["truncate", "text-ellipsis", "text-clip"]; 26 | 27 | const verticalAlign = [ 28 | "align-baseline", 29 | "align-top", 30 | "align-middle", 31 | "align-bottom", 32 | "align-text-top", 33 | "align-text-bottom", 34 | "align-sub", 35 | "align-super", 36 | ]; 37 | 38 | const whitespace = [ 39 | "whitespace-normal", 40 | "whitespace-nowrap", 41 | "whitespace-pre", 42 | "whitespace-pre-line", 43 | "whitespace-pre-wrap", 44 | ]; 45 | 46 | const wordBreak = ["break-normal", "break-words", "break-all", "break-keep"]; 47 | 48 | const textDecorationStyle = [ 49 | "decoration-solid", 50 | "decoration-double", 51 | "decoration-dotted", 52 | "decoration-dashed", 53 | "decoration-wavy", 54 | ]; 55 | 56 | export default { 57 | fontSmoothing, 58 | fontStyle, 59 | fontVariantNumeric, 60 | listStylePosition, 61 | textAlign, 62 | textDecoration, 63 | textTransform, 64 | textOverflow, 65 | verticalAlign, 66 | whitespace, 67 | wordBreak, 68 | textDecorationStyle, 69 | }; 70 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/flexbox.ts: -------------------------------------------------------------------------------- 1 | const flexDirection = ["flex-row", "flex-row-reverse", "flex-col", "flex-col-reverse"]; 2 | 3 | const flexWrap = ["flex-nowrap", "flex-wrap", "flex-wrap-reverse"]; 4 | 5 | const alignItems = ["items-stretch", "items-start", "items-center", "items-end", "items-baseline"]; 6 | 7 | const alignContent = [ 8 | "content-start", 9 | "content-center", 10 | "content-end", 11 | "content-between", 12 | "content-around", 13 | "content-baseline", 14 | ]; 15 | 16 | const alignSelf = ["self-auto", "self-start", "self-center", "self-end", "self-stretch", "self-baseline"]; 17 | 18 | const placeContent = [ 19 | "place-content-start", 20 | "place-content-center", 21 | "place-content-end", 22 | "place-content-between", 23 | "place-content-around", 24 | "place-content-evenly", 25 | "place-content-stretch", 26 | "place-content-baseline", 27 | ]; 28 | 29 | const placeItems = [ 30 | "place-items-auto", 31 | "place-items-start", 32 | "place-items-center", 33 | "place-items-end", 34 | "place-items-stretch", 35 | "place-items-baseline", 36 | ]; 37 | 38 | const placeSelf = ["place-self-auto", "place-self-start", "place-self-center", "place-self-end", "place-self-stretch"]; 39 | 40 | const justifyContent = [ 41 | "justify-start", 42 | "justify-center", 43 | "justify-end", 44 | "justify-between", 45 | "justify-around", 46 | "justify-evenly", 47 | ]; 48 | 49 | const justifyItems = [ 50 | "justify-items-auto", 51 | "justify-items-start", 52 | "justify-items-center", 53 | "justify-items-end", 54 | "justify-items-stretch", 55 | ]; 56 | 57 | const justifySelf = [ 58 | "justify-self-auto", 59 | "justify-self-start", 60 | "justify-self-center", 61 | "justify-self-end", 62 | "justify-self-stretch", 63 | ]; 64 | 65 | const flex = ["flex-initial", "flex-1", "flex-auto", "flex-none"]; 66 | 67 | export default { 68 | flexDirection, 69 | flexWrap, 70 | alignItems, 71 | alignContent, 72 | alignSelf, 73 | placeContent, 74 | placeItems, 75 | placeSelf, 76 | justifyContent, 77 | justifyItems, 78 | justifySelf, 79 | flex, 80 | }; 81 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/node,visualstudiocode,macos 2 | 3 | # Generated stuff 4 | .code 5 | dist 6 | /lib 7 | es 8 | 9 | ### macOS ### 10 | *.DS_Store 11 | .AppleDouble 12 | .LSOverride 13 | 14 | # Icon must end with two \r 15 | Icon 16 | 17 | # Thumbnails 18 | ._* 19 | 20 | # Files that might appear in the root of a volume 21 | .DocumentRevisions-V100 22 | .fseventsd 23 | .Spotlight-V100 24 | .TemporaryItems 25 | .Trashes 26 | .VolumeIcon.icns 27 | .com.apple.timemachine.donotpresent 28 | 29 | # Directories potentially created on remote AFP share 30 | .AppleDB 31 | .AppleDesktop 32 | Network Trash Folder 33 | Temporary Items 34 | .apdisk 35 | 36 | ### Node ### 37 | # Logs 38 | logs 39 | *.log 40 | npm-debug.log* 41 | yarn-debug.log* 42 | yarn-error.log* 43 | 44 | # Runtime data 45 | pids 46 | *.pid 47 | *.seed 48 | *.pid.lock 49 | 50 | # Directory for instrumented libs generated by jscoverage/JSCover 51 | lib-cov 52 | 53 | # Coverage directory used by tools like istanbul 54 | coverage 55 | 56 | # nyc test coverage 57 | .nyc_output 58 | 59 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 60 | .grunt 61 | 62 | # Bower dependency directory (https://bower.io/) 63 | bower_components 64 | 65 | # node-waf configuration 66 | .lock-wscript 67 | 68 | # Compiled binary addons (http://nodejs.org/api/addons.html) 69 | build/Release 70 | 71 | # Dependency directories 72 | node_modules/ 73 | jspm_packages/ 74 | 75 | # Typescript v1 declaration files 76 | typings/ 77 | 78 | # Optional npm cache directory 79 | .npm 80 | 81 | # Optional eslint cache 82 | .eslintcache 83 | 84 | # Optional REPL history 85 | .node_repl_history 86 | 87 | # Output of 'npm pack' 88 | *.tgz 89 | 90 | # Yarn Integrity file 91 | .yarn-integrity 92 | 93 | # dotenv environment variables file 94 | .env 95 | 96 | # IntelliJ based IDEs 97 | .idea 98 | 99 | ### VisualStudioCode ### 100 | .vscode/* 101 | !.vscode/launch.json 102 | !.vscode/tasks.json 103 | 104 | # End of https://www.gitignore.io/api/node,visualstudiocode,macos 105 | 106 | # yarn lock file 107 | yarn.lock 108 | 109 | # project specific 110 | tailwind.config.js 111 | tailwindcss-classnames.ts 112 | -------------------------------------------------------------------------------- /src/cli/lib/non-configurable/layout.ts: -------------------------------------------------------------------------------- 1 | const boxSizing = ["box-border", "box-content"]; 2 | 3 | const display = [ 4 | "block", 5 | "inline-block", 6 | "inline", 7 | "flex", 8 | "inline-flex", 9 | "grid", 10 | "inline-grid", 11 | "table", 12 | "inline-table", 13 | "table-row", 14 | "table-cell", 15 | "contents", 16 | "list-item", 17 | "hidden", 18 | ]; 19 | 20 | const boxDecorationBreak = ["box-decoration-slice", "box-decoration-clone"]; 21 | 22 | const container = ["container"]; 23 | 24 | const float = ["float-right", "float-left", "float-none"]; 25 | 26 | const clear = ["clear-left", "clear-right", "clear-both", "clear-none"]; 27 | 28 | const isolation = ["isolate", "isolation-auto"]; 29 | 30 | const objectFit = ["object-contain", "object-cover", "object-fill", "object-none", "object-scale-down"]; 31 | 32 | const overflow = [ 33 | "overflow-auto", 34 | "overflow-clip", 35 | "overflow-hidden", 36 | "overflow-visible", 37 | "overflow-scroll", 38 | "overflow-x-auto", 39 | "overflow-y-auto", 40 | "overflow-x-clip", 41 | "overflow-y-clip", 42 | "overflow-x-hidden", 43 | "overflow-y-hidden", 44 | "overflow-x-visible", 45 | "overflow-y-visible", 46 | "overflow-x-scroll", 47 | "overflow-y-scroll", 48 | ]; 49 | 50 | const overscrollBehavior = [ 51 | "overscroll-auto", 52 | "overscroll-contain", 53 | "overscroll-none", 54 | "overscroll-y-auto", 55 | "overscroll-y-contain", 56 | "overscroll-y-none", 57 | "overscroll-x-auto", 58 | "overscroll-x-contain", 59 | "overscroll-x-none", 60 | ]; 61 | 62 | const position = ["static", "fixed", "absolute", "relative", "sticky"]; 63 | 64 | const visibility = ["visible", "invisible", "collapse"]; 65 | 66 | const breakBefore = [ 67 | "break-before-auto", 68 | "break-before-avoid", 69 | "break-before-all", 70 | "break-before-avoid-page", 71 | "break-before-page", 72 | "break-before-left", 73 | "break-before-right", 74 | "break-before-column", 75 | ]; 76 | const breakInside = ["break-inside-auto", "break-inside-avoid", "break-inside-avoid-page", "break-inside-avoid-column"]; 77 | const breakAfter = [ 78 | "break-after-auto", 79 | "break-after-avoid", 80 | "break-after-all", 81 | "break-after-avoid-page", 82 | "break-after-page", 83 | "break-after-left", 84 | "break-after-right", 85 | "break-after-column", 86 | ]; 87 | 88 | export default { 89 | display, 90 | boxDecorationBreak, 91 | boxSizing, 92 | container, 93 | float, 94 | clear, 95 | isolation, 96 | objectFit, 97 | overflow, 98 | overscrollBehavior, 99 | position, 100 | visibility, 101 | breakBefore, 102 | breakInside, 103 | breakAfter, 104 | }; 105 | -------------------------------------------------------------------------------- /src/cli/index.ts: -------------------------------------------------------------------------------- 1 | import commander from "commander"; 2 | import inquirer from "inquirer"; 3 | import colors from "@colors/colors"; 4 | import fs from "fs"; 5 | 6 | import { GeneratedFileWriter } from "./core/GeneratedFileWriter"; 7 | 8 | type TInquirerAnswers = { 9 | configFilename: string; 10 | outputFilename: string | void; 11 | customClassesFilename: string | void; 12 | }; 13 | 14 | commander 15 | // Configure CLI options 16 | .option("-i, --input ", "Name or relative path of the TailwindCSS config file") 17 | .option("-o, --output ", "Name or relative path of the generated types file", "tailwindcss-classnames.ts") 18 | .option("-x, --extra ", "Name or relative path of the file with the custom extra types") 19 | 20 | // Define the action of the CLI 21 | .action(({ input, output, extra }: { [key: string]: string | void }) => { 22 | const isConfigFileFound: boolean = fs.existsSync("./tailwind.config.js"); 23 | // If the config file is found or provided explicitly by the user... 24 | if (isConfigFileFound || !!input) { 25 | // Generate the types and write them to a file on disk 26 | return new GeneratedFileWriter({ 27 | configFilename: input ? input : "tailwind.config.js", 28 | outputFilename: output, 29 | customClassesFilename: extra, 30 | }).write(); 31 | } 32 | // Otherwise... 33 | else { 34 | // Prompt the user and ask to enter required information 35 | inquirer 36 | .prompt([ 37 | { 38 | name: "configFilename", 39 | type: "input", 40 | default: "tailwind.config.js", 41 | message: "Tailwind configuration filename", 42 | }, 43 | { 44 | name: "outputFilename", 45 | type: "input", 46 | default: "tailwindcss-classnames.ts", 47 | message: "Name of the file with generated types", 48 | }, 49 | { 50 | name: "customClassesFilename", 51 | type: "input", 52 | default: null, 53 | message: "Name or path of the file with the custom types", 54 | }, 55 | ]) 56 | .then((answers: TInquirerAnswers) => { 57 | // Get the answers and use them to create the file with generated types 58 | return new GeneratedFileWriter({ 59 | configFilename: answers.configFilename, 60 | outputFilename: answers.outputFilename, 61 | customClassesFilename: answers.customClassesFilename, 62 | }).write(); 63 | }) 64 | // Catch any errors that occur when prompting the user... 65 | .catch(error => { 66 | if (error.isTtyError) { 67 | console.error(colors.red("Prompt couldn't be rendered in the current environment")); 68 | } else { 69 | console.error(colors.red("Something went wrong with the prompt")); 70 | } 71 | }); 72 | } 73 | }); 74 | 75 | commander.parse(process.argv); 76 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing guidelines 2 | 3 | To submit patches or features: 4 | 5 | 1. Fork the repo 6 | 2. Run `yarn install` or `npm install` 7 | 3. Make changes 8 | 4. Build and run the CLI by `yarn run-cli` or `npm run run-cli` 9 | 5. Submit your changes via GitHub Pull Requests. 10 | 11 | ## Git commits style 12 | 13 | Commit messages follows the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) style. 14 | 15 | ## Code style 16 | 17 | The code style is enforced by prettier and eslint rules and there is a pre-commit hooks setup that automatically fixes any fixable violations. 18 | 19 | Check style violations by running: 20 | 21 | ```bash 22 | yarn run lint && yarn run check-formatting 23 | ``` 24 | 25 | Fix formatting issues by running: 26 | 27 | ```bash 28 | yarn run fix-formatting 29 | ``` 30 | 31 | ## Adding new features from TailwindCSS 32 | 33 | First thing is to look at their [release notes](https://github.com/tailwindlabs/tailwindcss/releases), then update tailwindcss and the default config file by running: 34 | 35 | ```bash 36 | yarn add -D tailwindcss@^RELEASE_VERSION 37 | yarn run updateConfig 38 | ``` 39 | 40 | This will update [`src/cli/lib/defaultTailwindConfig.ts`](https://github.com/muhammadsammy/tailwindcss-classnames/blob/develop/src/cli/lib/defaultTailwindConfig.ts) with the latest tailwind config and 41 | the CLI will use this file to automatically generate the following classes: 42 | 43 | - new [pseudoclass variants](https://github.com/muhammadsammy/tailwindcss-classnames/blob/61913c02330efdb746ba6da9a2464ca64ed6471c/src/cli/core/ClassesGenerator.ts#L317) e.g. `hover:flex`, `focus:flex`, `md:flex` etc. 44 | - new classnames that are based on new _values_ in config. e.g. in tailwind v2 they added font sizing like `text-7xl`. the new config will have this value and thus will be [generated by the CLI](https://github.com/muhammadsammy/tailwindcss-classnames/blob/61913c02330efdb746ba6da9a2464ca64ed6471c/src/cli/core/ClassesGenerator.ts#L305). 45 | 46 | The above will update _existing_ classes that got new _values_. 47 | For new _classnames_: 48 | 49 | - classes that their name cannot be customized should be added to [`src/cli/lib/non-configurable/CORRESPONDING_CATEGORY.ts`](https://github.com/muhammadsammy/tailwindcss-classnames/tree/develop/src/cli/lib/non-configurable). 50 | An example for these would be `flex`, `block` (non-configurable/layout) or `capitalize` (non-configurable/typography). 51 | 52 | - classes that their name can be customized (like `bg-red-100`, sizing classes `w-6`, etc.) each should be added to corresponding category method in [`ClassnamesGenerator`](https://github.com/muhammadsammy/tailwindcss-classnames/blob/master/src/cli/core/ClassnamesGenerator.ts) class. 53 | 54 | After doing this for new classes, the CLI would be compatible with new tailwind release. 55 | 56 | Now `src/index.ts` can be updated with the new types by running: 57 | 58 | ```bash 59 | yarn run generate 60 | ``` 61 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "eslint/config"; 2 | import _import from "eslint-plugin-import"; 3 | import { fixupPluginRules } from "@eslint/compat"; 4 | import tsParser from "@typescript-eslint/parser"; 5 | import path from "node:path"; 6 | import { fileURLToPath } from "node:url"; 7 | import js from "@eslint/js"; 8 | import { FlatCompat } from "@eslint/eslintrc"; 9 | 10 | const __filename = fileURLToPath(import.meta.url); 11 | const __dirname = path.dirname(__filename); 12 | const compat = new FlatCompat({ 13 | baseDirectory: __dirname, 14 | recommendedConfig: js.configs.recommended, 15 | allConfig: js.configs.all, 16 | }); 17 | 18 | const rootConfig = { 19 | extends: compat.extends( 20 | "plugin:@typescript-eslint/recommended", 21 | "plugin:@typescript-eslint/eslint-recommended", 22 | "plugin:@typescript-eslint/recommended-requiring-type-checking", 23 | "prettier/@typescript-eslint", 24 | "prettier", 25 | ), 26 | files: ["src/**/*.{js,ts}"], 27 | ignores: [ 28 | "**/jest.config.js", 29 | "**/.eslintrc.js", 30 | "**/rollup.config.js", 31 | "**/tailwind.config.js", 32 | "**/tailwindcss-classnames.ts", 33 | "**/*.js", 34 | ], 35 | plugins: { 36 | import: fixupPluginRules(_import), 37 | }, 38 | languageOptions: { 39 | parser: tsParser, 40 | ecmaVersion: 2019, 41 | sourceType: "module", 42 | 43 | parserOptions: { 44 | project: "./tsconfig.json", 45 | }, 46 | }, 47 | rules: { 48 | "no-use-before-define": "off", 49 | "@typescript-eslint/no-unsafe-call": 0, 50 | "@typescript-eslint/no-unsafe-member-access": 0, 51 | "@typescript-eslint/explicit-member-accessibility": [ 52 | "warn", 53 | { 54 | overrides: { 55 | constructors: "no-public", 56 | }, 57 | }, 58 | ], 59 | "@typescript-eslint/explicit-function-return-type": [ 60 | "warn", 61 | { 62 | allowExpressions: true, 63 | }, 64 | ], 65 | "@typescript-eslint/no-unused-vars": [ 66 | "warn", 67 | { 68 | argsIgnorePattern: "^_", 69 | varsIgnorePattern: "^_", 70 | caughtErrorsIgnorePattern: "^_", 71 | }, 72 | ], 73 | 74 | "@typescript-eslint/no-explicit-any": 1, 75 | "@typescript-eslint/no-use-before-define": [ 76 | 2, 77 | { 78 | functions: false, 79 | classes: false, 80 | }, 81 | ], 82 | "@typescript-eslint/no-inferrable-types": [ 83 | "warn", 84 | { 85 | ignoreParameters: true, 86 | }, 87 | ], 88 | "lines-between-class-members": [ 89 | "error", 90 | "always", 91 | { 92 | exceptAfterSingleLine: true, 93 | }, 94 | ], 95 | "import/prefer-default-export": "off", 96 | "import/no-default-export": "error", 97 | }, 98 | }; 99 | 100 | const nonConfigurableClassnamesFolderConfig = { 101 | files: ["src/cli/lib/non-configurable/**/*.ts"], 102 | rules: { 103 | "import/no-default-export": "off", 104 | }, 105 | }; 106 | 107 | export default defineConfig([rootConfig, nonConfigurableClassnamesFolderConfig]); 108 | -------------------------------------------------------------------------------- /src/cli/core/constants/regularClassGroupKeys.ts: -------------------------------------------------------------------------------- 1 | export const regularClassGroupKeys = [ 2 | // 'accessibility', 3 | "screenReaders", 4 | "alignContent", 5 | "alignItems", 6 | "alignSelf", 7 | "animation", 8 | "appearance", 9 | "backdropBlur", 10 | "backdropBrightness", 11 | "backdropContrast", 12 | "backdropDropShadow", 13 | "backdropFilter", 14 | "backdropGrayscale", 15 | "backdropHueRotate", 16 | "backdropInvert", 17 | "backdropSaturate", 18 | "backdropSepia", 19 | "backgroundAttachment", 20 | "backgroundBlendMode", 21 | "backgroundClip", 22 | "backgroundColor", 23 | "backgroundImage", 24 | "backgroundOpacity", 25 | "backgroundPosition", 26 | "backgroundRepeat", 27 | "backgroundSize", 28 | "backgroundOrigin", 29 | "blur", 30 | "borderCollapse", 31 | "borderColor", 32 | "borderOpacity", 33 | "borderRadius", 34 | "borderStyle", 35 | "borderWidth", 36 | "boxDecorationBreak", 37 | "boxShadow", 38 | "boxSizing", 39 | "brightness", 40 | "clear", 41 | "container", 42 | "contrast", 43 | "cursor", 44 | "display", 45 | "divideColor", 46 | "divideOpacity", 47 | "divideStyle", 48 | "divideWidth", 49 | "dropShadow", 50 | "fill", 51 | "filter", 52 | "flex", 53 | "flexDirection", 54 | "flexGrow", 55 | "flexShrink", 56 | "flexWrap", 57 | "float", 58 | "fontFamily", 59 | "fontSize", 60 | "fontSmoothing", 61 | "fontStyle", 62 | "fontVariantNumeric", 63 | "fontWeight", 64 | "gap", 65 | "gradientColorStops", 66 | "grayscale", 67 | "gridAutoColumns", 68 | "gridAutoFlow", 69 | "gridAutoRows", 70 | "gridColumn", 71 | "gridColumnEnd", 72 | "gridColumnStart", 73 | "gridRow", 74 | "gridRowEnd", 75 | "gridRowStart", 76 | "gridTemplateColumns", 77 | "gridTemplateRows", 78 | "height", 79 | "hueRotate", 80 | "inset", 81 | "invert", 82 | "isolation", 83 | "justifyContent", 84 | "justifyItems", 85 | "justifySelf", 86 | "letterSpacing", 87 | "lineHeight", 88 | "listStylePosition", 89 | "listStyleType", 90 | "margin", 91 | "maxHeight", 92 | "maxWidth", 93 | "minHeight", 94 | "minWidth", 95 | "mixBlendMode", 96 | "objectFit", 97 | "objectPosition", 98 | "opacity", 99 | "order", 100 | "outline", 101 | "overflow", 102 | "overscrollBehavior", 103 | "padding", 104 | "placeContent", 105 | "placeItems", 106 | "placeSelf", 107 | "placeholderColor", 108 | "placeholderOpacity", 109 | "pointerEvents", 110 | "position", 111 | "resize", 112 | "ringColor", 113 | "ringOffsetColor", 114 | "ringOffsetWidth", 115 | "ringOpacity", 116 | "ringWidth", 117 | "rotate", 118 | "saturate", 119 | "scale", 120 | "sepia", 121 | "skew", 122 | "space", 123 | "stroke", 124 | "strokeWidth", 125 | "tableLayout", 126 | "textAlign", 127 | "textColor", 128 | "textDecoration", 129 | "textOpacity", 130 | "textOverflow", 131 | "textTransform", 132 | "transform", 133 | "transformOrigin", 134 | "transitionDelay", 135 | "transitionDuration", 136 | "transitionProperty", 137 | "transitionTimingFunction", 138 | "translate", 139 | "userSelect", 140 | "verticalAlign", 141 | "visibility", 142 | "whitespace", 143 | "width", 144 | "wordBreak", 145 | "zIndex", 146 | ]; 147 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tailwindcss-classnames", 3 | "version": "3.2.0", 4 | "description": "Functional typed classnames for TailwindCSS", 5 | "author": "Christian Alfoni ", 6 | "contributors": [ 7 | "Muhammad Sammy ", 8 | "Christian Alfoni " 9 | ], 10 | "license": "MIT", 11 | "repository": "git+https://github.com/muhammadsammy/tailwindcss-classnames.git", 12 | "main": "lib/index.js", 13 | "bin": { 14 | "tailwindcss-classnames": "lib/cli/index.js" 15 | }, 16 | "module": "es/index.js", 17 | "browser": "dist/bundle.js", 18 | "types": "dist/bundle.d.ts", 19 | "scripts": { 20 | "build": "npm run build:lib & npm run build:umd", 21 | "build:lib": "tsc --outDir lib --module commonjs", 22 | "build:es": "tsc --outDir es --module es2015", 23 | "build:umd": "npm run build:es && rollup --config && dts-bundle --name dist/bundle --main es --outputAsModuleFolder", 24 | "clean": "rimraf dist es lib coverage tailwindcss-classnames.ts tailwind.config.js", 25 | "typecheck": "tsc --noEmit", 26 | "lint": "eslint \"src/**/*.{js,ts}\" && npm run typecheck", 27 | "check-formatting": "prettier \"**/*.{md,js,jsx,json,ts,tsx}\" --check", 28 | "fix-formatting": "prettier \"**/*.{md,js,jsx,json,ts,tsx}\" --write", 29 | "test": "jest --env=jsdom --coverage --passWithNoTests", 30 | "test:watch": "jest --env=jsdom --watch --updateSnapshot", 31 | "prepublishOnly": "npm run build", 32 | "run-cli": "npm run build:lib && node lib/cli/index.js", 33 | "prebuild": "npm run clean", 34 | "postbuild": "rimraf {lib,es}/**/__tests__ {lib,es}/**/*.{spec,test}.{js,d.ts,js.map}", 35 | "posttest": "npm run typecheck && npm run lint", 36 | "preversion": "npm test", 37 | "postversion": "git push && git push --tags", 38 | "release": "standard-version", 39 | "releaseAs": "standard-version --release-as", 40 | "pregenerate": "npm run clean && npm run build:lib", 41 | "generate": "tailwindcss init --full && node lib/cli/index.js -i tailwind.config.js -o src/index.ts", 42 | "postgenerate": "npm run clean && prettier src/index.ts --write", 43 | "preupdateConfig": "npm run clean", 44 | "updateConfig": "tailwindcss init --full && node scripts/updateDefaultConfig.js", 45 | "postupdateConfig": "npm run clean && prettier src/cli/lib/defaultTailwindConfig.ts --write", 46 | "prepare": "husky" 47 | }, 48 | "keywords": [ 49 | "typescript", 50 | "tailwindcss", 51 | "tailwind", 52 | "classnames" 53 | ], 54 | "files": [ 55 | "lib", 56 | "es", 57 | "dist" 58 | ], 59 | "dependencies": { 60 | "@colors/colors": "^1.6.0", 61 | "clsx": "^1.2.1", 62 | "commander": "^7.2.0", 63 | "inquirer": "^8.2.6", 64 | "lodash": "^4.17.21", 65 | "tslib": "^2.8.1" 66 | }, 67 | "devDependencies": { 68 | "@commitlint/cli": "^19.8.0", 69 | "@commitlint/config-conventional": "^11.0.0", 70 | "@eslint/compat": "^1.2.8", 71 | "@eslint/eslintrc": "^3.3.1", 72 | "@eslint/js": "^9.25.1", 73 | "@types/inquirer": "^7.3.3", 74 | "@types/jest": "^26.0.24", 75 | "@types/lodash": "^4.17.16", 76 | "@types/node": "^14.18.63", 77 | "@typescript-eslint/eslint-plugin": "^8.31.0", 78 | "@typescript-eslint/parser": "^8.31.0", 79 | "autoprefixer": "^10.4.21", 80 | "dts-bundle": "^0.1.1", 81 | "eslint": "^9.25.1", 82 | "eslint-config-prettier": "^7.2.0", 83 | "eslint-plugin-import": "^2.31.0", 84 | "husky": "^9.1.7", 85 | "jest": "^29.7.0", 86 | "lint-staged": "^10.5.4", 87 | "pascal-case": "^3.1.2", 88 | "postcss": "^8.5.3", 89 | "prettier": "^2.8.8", 90 | "rimraf": "^3.0.2", 91 | "rollup": "^2.79.2", 92 | "rollup-plugin-commonjs": "^10.1.0", 93 | "rollup-plugin-node-builtins": "^2.1.2", 94 | "rollup-plugin-node-globals": "^1.4.0", 95 | "rollup-plugin-node-resolve": "^5.2.0", 96 | "rollup-plugin-sourcemaps": "^0.6.3", 97 | "rollup-plugin-terser": "^7.0.2", 98 | "semver": "^7.7.1", 99 | "standard-version": "^9.5.0", 100 | "tailwindcss": "3.2.0", 101 | "ts-jest": "^29.3.2", 102 | "typescript": "^5.8.3" 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/cli/core/constants/tailwindColors.ts: -------------------------------------------------------------------------------- 1 | export const tailwindColors = { 2 | inherit: "inherit", 3 | current: "currentColor", 4 | transparent: "transparent", 5 | black: "#000", 6 | white: "#fff", 7 | slate: { 8 | 50: "#f8fafc", 9 | 100: "#f1f5f9", 10 | 200: "#e2e8f0", 11 | 300: "#cbd5e1", 12 | 400: "#94a3b8", 13 | 500: "#64748b", 14 | 600: "#475569", 15 | 700: "#334155", 16 | 800: "#1e293b", 17 | 900: "#0f172a", 18 | }, 19 | gray: { 20 | 50: "#f9fafb", 21 | 100: "#f3f4f6", 22 | 200: "#e5e7eb", 23 | 300: "#d1d5db", 24 | 400: "#9ca3af", 25 | 500: "#6b7280", 26 | 600: "#4b5563", 27 | 700: "#374151", 28 | 800: "#1f2937", 29 | 900: "#111827", 30 | }, 31 | zinc: { 32 | 50: "#fafafa", 33 | 100: "#f4f4f5", 34 | 200: "#e4e4e7", 35 | 300: "#d4d4d8", 36 | 400: "#a1a1aa", 37 | 500: "#71717a", 38 | 600: "#52525b", 39 | 700: "#3f3f46", 40 | 800: "#27272a", 41 | 900: "#18181b", 42 | }, 43 | neutral: { 44 | 50: "#fafafa", 45 | 100: "#f5f5f5", 46 | 200: "#e5e5e5", 47 | 300: "#d4d4d4", 48 | 400: "#a3a3a3", 49 | 500: "#737373", 50 | 600: "#525252", 51 | 700: "#404040", 52 | 800: "#262626", 53 | 900: "#171717", 54 | }, 55 | stone: { 56 | 50: "#fafaf9", 57 | 100: "#f5f5f4", 58 | 200: "#e7e5e4", 59 | 300: "#d6d3d1", 60 | 400: "#a8a29e", 61 | 500: "#78716c", 62 | 600: "#57534e", 63 | 700: "#44403c", 64 | 800: "#292524", 65 | 900: "#1c1917", 66 | }, 67 | red: { 68 | 50: "#fef2f2", 69 | 100: "#fee2e2", 70 | 200: "#fecaca", 71 | 300: "#fca5a5", 72 | 400: "#f87171", 73 | 500: "#ef4444", 74 | 600: "#dc2626", 75 | 700: "#b91c1c", 76 | 800: "#991b1b", 77 | 900: "#7f1d1d", 78 | }, 79 | orange: { 80 | 50: "#fff7ed", 81 | 100: "#ffedd5", 82 | 200: "#fed7aa", 83 | 300: "#fdba74", 84 | 400: "#fb923c", 85 | 500: "#f97316", 86 | 600: "#ea580c", 87 | 700: "#c2410c", 88 | 800: "#9a3412", 89 | 900: "#7c2d12", 90 | }, 91 | amber: { 92 | 50: "#fffbeb", 93 | 100: "#fef3c7", 94 | 200: "#fde68a", 95 | 300: "#fcd34d", 96 | 400: "#fbbf24", 97 | 500: "#f59e0b", 98 | 600: "#d97706", 99 | 700: "#b45309", 100 | 800: "#92400e", 101 | 900: "#78350f", 102 | }, 103 | yellow: { 104 | 50: "#fefce8", 105 | 100: "#fef9c3", 106 | 200: "#fef08a", 107 | 300: "#fde047", 108 | 400: "#facc15", 109 | 500: "#eab308", 110 | 600: "#ca8a04", 111 | 700: "#a16207", 112 | 800: "#854d0e", 113 | 900: "#713f12", 114 | }, 115 | lime: { 116 | 50: "#f7fee7", 117 | 100: "#ecfccb", 118 | 200: "#d9f99d", 119 | 300: "#bef264", 120 | 400: "#a3e635", 121 | 500: "#84cc16", 122 | 600: "#65a30d", 123 | 700: "#4d7c0f", 124 | 800: "#3f6212", 125 | 900: "#365314", 126 | }, 127 | green: { 128 | 50: "#f0fdf4", 129 | 100: "#dcfce7", 130 | 200: "#bbf7d0", 131 | 300: "#86efac", 132 | 400: "#4ade80", 133 | 500: "#22c55e", 134 | 600: "#16a34a", 135 | 700: "#15803d", 136 | 800: "#166534", 137 | 900: "#14532d", 138 | }, 139 | emerald: { 140 | 50: "#ecfdf5", 141 | 100: "#d1fae5", 142 | 200: "#a7f3d0", 143 | 300: "#6ee7b7", 144 | 400: "#34d399", 145 | 500: "#10b981", 146 | 600: "#059669", 147 | 700: "#047857", 148 | 800: "#065f46", 149 | 900: "#064e3b", 150 | }, 151 | teal: { 152 | 50: "#f0fdfa", 153 | 100: "#ccfbf1", 154 | 200: "#99f6e4", 155 | 300: "#5eead4", 156 | 400: "#2dd4bf", 157 | 500: "#14b8a6", 158 | 600: "#0d9488", 159 | 700: "#0f766e", 160 | 800: "#115e59", 161 | 900: "#134e4a", 162 | }, 163 | cyan: { 164 | 50: "#ecfeff", 165 | 100: "#cffafe", 166 | 200: "#a5f3fc", 167 | 300: "#67e8f9", 168 | 400: "#22d3ee", 169 | 500: "#06b6d4", 170 | 600: "#0891b2", 171 | 700: "#0e7490", 172 | 800: "#155e75", 173 | 900: "#164e63", 174 | }, 175 | sky: { 176 | 50: "#f0f9ff", 177 | 100: "#e0f2fe", 178 | 200: "#bae6fd", 179 | 300: "#7dd3fc", 180 | 400: "#38bdf8", 181 | 500: "#0ea5e9", 182 | 600: "#0284c7", 183 | 700: "#0369a1", 184 | 800: "#075985", 185 | 900: "#0c4a6e", 186 | }, 187 | blue: { 188 | 50: "#eff6ff", 189 | 100: "#dbeafe", 190 | 200: "#bfdbfe", 191 | 300: "#93c5fd", 192 | 400: "#60a5fa", 193 | 500: "#3b82f6", 194 | 600: "#2563eb", 195 | 700: "#1d4ed8", 196 | 800: "#1e40af", 197 | 900: "#1e3a8a", 198 | }, 199 | indigo: { 200 | 50: "#eef2ff", 201 | 100: "#e0e7ff", 202 | 200: "#c7d2fe", 203 | 300: "#a5b4fc", 204 | 400: "#818cf8", 205 | 500: "#6366f1", 206 | 600: "#4f46e5", 207 | 700: "#4338ca", 208 | 800: "#3730a3", 209 | 900: "#312e81", 210 | }, 211 | violet: { 212 | 50: "#f5f3ff", 213 | 100: "#ede9fe", 214 | 200: "#ddd6fe", 215 | 300: "#c4b5fd", 216 | 400: "#a78bfa", 217 | 500: "#8b5cf6", 218 | 600: "#7c3aed", 219 | 700: "#6d28d9", 220 | 800: "#5b21b6", 221 | 900: "#4c1d95", 222 | }, 223 | purple: { 224 | 50: "#faf5ff", 225 | 100: "#f3e8ff", 226 | 200: "#e9d5ff", 227 | 300: "#d8b4fe", 228 | 400: "#c084fc", 229 | 500: "#a855f7", 230 | 600: "#9333ea", 231 | 700: "#7e22ce", 232 | 800: "#6b21a8", 233 | 900: "#581c87", 234 | }, 235 | fuchsia: { 236 | 50: "#fdf4ff", 237 | 100: "#fae8ff", 238 | 200: "#f5d0fe", 239 | 300: "#f0abfc", 240 | 400: "#e879f9", 241 | 500: "#d946ef", 242 | 600: "#c026d3", 243 | 700: "#a21caf", 244 | 800: "#86198f", 245 | 900: "#701a75", 246 | }, 247 | pink: { 248 | 50: "#fdf2f8", 249 | 100: "#fce7f3", 250 | 200: "#fbcfe8", 251 | 300: "#f9a8d4", 252 | 400: "#f472b6", 253 | 500: "#ec4899", 254 | 600: "#db2777", 255 | 700: "#be185d", 256 | 800: "#9d174d", 257 | 900: "#831843", 258 | }, 259 | rose: { 260 | 50: "#fff1f2", 261 | 100: "#ffe4e6", 262 | 200: "#fecdd3", 263 | 300: "#fda4af", 264 | 400: "#fb7185", 265 | 500: "#f43f5e", 266 | 600: "#e11d48", 267 | 700: "#be123c", 268 | 800: "#9f1239", 269 | 900: "#881337", 270 | }, 271 | }; 272 | -------------------------------------------------------------------------------- /src/cli/types/classes.ts: -------------------------------------------------------------------------------- 1 | import { tailwindLabsPlugins } from "../lib/tailwindlabs-plugins"; 2 | 3 | export type Accessibility = Record; 4 | export type Backgrounds = Record; 5 | export type Borders = Record; 6 | export type Effects = Record; 7 | export type Filters = Record; 8 | export type FlexBox = Record; 9 | export type Grid = Record; 10 | export type Grouping = Record; 11 | export type Interactivity = Record; 12 | export type Layout = Record; 13 | export type Sizing = Record; 14 | export type Spacing = Record; 15 | export type SVG = Record; 16 | export type Tables = Record; 17 | export type Transforms = Record; 18 | export type TransitionsAndAnimations = Record; 19 | export type Typography = Record; 20 | 21 | export type TAllClassnames = { 22 | Accessibility: Accessibility; 23 | Backgrounds: Backgrounds; 24 | Borders: Borders; 25 | Effects: Effects; 26 | Filters: Filters; 27 | FlexBox: FlexBox; 28 | Grid: Grid; 29 | Grouping: Grouping; 30 | Interactivity: Interactivity; 31 | Layout: Layout; 32 | Sizing: Sizing; 33 | Spacing: Spacing; 34 | SVG: SVG; 35 | Tables: Tables; 36 | Transforms: Transforms; 37 | TransitionsAndAnimations: TransitionsAndAnimations; 38 | Typography: Typography; 39 | 40 | TailwindLabsPlugins?: Partial; 41 | }; 42 | 43 | type TAccessibilityCategoryItem = "screenReaders"; 44 | 45 | type TBackgroundsCategoryItem = 46 | | "backgroundAttachment" 47 | | "backgroundClip" 48 | | "backgroundColor" 49 | | "backgroundOpacity" 50 | | "backgroundPosition" 51 | | "backgroundRepeat" 52 | | "backgroundSize" 53 | | "backgroundImage" 54 | | "gradientColorStops"; 55 | 56 | type TBordersCategoryItem = 57 | | "borderColor" 58 | | "borderOpacity" 59 | | "borderStyle" 60 | | "borderWidth" 61 | | "borderRadius" 62 | | "divideWidth" 63 | | "divideOpacity" 64 | | "divideColor" 65 | | "divideStyle" 66 | | "ringColor" 67 | | "ringOpacity" 68 | | "ringOffsetColor" 69 | | "ringOffsetWidth" 70 | | "ringWidth" 71 | | "outlineWidth" 72 | | "outlineOffset" 73 | | "outlineColor"; 74 | 75 | type TEffectsCategoryItem = "boxShadow" | "boxShadowColor" | "opacity" | "mixBlendMode" | "backgroundBlendMode"; 76 | 77 | type TFiltersCategoryItem = 78 | | "filter" 79 | | "backdropFilter" 80 | | "blur" 81 | | "brightness" 82 | | "contrast" 83 | | "dropShadow" 84 | | "grayscale" 85 | | "hueRotate" 86 | | "invert" 87 | | "saturate" 88 | | "sepia" 89 | | "backdropBlur" 90 | | "backdropBrightness" 91 | | "backdropContrast" 92 | | "backdropGrayscale" 93 | | "backdropHueRotate" 94 | | "backdropInvert" 95 | | "backdropOpacity" 96 | | "backdropSaturate" 97 | | "backdropSepia"; 98 | 99 | type TFlexBoxCategoryItem = 100 | | "flexBasis" 101 | | "flexDirection" 102 | | "flexWrap" 103 | | "alignItems" 104 | | "alignContent" 105 | | "alignSelf" 106 | | "placeContent" 107 | | "placeItems" 108 | | "placeSelf" 109 | | "justifyContent" 110 | | "justifyItems" 111 | | "justifySelf" 112 | | "flex" 113 | | "flexGrow" 114 | | "flexShrink" 115 | | "order"; 116 | 117 | type TGridCategoryItem = 118 | | "gridTemplateColumns" 119 | | "gridAutoColumns" 120 | | "gridColumn" 121 | | "gridColumnStart" 122 | | "gridColumnEnd" 123 | | "gridTemplateRows" 124 | | "gridAutoRows" 125 | | "gridRow" 126 | | "gridRowStart" 127 | | "gridRowEnd" 128 | | "gap" 129 | | "gridAutoFlow"; 130 | 131 | type TGroupingCategoryItem = "group" | "peer"; 132 | 133 | type TInteractivityCategoryItem = 134 | | "appearance" 135 | | "cursor" 136 | | "pointerEvents" 137 | | "resize" 138 | | "userSelect" 139 | | "caretColor" 140 | | "willChange" 141 | | "accentColor" 142 | | "scrollSnap" 143 | | "scrollMargin" 144 | | "scrollPadding" 145 | | "scrollBehavior" 146 | | "touchAction"; 147 | 148 | type TLayoutCategoryItem = 149 | | "display" 150 | | "boxDecorationBreak" 151 | | "boxSizing" 152 | | "container" 153 | | "float" 154 | | "clear" 155 | | "isolation" 156 | | "objectFit" 157 | | "objectPosition" 158 | | "overflow" 159 | | "overscrollBehavior" 160 | | "position" 161 | | "inset" 162 | | "visibility" 163 | | "zIndex" 164 | | "aspectRatio" 165 | | "columns" 166 | | "breakBefore" 167 | | "breakInside" 168 | | "breakAfter"; 169 | 170 | type TSizingCategoryItem = "width" | "minWidth" | "maxWidth" | "height" | "minHeight" | "maxHeight"; 171 | 172 | type TSpacingCategoryItem = "padding" | "margin" | "space"; 173 | 174 | type TSVGCategoryItem = "fill" | "stroke" | "strokeWidth"; 175 | 176 | type TTablesCategoryItem = "borderCollapse" | "tableLayout" | "borderSpacing"; 177 | 178 | type TTransformsCategoryItem = "scale" | "rotate" | "translate" | "skew" | "transformOrigin"; 179 | 180 | type TTransitionsAndAnimationsCategoryItem = 181 | | "transitionProperty" 182 | | "transitionDuration" 183 | | "transitionTimingFunction" 184 | | "transitionDelay" 185 | | "animation"; 186 | 187 | type TTypographyCategoryItem = 188 | | "fontFamily" 189 | | "fontSize" 190 | | "fontSmoothing" 191 | | "fontStyle" 192 | | "fontWeight" 193 | | "fontVariantNumeric" 194 | | "letterSpacing" 195 | | "lineHeight" 196 | | "listStyleType" 197 | | "listStylePosition" 198 | | "placeholderColor" 199 | | "placeholderOpacity" 200 | | "textAlign" 201 | | "textColor" 202 | | "textDecoration" 203 | | "textOpacity" 204 | | "textTransform" 205 | | "verticalAlign" 206 | | "whitespace" 207 | | "wordBreak" 208 | | "content" 209 | | "textIndent" 210 | | "textDecorationColor" 211 | | "textDecorationStyle" 212 | | "textDecorationThickness" 213 | | "textUnderlineOffset"; 214 | -------------------------------------------------------------------------------- /src/cli/core/GeneratedFileWriter.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/restrict-template-expressions */ 2 | 3 | import { promises as fs } from "fs"; 4 | import vm from "vm"; 5 | import path from "path"; 6 | import colors from "@colors/colors"; 7 | import { ClassnamesGenerator } from "./ClassnamesGenerator"; 8 | import { TailwindConfigParser } from "./TailwindConfigParser"; 9 | import { FileContentGenerator } from "./FileContentGenerator"; 10 | import { TTailwindCSSConfig } from "../types/config"; 11 | 12 | type TCliOptions = { 13 | configFilename: string | void; 14 | outputFilename: string | void; 15 | customClassesFilename: string | void; 16 | }; 17 | 18 | /** 19 | * Responsible for writing a file with the generated content to the disk. 20 | */ 21 | export class GeneratedFileWriter { 22 | private readonly _configFilename: string | void; 23 | private readonly _outputFilename: string | void; 24 | private readonly _customClassesFilename: string | void; 25 | /** The data returned from reading the config file */ 26 | private _configFileData = ""; 27 | 28 | /** 29 | * Initializes a new instance of `GeneratedFileWriter` class. 30 | * @param options The parsed CLI options from user input. 31 | */ 32 | constructor(options: TCliOptions) { 33 | this._configFilename = options.configFilename; 34 | this._outputFilename = options.outputFilename; 35 | this._customClassesFilename = options.customClassesFilename; 36 | } 37 | 38 | /** 39 | * Writes the generated file to disk. 40 | */ 41 | public write = async (): Promise => { 42 | // Check whether the CLI inputs are valid or not 43 | try { 44 | await this.validateCliOptions(); 45 | } catch (_error) { 46 | return; 47 | } 48 | 49 | // If the inputs were valid, generate the file content 50 | const contentGenerationResult = await this.generateFileContent(); 51 | 52 | // Then write the generation result to a file with the provided value from the CLI interface. 53 | fs.writeFile(`${this._outputFilename}`, contentGenerationResult, "utf8") 54 | .then(() => { 55 | this.printCliMessage( 56 | "success", 57 | `Types has successfully been generated in ${this._outputFilename} file.`, 58 | ); 59 | }) 60 | .catch((error: string) => { 61 | this.printCliMessage("error", error); 62 | }); 63 | }; 64 | 65 | private evaluateTailwindConfigFile = async (): Promise => { 66 | // Read the config file from the provided config path 67 | try { 68 | this._configFileData = await fs.readFile(`./${this._configFilename}`, { 69 | encoding: "utf-8", 70 | }); 71 | } catch (_err) { 72 | this.printCliMessage("error", `Error Reading: "./${this._configFilename}"`); 73 | } 74 | 75 | // Execute the config file content as JavaScript code 76 | return vm.runInNewContext(this._configFileData, { 77 | __dirname: path.dirname(path.resolve(`./${this._configFilename}`)), 78 | require, 79 | module: {}, 80 | process, 81 | }); 82 | }; 83 | 84 | private generateFileContent = async (): Promise => { 85 | // Evaluate the config as a JS object 86 | const evaluatedConfig = await this.evaluateTailwindConfigFile(); 87 | 88 | // Parse the config with the config parser class 89 | const configParser = new TailwindConfigParser(evaluatedConfig, { 90 | pluginTypography: this._configFileData.includes("@tailwindcss/typography"), 91 | pluginCustomForms: this._configFileData.includes("@tailwindcss/custom-forms"), 92 | }); 93 | 94 | // Generate all classnames from the config 95 | const generatedClassnames = new ClassnamesGenerator(configParser).generate(); 96 | 97 | // Create the file content from the generated classnames 98 | const fileContentTemplate = new FileContentGenerator(generatedClassnames, configParser).generateFileContent(); 99 | 100 | // Resolve the custom classes import path relative to the output file 101 | let customClassesImportPath: string | null = null; 102 | if (!!this._outputFilename && !!this._customClassesFilename) { 103 | customClassesImportPath = path 104 | .join( 105 | path.relative( 106 | path.join(process.cwd(), path.dirname(this._outputFilename)), 107 | path.join(process.cwd(), path.dirname(this._customClassesFilename)), 108 | ), 109 | path.basename(this._customClassesFilename), 110 | ) 111 | // Convert any Windows path separators to posix 112 | .replace(/\\/g, "/") 113 | .replace(/(\.d)?\.ts$/, ""); 114 | customClassesImportPath = 115 | customClassesImportPath[0] === "." ? customClassesImportPath : `./${customClassesImportPath}`; 116 | } 117 | 118 | // Return final file content 119 | return ( 120 | fileContentTemplate 121 | // Append the custom classes types from external file if provided. 122 | .replace( 123 | /T_CUSTOM_CLASSES_IMPORT_STATEMENT/g, 124 | !!customClassesImportPath 125 | ? `import type TCustomClassesFromExternalFile from '${customClassesImportPath}';` 126 | : "", 127 | ) 128 | .replace( 129 | / ?IMPORTED_T_CUSTOM_CLASSES_KEY/g, 130 | !!customClassesImportPath ? " | TCustomClassesFromExternalFile" : "", 131 | ) 132 | .replace( 133 | / ?IMPORTED_T_CUSTOM_CLASSES_ARG/g, 134 | !!customClassesImportPath ? "| TCustomClassesFromExternalFile\n" : "", 135 | ) 136 | ); 137 | }; 138 | 139 | private validateCliOptions = (): Promise => { 140 | // Check for missing cli options 141 | if (!this._configFilename) { 142 | this.printCliMessage("error", "tailwindcss config file name or path is not provided"); 143 | throw new Error(); 144 | } 145 | if (!this._outputFilename) { 146 | this.printCliMessage("error", "Please provide a valid filename to add generated types to it"); 147 | throw new Error(); 148 | } 149 | 150 | // Check for invalid custom classes file content 151 | if (!!this._customClassesFilename) { 152 | return fs 153 | .readFile(`./${this._customClassesFilename}`) 154 | .then(data => { 155 | if (!data.toString().includes("export default")) { 156 | this.printCliMessage("error", "The type having the custom classes must be a default export"); 157 | } 158 | }) 159 | .catch(error => { 160 | this.printCliMessage("error", `Unable to read the file with custom types. ${error}`); 161 | throw new Error(); 162 | }); 163 | } 164 | 165 | return Promise.resolve(); 166 | }; 167 | 168 | private printCliMessage = (type: "error" | "success", message: string): void => { 169 | const formattedMessage = "\n\n" + message + "\n" + "\n\n"; 170 | 171 | switch (type) { 172 | case "success": 173 | console.log(colors.black.bgGreen(formattedMessage)); 174 | break; 175 | case "error": 176 | console.error(colors.white.bgRed(formattedMessage)); 177 | break; 178 | default: 179 | console.log(formattedMessage); 180 | break; 181 | } 182 | }; 183 | } 184 | -------------------------------------------------------------------------------- /src/cli/core/TailwindConfigParser.ts: -------------------------------------------------------------------------------- 1 | import _ from "lodash"; 2 | import { defaultTailwindConfig } from "../lib/defaultTailwindConfig"; 3 | import { TTailwindCSSConfig, TConfigDarkMode, TConfigPlugins } from "../types/config"; 4 | import { TConfigTheme, TThemeItems } from "../types/config"; 5 | import { baseVariants } from "./constants/baseVariants"; 6 | import { tailwindColors } from "./constants/tailwindColors"; 7 | /* eslint-disable @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-return */ 8 | 9 | /** 10 | * Parses the tailwind config object 11 | */ 12 | export class TailwindConfigParser { 13 | private readonly _mode: string | undefined; 14 | private readonly _prefix: string; 15 | private readonly _separator: string; 16 | private readonly _darkMode: TConfigDarkMode; 17 | private readonly _themeConfig: TConfigTheme; 18 | private _evaluatedTheme: TConfigTheme | null; 19 | private readonly _pluginsConfig: TConfigPlugins; 20 | 21 | constructor(tailwindConfig: TTailwindCSSConfig, plugins: TConfigPlugins) { 22 | this._mode = tailwindConfig?.mode; 23 | this._prefix = _.isEmpty(tailwindConfig?.prefix) ? "" : (tailwindConfig.prefix as string); 24 | this._darkMode = _.isEmpty(tailwindConfig?.darkMode) ? false : (tailwindConfig.darkMode as TConfigDarkMode); 25 | this._separator = _.isEmpty(tailwindConfig.separator) ? ":" : (tailwindConfig.separator as string); 26 | this._themeConfig = { 27 | ...defaultTailwindConfig.theme, 28 | ...tailwindConfig.theme, 29 | }; 30 | this._evaluatedTheme = null; 31 | this._pluginsConfig = plugins; 32 | } 33 | 34 | /** 35 | * Gets the config prefix value 36 | */ 37 | public getPrefix = (): string => this._prefix; 38 | 39 | /** 40 | * Gets the config dark mode value 41 | */ 42 | public getDarkMode = (): TConfigDarkMode => this._darkMode; 43 | 44 | /** 45 | * Gets the config separator value 46 | */ 47 | public getSeparator = (): string => this._separator; 48 | 49 | /** 50 | * Gets the config plugins value 51 | */ 52 | public getPlugins = (): TConfigPlugins | null => { 53 | const { pluginTypography, pluginCustomForms } = this._pluginsConfig; 54 | 55 | return pluginTypography || pluginCustomForms ? this._pluginsConfig : null; 56 | }; 57 | 58 | /** 59 | * Gets the config theme object 60 | */ 61 | public getTheme = (): TThemeItems => { 62 | // Check whether config was evaluated before; if yes, return cached result instead of re-calc 63 | if (this._evaluatedTheme) { 64 | return this._evaluatedTheme; 65 | } 66 | 67 | /** Evaluate function closures inside theme config and get the evaluated theme object */ 68 | const evaluateTheme = (valueSourceTheme?: TThemeItems): TThemeItems => { 69 | // Pick the theme config items except theme.extend 70 | const coreTheme = _.omit(this._themeConfig, "extend"); 71 | // Iterate over theme object items and run the evaluator on it 72 | const valueEvaluator = new ThemeClosuresEvaluator(coreTheme); 73 | for (const [key, value] of Object.entries(this._themeConfig)) { 74 | let evaluatorResult = valueEvaluator.evaluate(value, valueSourceTheme); 75 | // Need to make sure that extensions for specific properties are considered 76 | // For example when 'width' is extended, which is originally based on spacing 77 | if (valueSourceTheme && _.isObject(evaluatorResult)) { 78 | const sourceValue = valueSourceTheme[key as keyof TThemeItems]; 79 | evaluatorResult = { 80 | ...(_.isObject(sourceValue) ? sourceValue : {}), 81 | ...evaluatorResult, 82 | }; 83 | } 84 | coreTheme[key as keyof TThemeItems] = evaluatorResult; 85 | } 86 | 87 | // Return the result of evaluation 88 | return coreTheme; 89 | }; 90 | 91 | /** Evaluate function closures inside theme.extend config and get the evaluated theme.extend object */ 92 | const evaluateThemeExtend = (): Partial => { 93 | // Get the theme.extend property value 94 | const themeExtend = this._themeConfig.extend; 95 | 96 | // Only when theme.extend exists... 97 | if (themeExtend) { 98 | // Iterate over every item and evaluate closures in it 99 | const valueEvaluator = new ThemeClosuresEvaluator(themeExtend); 100 | for (const [key, value] of Object.entries(themeExtend)) 101 | themeExtend[key as keyof TThemeItems] = valueEvaluator.evaluate(value); 102 | } 103 | 104 | // Return the result of the evaluation 105 | return themeExtend; 106 | }; 107 | 108 | // Merge theme with extensions 109 | const themeWithMergedExtend = _.merge(evaluateTheme(), evaluateThemeExtend()); 110 | // Evaluate the theme again, however taking the values from the merge result 111 | this._evaluatedTheme = evaluateTheme(themeWithMergedExtend); 112 | delete this._evaluatedTheme?.extend; 113 | 114 | // Return the evaluated theme 115 | return this._evaluatedTheme; 116 | }; 117 | 118 | /** 119 | * Get the pseudoclass variants based on config. 120 | */ 121 | public getVariants = (): string[] => { 122 | const variants = baseVariants; 123 | 124 | // get responsive variants 125 | const [mediaBreakpoints] = this.getThemeProperty("screens"); 126 | if (this.getDarkMode() == "media" || this.getDarkMode() == "class") mediaBreakpoints.push("dark"); 127 | 128 | mediaBreakpoints.map((breakpoint: string) => { 129 | if (!variants.includes(breakpoint)) { 130 | variants.push(breakpoint); 131 | } 132 | }); 133 | 134 | // get aria variants 135 | const [aria] = this.getThemeProperty("aria"); 136 | aria.map(a => { 137 | if (!variants.includes("aria-" + a)) { 138 | variants.push("aria-" + a); 139 | } 140 | }); 141 | 142 | return variants; 143 | }; 144 | 145 | /** 146 | * Get the value (and key) of a supplied theme property. 147 | * @param themeProperty The theme property name 148 | */ 149 | public getThemeProperty = ( 150 | themeProperty: keyof TThemeItems, 151 | ): [string[], Array>] => { 152 | return [Object.keys(this.getTheme()[themeProperty]), Object.values(this.getTheme()[themeProperty])]; 153 | }; 154 | } 155 | 156 | /** 157 | * The class responsible for evaluating the closures inside the config. 158 | */ 159 | class ThemeClosuresEvaluator { 160 | constructor(private themeConfig: Partial) {} 161 | 162 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 163 | public evaluate(value: any, valueSourceTheme?: TThemeItems): any { 164 | // If a value is a function... 165 | if (_.isFunction(value)) { 166 | // evaluate the value by running the evaluator methods in this class. 167 | return value({ 168 | colors: tailwindColors, 169 | theme: this.makeThemePathResolver(valueSourceTheme || this.themeConfig), 170 | negative: ThemeClosuresEvaluator.negative.bind(this), 171 | breakpoints: ThemeClosuresEvaluator.breakpoints.bind(this), 172 | }); 173 | } 174 | // Otherwise, return the value. 175 | else { 176 | return value; 177 | } 178 | } 179 | 180 | /** 181 | * Creates evaluator for `theme()` functions/closures in config file 182 | */ 183 | private makeThemePathResolver = 184 | (theme: Partial) => 185 | (path: string): Record => { 186 | return _.get(theme, _.trim(path, `'"`)) as Record | string>; 187 | }; 188 | 189 | /** 190 | * Evaluate `negative()` functions/closures 191 | */ 192 | private static negative(item: Record): Record { 193 | const itemCopy = { ...item }; 194 | for (const [key] of Object.entries(itemCopy)) { 195 | itemCopy["-" + key] = itemCopy[key]; 196 | delete itemCopy[key]; 197 | } 198 | return itemCopy; 199 | } 200 | 201 | /** 202 | * Evaluate `breakpoints()` functions/closures 203 | */ 204 | private static breakpoints(item: Record): Record { 205 | const itemCopy = { ...item }; 206 | for (const [key] of Object.entries(itemCopy)) { 207 | itemCopy["screen-" + key] = itemCopy[key]; 208 | delete itemCopy[key]; 209 | } 210 | return itemCopy; 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /src/cli/core/FileContentGenerator.ts: -------------------------------------------------------------------------------- 1 | import _ from "lodash"; 2 | import { TAllClassnames } from "../types/classes"; 3 | import { TailwindConfigParser } from "./TailwindConfigParser"; 4 | 5 | export class FileContentGenerator { 6 | private _configParser: TailwindConfigParser; 7 | private readonly _generatedClassNames: TAllClassnames; 8 | 9 | /** 10 | * Initializes a new instance of the `FileContentGenerator` class. 11 | * @param generatedClassnames The generated classnames to put in the template. 12 | */ 13 | constructor(generatedClassnames: TAllClassnames, configParser: TailwindConfigParser) { 14 | this._configParser = configParser; 15 | this._generatedClassNames = generatedClassnames; 16 | } 17 | 18 | public generateFileContent = (): string => { 19 | return ( 20 | this.fileHeaderTemplate() + 21 | "\n\n" + 22 | this.importStatementsTemplate() + 23 | "\n\n" + 24 | this.regularClassnamesTypesTemplate() + 25 | "\n\n" + 26 | this.variantsTypeTemplate() + 27 | "\n\n" + 28 | this.utilityFunctionsTemplate() + 29 | "\n\n" + 30 | this.mainExportStatementsTemplate() 31 | ); 32 | }; 33 | 34 | private fileHeaderTemplate = (): string => { 35 | return ( 36 | "/* eslint-disable */\n" + 37 | "/* tslint:disable */\n" + 38 | "\n" + 39 | "//////////////////////////////////////////////////////////////////////////////\n" + 40 | "/// Autogenerated by tailwindcss-classnames CLI. https://git.io/JtsPU\n" + 41 | "/// DO NOT EDIT THIS FILE DIRECTLY!\n" + 42 | "//////////////////////////////////////////////////////////////////////////////\n" 43 | ); 44 | }; 45 | 46 | private importStatementsTemplate = (): string => { 47 | return "import classnamesLib from 'clsx';" + "\n" + `T_CUSTOM_CLASSES_IMPORT_STATEMENT`; 48 | }; 49 | 50 | private variantsTypeTemplate = (): string => { 51 | const variants = this._configParser.getVariants(); 52 | 53 | return this.generateTypesTemplate( 54 | "PseudoClassVariants", 55 | variants.map(variant => variant + this._configParser.getSeparator()), // 'hover:', 'focus:' 56 | undefined, 57 | true, 58 | ); 59 | }; 60 | 61 | private regularClassnamesTypesTemplate = (): string => { 62 | return Object.keys(this._generatedClassNames) 63 | .map(classGroupKey => { 64 | return this.generateTypesGroupTemplate( 65 | this._generatedClassNames[classGroupKey as keyof TAllClassnames] as TAllClassnames, 66 | classGroupKey, 67 | ); 68 | }) 69 | .join("\n"); 70 | }; 71 | 72 | private utilityFunctionsTemplate = (): string => { 73 | let template = 74 | "//////////// Utility Function generic type\n\n" + 75 | "type TUtilityFunction = (\n" + 76 | " ...args: Array<\n" + 77 | " | T\n" + 78 | " | `!${T}`\n" + 79 | " | `${TPseudoClassVariants}${T}`\n" + 80 | " | `${TPseudoClassVariants}!${T}`\n" + 81 | " | null\n" + 82 | " | undefined\n" + 83 | " | {[key in T | `${TPseudoClassVariants}${T}` | `!${T}` | `${TPseudoClassVariants}!${T}` | TTailwindString]?: boolean}\n" + 84 | " | TTailwindString\n" + 85 | " >\n" + 86 | ") => TTailwindString;"; 87 | 88 | /** 89 | * Specific subcategory utility functions 90 | */ 91 | for (const [categoryKey, value] of Object.entries(this._generatedClassNames)) { 92 | const subCategoriesTemplate = Object.keys(value) // sub-ctegories keys 93 | .map(SubCategory => { 94 | const fnName = _.camelCase(SubCategory); 95 | const fnType = `TUtilityFunction`; 96 | 97 | return `export const ${fnName}: ${fnType} = classnamesLib as any`; 98 | }) 99 | .join("\n"); 100 | 101 | template = 102 | template + "\n" + `\n//////////// ${categoryKey} Utility functions\n` + "\n" + subCategoriesTemplate; 103 | } 104 | 105 | /** 106 | * general category utility functions 107 | */ 108 | const generalCategoriesTemplate = Object.keys(this._generatedClassNames) 109 | .map(categorykey => { 110 | const comment = "\n" + `\n//////////// ${categorykey} Utility functions\n` + "\n"; 111 | 112 | const fnName = _.camelCase(categorykey); 113 | const fnType = `TUtilityFunction`; 114 | 115 | return comment + `export const ${fnName}: ${fnType} = classnamesLib as any`; 116 | }) 117 | .join("\n"); 118 | 119 | template = template + generalCategoriesTemplate; 120 | 121 | return template; 122 | }; 123 | 124 | private mainExportStatementsTemplate = (): string => { 125 | const specificUtilityFunctionsObjectTemplate = Object.keys(this._generatedClassNames) 126 | .map(cn => { 127 | const subCategoryObj = this._generatedClassNames[cn as keyof TAllClassnames]; 128 | if (subCategoryObj !== undefined) { 129 | return Object.keys(subCategoryObj) 130 | .map(sc => " " + sc) 131 | .join(",\n"); 132 | } 133 | }) 134 | .join(",\n"); 135 | 136 | const generalUtilityFunctionsObjectTemplate = Object.keys(this._generatedClassNames) 137 | .map(cn => " " + _.camelCase(cn)) 138 | .join(",\n"); 139 | 140 | return ( 141 | `export const TW = {\n${specificUtilityFunctionsObjectTemplate}\n}\n` + 142 | "\n" + 143 | `export const CN = {\n${generalUtilityFunctionsObjectTemplate}\n}\n` + 144 | "\n" + 145 | "export const mainCategoriesUtilityFunctions = CN;\n" + 146 | "\n" + 147 | "export const subCategoriesUtilityFunctions = TW;\n" + 148 | "\n" + 149 | 'export type TTailwindString = "TAILWIND_STRING"\n' + 150 | "\n" + 151 | "export type TArg =\n" + 152 | "| null\n" + 153 | "| undefined\n" + 154 | this.getDarkModeClassnameType() + 155 | "| TTailwindString\nIMPORTED_T_CUSTOM_CLASSES_ARG" + 156 | "\n" + 157 | "export type TTailwind = (...args: TArg[]) => TTailwindString\n" + 158 | "\n" + 159 | "export const classnames: TTailwind = classnamesLib as any\n" + 160 | "\n" + 161 | "export default classnames" 162 | ); 163 | }; 164 | 165 | /** 166 | * Get the dark mode config custom classname type 167 | * @returns the name of the classname for dark mode 168 | */ 169 | private getDarkModeClassnameType = (): string => { 170 | const darkModeConfig = this._configParser.getDarkMode(); 171 | if (_.isArray(darkModeConfig) && darkModeConfig[0] === "class") { 172 | return `| '${darkModeConfig[1]}'\n`; 173 | } else if (_.isString(darkModeConfig) && darkModeConfig === "class") { 174 | return `| 'dark'\n`; 175 | } else { 176 | return ""; 177 | } 178 | }; 179 | 180 | /** 181 | * Generates types group template for a utility classes group object. 182 | * 183 | * 184 | * ### example: 185 | * 186 | * A utility group object as: 187 | * 188 | * ```js 189 | * const FlexBox = { 190 | * alignSelf: ['self-auto', 'self-start', 'self-center'], 191 | * flexWrap: ['flex-nowrap', 'flex-wrap'], 192 | * } 193 | *``` 194 | * 195 | * will produce a template which looks like this: 196 | * 197 | * ```ts 198 | * export type TFlexWrap = 199 | * | 'flex-nowrap' 200 | * | 'flex-wrap'; 201 | * 202 | * export type TAlignSelf = 203 | * | 'self-auto' 204 | * | 'self-start' 205 | * | 'self-center'; 206 | * 207 | * export type TFlexBox = TFlexWrap | TAlignSelf; 208 | * ``` 209 | */ 210 | private generateTypesGroupTemplate = (group: TAllClassnames, groupName: string): string => { 211 | const members = Object.keys(group); 212 | 213 | const generateMembersStatements = (): string[] => { 214 | return members.map(member => { 215 | return this.generateTypesTemplate( 216 | member, 217 | group[member as keyof TAllClassnames] as string[], 218 | this._configParser.getPrefix(), 219 | ); 220 | }); 221 | }; 222 | 223 | const generateGroupStatement = (): string => { 224 | const getMembersStatementsReferences = (): string => 225 | members.map(member => "T" + _.upperFirst(member)).join("\n | "); 226 | 227 | return `export type T${_.upperFirst(groupName)} =` + "\n | " + getMembersStatementsReferences() + "\n"; 228 | }; 229 | 230 | return generateMembersStatements().join("\n\n") + "\n\n" + generateGroupStatement(); 231 | }; 232 | 233 | /** 234 | * Generates TS types template from a list of strings. 235 | * 236 | * #### Example: 237 | * 238 | * Given typeName: 'baz' and items: 239 | * ```js 240 | * ['foo', 'bar'] 241 | * ``` 242 | * 243 | * generates: 244 | * 245 | * ``` 246 | * export type TBaz 247 | * | foo 248 | * | bar; 249 | * ``` 250 | * or with quoutes: 251 | * ``` 252 | * export type TBaz 253 | * | 'foo' 254 | * | 'bar'; 255 | * ``` 256 | * @param typeName The name of the type (without T prefix). 257 | * @param items The list of the strings of items to add to the type name. 258 | * @param prefix The prefix to add to the beginning of each item of the string array. 259 | * @param surroundWithQuotes Whether to quote the types or not (make it a string or an actual type) 260 | */ 261 | private generateTypesTemplate = ( 262 | typeName: string, 263 | items: string[], 264 | prefix?: string, 265 | surroundWithQuotes: boolean = true, 266 | ): string => { 267 | return ( 268 | `export type T${_.upperFirst(typeName)} =` + 269 | "\n | " + 270 | items 271 | .flatMap(item => { 272 | const classnamesThatShouldKeepTheDefaultSuffix = ["cursor"]; 273 | 274 | return classnamesThatShouldKeepTheDefaultSuffix.map(x => { 275 | const shouldKeepDefaultSuffix: boolean = item.includes(x); 276 | const name = shouldKeepDefaultSuffix ? item : item.replace("-DEFAULT", ""); 277 | 278 | const nameWithOrWithoutPrefix = `${prefix ? prefix : ""}${name}`; 279 | 280 | return surroundWithQuotes ? `'${nameWithOrWithoutPrefix}'` : nameWithOrWithoutPrefix; 281 | }); 282 | }) 283 | .join("\n | ") 284 | ); 285 | }; 286 | } 287 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tailwindcss-classnames ![NPM](https://img.shields.io/npm/l/tailwindcss-classnames) [![npm bundle size](https://img.shields.io/bundlephobia/minzip/tailwindcss-classnames)](https://bundlephobia.com/result?p=tailwindcss-classnames) [![npm version](https://img.shields.io/npm/v/tailwindcss-classnames.svg)](https://www.npmjs.com/package/tailwindcss-classnames) 2 | 3 | Functional typed classnames for TailwindCSS 4 | 5 | [TailwindCSS](https://tailwindcss.com/) is a CSS library that has gained a lot of traction. The developer experience is pretty epic and you ensure a low footprint on your css by composing existing classes for most of your css. 6 | 7 | ## So why mess with it? 8 | 9 | TailwindCSS is based on strings and with some nice tooling on top like [TailwindCSS VSCode extension](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) you get a pretty descent experience. That said, there are limitations to a purely declarative approach of strings. When using **tailwindcss-classnames** you will get additional power in the form of: 10 | 11 | - **Validation of classnames**: You can not write the wrong classname, cause the API only allows you to insert valid classnames 12 | - **Functional approach**: Since we are working in Typescript we get more freedom in using functional powers like composition and dynamic composition 13 | - **Defining by variables**: Even though it is nice to write TailwindCSS inline with your elements, it does not scale. You want to move definitions outside of the component for reusability and composition 14 | - **Support for all editors and IDEs**: Because it's just TypeScript types, you get these powers in all editors and IDEs that support TypeScript. 15 | 16 | You can not get this experience using pure TailwindCSS and the VSCode extension, but you do get it with **tailwindcss-classnames**. 17 | 18 | [![Edit tailwindcss-classnames](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/elegant-lederberg-sih5r?fontsize=14&hidenavigation=1&theme=dark) 19 | 20 | ## Install 21 | 22 | Please [follow the guide](https://tailwindcss.com/docs/installation/) to set up **TailwindCSS**. Now do: 23 | 24 | ```bash 25 | npm install tailwindcss-classnames 26 | ``` 27 | 28 | **NOTE:** This project versions match with TailwindCSS versions except for [semver _patch_](https://semver.org/) releases 29 | 30 | The project is literally the [clsx](https://www.npmjs.com/package/clsx) project with custom typing. That means it arrives at your browser at approximately **2.7kB** minified and gzipped ([bundlephobia](https://bundlephobia.com/result?p=tailwindcss-classnames)). 31 | 32 | ## **What's New in v3** 33 | 34 | - Way better performance overall (thanks to [@dylanvann](https://github.com/DylanVann)'s [idea and suggestions](https://github.com/muhammadsammy/tailwindcss-classnames/pull/281#discussion_r731682711)): 35 | 36 | - Generated file size is reduced to be **< 200 KB** (default config). Previous version was generating a file sized about [100 MB](https://github.com/muhammadsammy/tailwindcss-classnames/issues/282). 37 | - Fast autocompletion: this is due to usage of more specific utility functions and using template string types 38 | 39 | - **BREAKING**: Dropped support for JIT engine's Colors Opacity suffix feature (due to TypesScript _TS2590_ error) 40 | 41 | - **BREAKING**: Create Utility functions that accepts classnames (and pseudoclassnames) of that category. The `classnames` function won't accept or show autocompletion of all classnames anymore, but it will accept a function of these category functions [(#293)](https://github.com/muhammadsammy/tailwindcss-classnames/issues/293) 42 | 43 | ✅ Correct 44 | 45 | ```ts 46 | classnames( 47 | display("flex", "md:block"), 48 | textColor("text-black", "hover:text-red-600"), 49 | flexDirection("flex-row-reverse"), 50 | ); 51 | ``` 52 | 53 | OR 54 | 55 | ```ts 56 | classnames( 57 | flexBox("flex", "md:block", "flex-row-reverse"), 58 | typography("text-black", "hover:text-red-600", "text-3xl", "text-center", "italic"), 59 | ); 60 | ``` 61 | 62 | ❌ Incorrect 63 | 64 | ```ts 65 | classnames("flex", "md:block", "text-black", "hover:text-red-600", "flex-row-reverse"); 66 | ``` 67 | 68 | ## **twcn3** 69 | 70 | To make the migrtion easier, [Ryan Goree](https://github.com/ryangoree) created [twcn3](https://www.npmjs.com/package/twcn3) which is a CLI that converts old codebase using the single `classnames` function into multiple utility functions. 71 | 72 | ## Create classes 73 | 74 | ```js 75 | import { classnames } from "tailwindcss-classnames"; 76 | 77 | classnames("border-none", "rounded-sm"); 78 | ``` 79 | 80 | The arguments passed to **classnames** is typed, which means you get discoverability. You can even search for the supported classes: 81 | 82 | ![DISCOVER](/discover.png) 83 | 84 | ## Dynamic classes 85 | 86 | Since we are using **classnames** you can also add your classes dynamically: 87 | 88 | ```js 89 | import { classnames } from "tailwindcss-classnames"; 90 | 91 | classnames("border-none", "rounded-sm", { 92 | ["bg-gray-200"]: true, 93 | }); 94 | ``` 95 | 96 | ## Composing classes 97 | 98 | Even though **classnames** just returns a string, it is a special typed string that you can compose into other definitions. 99 | 100 | ```js 101 | import { classnames } from "tailwindcss-classnames"; 102 | 103 | export const button = classnames("border-none", "rounded-sm"); 104 | 105 | export const redButton = classnames(button, "bg-red-100"); 106 | ``` 107 | 108 | ## Using with React 109 | 110 | Since React has excellent typing support I want to give an example of how you could use it. 111 | 112 | ```tsx 113 | // styles.ts 114 | import { classnames } from "tailwindcss-classnames"; 115 | 116 | export const form = classnames("container", "w-full"); 117 | 118 | export const button = classnames("border-none", "rounded-sm"); 119 | 120 | export const alertButton = classnames(button, "bg-red-100"); 121 | 122 | export const disabled = classnames("opacity-25", "bg-gray-100"); 123 | 124 | export const submitButton = (disabled: boolean) => 125 | classnames(styles.button, { 126 | [styles.disabled]: disabled, 127 | }); 128 | 129 | // App.tsx 130 | import * as React from "react"; 131 | import * as styles from "./styles"; 132 | 133 | export const App: React.FC<{ disabled }> = ({ disabled }) => { 134 | return ( 135 |
136 | 139 | 140 |
141 | ); 142 | }; 143 | ``` 144 | 145 | ## Using the CLI 146 | 147 | The types included in this package are the default tailwindcss classes, but if you modified your tailwind config file and/or want to add external custom classes, you can use the CLI tool to do this. 148 | 149 | ### CLI arguments 150 | 151 | - `-i`, `--input` Name or relative path of the TailwindCSS config file **(if not provided, tries to find 'tailwind.config.js')** 152 | - `-o`, `--output` Name or relative path of the generated types file **(optional, default: "tailwindcss-classnames.ts")** 153 | - `-x`, `--extra` Name or relative path of the file with the custom extra types **(optional)** 154 | - `-h`, `--help` display help for command 155 | 156 | ### Example of CLI usage 157 | 158 | Add the CLI to npm scripts in your **package.json** then run `npm run generate-css-types` or `yarn generate-css-types`: 159 | 160 | ```json 161 | "scripts": { 162 | "generate-css-types": "tailwindcss-classnames -i path/to/tailwind.config.js -o path/to/output-file.ts" 163 | } 164 | ``` 165 | 166 | **⚠️ NOTE:** that if you want to add custom types from external file, the type must be a default export: 167 | 168 | ```ts 169 | export default MyCustomType; 170 | type MyCustomType = 171 | | "btn" 172 | | "sidebar" 173 | ... 174 | ``` 175 | 176 | ### How to use generated types 177 | 178 | #### Method 1 179 | 180 | import _the generated_ file (and **NOT** the actual library) into your code in order to get the customized classnames, like this: 181 | 182 | ```ts 183 | import { classnames } from "path/to/generated/tailwindcss-classnames"; 184 | ``` 185 | 186 | #### Method 2 187 | 188 | A more elegant approach is to add the generated file to your projects tsconfig.json compilerOptions paths which should allow you to keep the import the same and use your generated version of tailwindcss-classnames instead of the node_modules one. 189 | 190 | ```json 191 | { 192 | "compilerOptions": { 193 | "paths": { 194 | "tailwindcss-classnames": ["path/to/generated/tailwindcss-classnames"] 195 | } 196 | } 197 | } 198 | ``` 199 | 200 | then: 201 | 202 | ```ts 203 | import { classnames } from "tailwindcss-classnames"; 204 | ``` 205 | 206 | [From original comment by @andykenward](https://github.com/muhammadsammy/tailwindcss-classnames/discussions/227#discussioncomment-3101220) 207 | 208 | ### Known limitiations 209 | 210 | - Relative imports inside the config does not work. use `__dirname` instead. See [#120](https://github.com/muhammadsammy/tailwindcss-classnames/issues/120) . 211 | - `npx tailwindcss-classnames` won't work. Use as an npm script as mentioned above. 212 | - Only official TailwindLabs plugins are supported. 213 | - Some JIT features are not supported ([#204](https://github.com/muhammadsammy/tailwindcss-classnames/issues/204)). 214 | 215 | Any help with these issues is very much appreciated. 216 | 217 | ## Contributing 218 | 219 | All contributions from everyone are very welcome. 220 | 221 | Please read the [contributing guidelines](./CONTRIBUTING.md) before submitting a Pull Request. 222 | 223 | ## Credits 224 | 225 | This project was started by [Christian Alfoni](https://github.com/christianalfoni) and is now maintained by [Muhammad Sammy](https://github.com/muhammadsammy). The full list of contributors can be found [here](https://github.com/muhammadsammy/tailwindcss-classnames/graphs/contributors). 226 | -------------------------------------------------------------------------------- /src/cli/lib/defaultTailwindConfig.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // @ts-nocheck 3 | 4 | /** @type {import('tailwindcss').Config} */ 5 | export const defaultTailwindConfig = { 6 | content: [], 7 | presets: [], 8 | darkMode: "media", // or 'class' 9 | theme: { 10 | screens: { 11 | sm: "640px", 12 | md: "768px", 13 | lg: "1024px", 14 | xl: "1280px", 15 | "2xl": "1536px", 16 | }, 17 | colors: ({ colors }) => ({ 18 | inherit: colors.inherit, 19 | current: colors.current, 20 | transparent: colors.transparent, 21 | black: colors.black, 22 | white: colors.white, 23 | slate: colors.slate, 24 | gray: colors.gray, 25 | zinc: colors.zinc, 26 | neutral: colors.neutral, 27 | stone: colors.stone, 28 | red: colors.red, 29 | orange: colors.orange, 30 | amber: colors.amber, 31 | yellow: colors.yellow, 32 | lime: colors.lime, 33 | green: colors.green, 34 | emerald: colors.emerald, 35 | teal: colors.teal, 36 | cyan: colors.cyan, 37 | sky: colors.sky, 38 | blue: colors.blue, 39 | indigo: colors.indigo, 40 | violet: colors.violet, 41 | purple: colors.purple, 42 | fuchsia: colors.fuchsia, 43 | pink: colors.pink, 44 | rose: colors.rose, 45 | }), 46 | columns: { 47 | auto: "auto", 48 | 1: "1", 49 | 2: "2", 50 | 3: "3", 51 | 4: "4", 52 | 5: "5", 53 | 6: "6", 54 | 7: "7", 55 | 8: "8", 56 | 9: "9", 57 | 10: "10", 58 | 11: "11", 59 | 12: "12", 60 | "3xs": "16rem", 61 | "2xs": "18rem", 62 | xs: "20rem", 63 | sm: "24rem", 64 | md: "28rem", 65 | lg: "32rem", 66 | xl: "36rem", 67 | "2xl": "42rem", 68 | "3xl": "48rem", 69 | "4xl": "56rem", 70 | "5xl": "64rem", 71 | "6xl": "72rem", 72 | "7xl": "80rem", 73 | }, 74 | spacing: { 75 | px: "1px", 76 | 0: "0px", 77 | 0.5: "0.125rem", 78 | 1: "0.25rem", 79 | 1.5: "0.375rem", 80 | 2: "0.5rem", 81 | 2.5: "0.625rem", 82 | 3: "0.75rem", 83 | 3.5: "0.875rem", 84 | 4: "1rem", 85 | 5: "1.25rem", 86 | 6: "1.5rem", 87 | 7: "1.75rem", 88 | 8: "2rem", 89 | 9: "2.25rem", 90 | 10: "2.5rem", 91 | 11: "2.75rem", 92 | 12: "3rem", 93 | 14: "3.5rem", 94 | 16: "4rem", 95 | 20: "5rem", 96 | 24: "6rem", 97 | 28: "7rem", 98 | 32: "8rem", 99 | 36: "9rem", 100 | 40: "10rem", 101 | 44: "11rem", 102 | 48: "12rem", 103 | 52: "13rem", 104 | 56: "14rem", 105 | 60: "15rem", 106 | 64: "16rem", 107 | 72: "18rem", 108 | 80: "20rem", 109 | 96: "24rem", 110 | }, 111 | animation: { 112 | none: "none", 113 | spin: "spin 1s linear infinite", 114 | ping: "ping 1s cubic-bezier(0, 0, 0.2, 1) infinite", 115 | pulse: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite", 116 | bounce: "bounce 1s infinite", 117 | }, 118 | aria: { 119 | checked: 'checked="true"', 120 | disabled: 'disabled="true"', 121 | expanded: 'expanded="true"', 122 | hidden: 'hidden="true"', 123 | pressed: 'pressed="true"', 124 | readonly: 'readonly="true"', 125 | required: 'required="true"', 126 | selected: 'selected="true"', 127 | }, 128 | aspectRatio: { 129 | auto: "auto", 130 | square: "1 / 1", 131 | video: "16 / 9", 132 | }, 133 | backdropBlur: ({ theme }) => theme("blur"), 134 | backdropBrightness: ({ theme }) => theme("brightness"), 135 | backdropContrast: ({ theme }) => theme("contrast"), 136 | backdropGrayscale: ({ theme }) => theme("grayscale"), 137 | backdropHueRotate: ({ theme }) => theme("hueRotate"), 138 | backdropInvert: ({ theme }) => theme("invert"), 139 | backdropOpacity: ({ theme }) => theme("opacity"), 140 | backdropSaturate: ({ theme }) => theme("saturate"), 141 | backdropSepia: ({ theme }) => theme("sepia"), 142 | backgroundColor: ({ theme }) => theme("colors"), 143 | backgroundImage: { 144 | none: "none", 145 | "gradient-to-t": "linear-gradient(to top, var(--tw-gradient-stops))", 146 | "gradient-to-tr": "linear-gradient(to top right, var(--tw-gradient-stops))", 147 | "gradient-to-r": "linear-gradient(to right, var(--tw-gradient-stops))", 148 | "gradient-to-br": "linear-gradient(to bottom right, var(--tw-gradient-stops))", 149 | "gradient-to-b": "linear-gradient(to bottom, var(--tw-gradient-stops))", 150 | "gradient-to-bl": "linear-gradient(to bottom left, var(--tw-gradient-stops))", 151 | "gradient-to-l": "linear-gradient(to left, var(--tw-gradient-stops))", 152 | "gradient-to-tl": "linear-gradient(to top left, var(--tw-gradient-stops))", 153 | }, 154 | backgroundOpacity: ({ theme }) => theme("opacity"), 155 | backgroundPosition: { 156 | bottom: "bottom", 157 | center: "center", 158 | left: "left", 159 | "left-bottom": "left bottom", 160 | "left-top": "left top", 161 | right: "right", 162 | "right-bottom": "right bottom", 163 | "right-top": "right top", 164 | top: "top", 165 | }, 166 | backgroundSize: { 167 | auto: "auto", 168 | cover: "cover", 169 | contain: "contain", 170 | }, 171 | blur: { 172 | 0: "0", 173 | none: "0", 174 | sm: "4px", 175 | DEFAULT: "8px", 176 | md: "12px", 177 | lg: "16px", 178 | xl: "24px", 179 | "2xl": "40px", 180 | "3xl": "64px", 181 | }, 182 | brightness: { 183 | 0: "0", 184 | 50: ".5", 185 | 75: ".75", 186 | 90: ".9", 187 | 95: ".95", 188 | 100: "1", 189 | 105: "1.05", 190 | 110: "1.1", 191 | 125: "1.25", 192 | 150: "1.5", 193 | 200: "2", 194 | }, 195 | borderColor: ({ theme }) => ({ 196 | ...theme("colors"), 197 | DEFAULT: theme("colors.gray.200", "currentColor"), 198 | }), 199 | borderOpacity: ({ theme }) => theme("opacity"), 200 | borderRadius: { 201 | none: "0px", 202 | sm: "0.125rem", 203 | DEFAULT: "0.25rem", 204 | md: "0.375rem", 205 | lg: "0.5rem", 206 | xl: "0.75rem", 207 | "2xl": "1rem", 208 | "3xl": "1.5rem", 209 | full: "9999px", 210 | }, 211 | borderSpacing: ({ theme }) => ({ 212 | ...theme("spacing"), 213 | }), 214 | borderWidth: { 215 | DEFAULT: "1px", 216 | 0: "0px", 217 | 2: "2px", 218 | 4: "4px", 219 | 8: "8px", 220 | }, 221 | boxShadow: { 222 | sm: "0 1px 2px 0 rgb(0 0 0 / 0.05)", 223 | DEFAULT: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)", 224 | md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)", 225 | lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)", 226 | xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)", 227 | "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)", 228 | inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)", 229 | none: "none", 230 | }, 231 | boxShadowColor: ({ theme }) => theme("colors"), 232 | caretColor: ({ theme }) => theme("colors"), 233 | accentColor: ({ theme }) => ({ 234 | ...theme("colors"), 235 | auto: "auto", 236 | }), 237 | contrast: { 238 | 0: "0", 239 | 50: ".5", 240 | 75: ".75", 241 | 100: "1", 242 | 125: "1.25", 243 | 150: "1.5", 244 | 200: "2", 245 | }, 246 | container: {}, 247 | content: { 248 | none: "none", 249 | }, 250 | cursor: { 251 | auto: "auto", 252 | default: "default", 253 | pointer: "pointer", 254 | wait: "wait", 255 | text: "text", 256 | move: "move", 257 | help: "help", 258 | "not-allowed": "not-allowed", 259 | none: "none", 260 | "context-menu": "context-menu", 261 | progress: "progress", 262 | cell: "cell", 263 | crosshair: "crosshair", 264 | "vertical-text": "vertical-text", 265 | alias: "alias", 266 | copy: "copy", 267 | "no-drop": "no-drop", 268 | grab: "grab", 269 | grabbing: "grabbing", 270 | "all-scroll": "all-scroll", 271 | "col-resize": "col-resize", 272 | "row-resize": "row-resize", 273 | "n-resize": "n-resize", 274 | "e-resize": "e-resize", 275 | "s-resize": "s-resize", 276 | "w-resize": "w-resize", 277 | "ne-resize": "ne-resize", 278 | "nw-resize": "nw-resize", 279 | "se-resize": "se-resize", 280 | "sw-resize": "sw-resize", 281 | "ew-resize": "ew-resize", 282 | "ns-resize": "ns-resize", 283 | "nesw-resize": "nesw-resize", 284 | "nwse-resize": "nwse-resize", 285 | "zoom-in": "zoom-in", 286 | "zoom-out": "zoom-out", 287 | }, 288 | divideColor: ({ theme }) => theme("borderColor"), 289 | divideOpacity: ({ theme }) => theme("borderOpacity"), 290 | divideWidth: ({ theme }) => theme("borderWidth"), 291 | dropShadow: { 292 | sm: "0 1px 1px rgb(0 0 0 / 0.05)", 293 | DEFAULT: ["0 1px 2px rgb(0 0 0 / 0.1)", "0 1px 1px rgb(0 0 0 / 0.06)"], 294 | md: ["0 4px 3px rgb(0 0 0 / 0.07)", "0 2px 2px rgb(0 0 0 / 0.06)"], 295 | lg: ["0 10px 8px rgb(0 0 0 / 0.04)", "0 4px 3px rgb(0 0 0 / 0.1)"], 296 | xl: ["0 20px 13px rgb(0 0 0 / 0.03)", "0 8px 5px rgb(0 0 0 / 0.08)"], 297 | "2xl": "0 25px 25px rgb(0 0 0 / 0.15)", 298 | none: "0 0 #0000", 299 | }, 300 | fill: ({ theme }) => ({ 301 | none: "none", 302 | ...theme("colors"), 303 | }), 304 | grayscale: { 305 | 0: "0", 306 | DEFAULT: "100%", 307 | }, 308 | hueRotate: { 309 | 0: "0deg", 310 | 15: "15deg", 311 | 30: "30deg", 312 | 60: "60deg", 313 | 90: "90deg", 314 | 180: "180deg", 315 | }, 316 | invert: { 317 | 0: "0", 318 | DEFAULT: "100%", 319 | }, 320 | flex: { 321 | 1: "1 1 0%", 322 | auto: "1 1 auto", 323 | initial: "0 1 auto", 324 | none: "none", 325 | }, 326 | flexBasis: ({ theme }) => ({ 327 | auto: "auto", 328 | ...theme("spacing"), 329 | "1/2": "50%", 330 | "1/3": "33.333333%", 331 | "2/3": "66.666667%", 332 | "1/4": "25%", 333 | "2/4": "50%", 334 | "3/4": "75%", 335 | "1/5": "20%", 336 | "2/5": "40%", 337 | "3/5": "60%", 338 | "4/5": "80%", 339 | "1/6": "16.666667%", 340 | "2/6": "33.333333%", 341 | "3/6": "50%", 342 | "4/6": "66.666667%", 343 | "5/6": "83.333333%", 344 | "1/12": "8.333333%", 345 | "2/12": "16.666667%", 346 | "3/12": "25%", 347 | "4/12": "33.333333%", 348 | "5/12": "41.666667%", 349 | "6/12": "50%", 350 | "7/12": "58.333333%", 351 | "8/12": "66.666667%", 352 | "9/12": "75%", 353 | "10/12": "83.333333%", 354 | "11/12": "91.666667%", 355 | full: "100%", 356 | }), 357 | flexGrow: { 358 | 0: "0", 359 | DEFAULT: "1", 360 | }, 361 | flexShrink: { 362 | 0: "0", 363 | DEFAULT: "1", 364 | }, 365 | fontFamily: { 366 | sans: [ 367 | "ui-sans-serif", 368 | "system-ui", 369 | "-apple-system", 370 | "BlinkMacSystemFont", 371 | '"Segoe UI"', 372 | "Roboto", 373 | '"Helvetica Neue"', 374 | "Arial", 375 | '"Noto Sans"', 376 | "sans-serif", 377 | '"Apple Color Emoji"', 378 | '"Segoe UI Emoji"', 379 | '"Segoe UI Symbol"', 380 | '"Noto Color Emoji"', 381 | ], 382 | serif: ["ui-serif", "Georgia", "Cambria", '"Times New Roman"', "Times", "serif"], 383 | mono: [ 384 | "ui-monospace", 385 | "SFMono-Regular", 386 | "Menlo", 387 | "Monaco", 388 | "Consolas", 389 | '"Liberation Mono"', 390 | '"Courier New"', 391 | "monospace", 392 | ], 393 | }, 394 | fontSize: { 395 | xs: ["0.75rem", { lineHeight: "1rem" }], 396 | sm: ["0.875rem", { lineHeight: "1.25rem" }], 397 | base: ["1rem", { lineHeight: "1.5rem" }], 398 | lg: ["1.125rem", { lineHeight: "1.75rem" }], 399 | xl: ["1.25rem", { lineHeight: "1.75rem" }], 400 | "2xl": ["1.5rem", { lineHeight: "2rem" }], 401 | "3xl": ["1.875rem", { lineHeight: "2.25rem" }], 402 | "4xl": ["2.25rem", { lineHeight: "2.5rem" }], 403 | "5xl": ["3rem", { lineHeight: "1" }], 404 | "6xl": ["3.75rem", { lineHeight: "1" }], 405 | "7xl": ["4.5rem", { lineHeight: "1" }], 406 | "8xl": ["6rem", { lineHeight: "1" }], 407 | "9xl": ["8rem", { lineHeight: "1" }], 408 | }, 409 | fontWeight: { 410 | thin: "100", 411 | extralight: "200", 412 | light: "300", 413 | normal: "400", 414 | medium: "500", 415 | semibold: "600", 416 | bold: "700", 417 | extrabold: "800", 418 | black: "900", 419 | }, 420 | gap: ({ theme }) => theme("spacing"), 421 | gradientColorStops: ({ theme }) => theme("colors"), 422 | gridAutoColumns: { 423 | auto: "auto", 424 | min: "min-content", 425 | max: "max-content", 426 | fr: "minmax(0, 1fr)", 427 | }, 428 | gridAutoRows: { 429 | auto: "auto", 430 | min: "min-content", 431 | max: "max-content", 432 | fr: "minmax(0, 1fr)", 433 | }, 434 | gridColumn: { 435 | auto: "auto", 436 | "span-1": "span 1 / span 1", 437 | "span-2": "span 2 / span 2", 438 | "span-3": "span 3 / span 3", 439 | "span-4": "span 4 / span 4", 440 | "span-5": "span 5 / span 5", 441 | "span-6": "span 6 / span 6", 442 | "span-7": "span 7 / span 7", 443 | "span-8": "span 8 / span 8", 444 | "span-9": "span 9 / span 9", 445 | "span-10": "span 10 / span 10", 446 | "span-11": "span 11 / span 11", 447 | "span-12": "span 12 / span 12", 448 | "span-full": "1 / -1", 449 | }, 450 | gridColumnEnd: { 451 | auto: "auto", 452 | 1: "1", 453 | 2: "2", 454 | 3: "3", 455 | 4: "4", 456 | 5: "5", 457 | 6: "6", 458 | 7: "7", 459 | 8: "8", 460 | 9: "9", 461 | 10: "10", 462 | 11: "11", 463 | 12: "12", 464 | 13: "13", 465 | }, 466 | gridColumnStart: { 467 | auto: "auto", 468 | 1: "1", 469 | 2: "2", 470 | 3: "3", 471 | 4: "4", 472 | 5: "5", 473 | 6: "6", 474 | 7: "7", 475 | 8: "8", 476 | 9: "9", 477 | 10: "10", 478 | 11: "11", 479 | 12: "12", 480 | 13: "13", 481 | }, 482 | gridRow: { 483 | auto: "auto", 484 | "span-1": "span 1 / span 1", 485 | "span-2": "span 2 / span 2", 486 | "span-3": "span 3 / span 3", 487 | "span-4": "span 4 / span 4", 488 | "span-5": "span 5 / span 5", 489 | "span-6": "span 6 / span 6", 490 | "span-full": "1 / -1", 491 | }, 492 | gridRowStart: { 493 | auto: "auto", 494 | 1: "1", 495 | 2: "2", 496 | 3: "3", 497 | 4: "4", 498 | 5: "5", 499 | 6: "6", 500 | 7: "7", 501 | }, 502 | gridRowEnd: { 503 | auto: "auto", 504 | 1: "1", 505 | 2: "2", 506 | 3: "3", 507 | 4: "4", 508 | 5: "5", 509 | 6: "6", 510 | 7: "7", 511 | }, 512 | gridTemplateColumns: { 513 | none: "none", 514 | 1: "repeat(1, minmax(0, 1fr))", 515 | 2: "repeat(2, minmax(0, 1fr))", 516 | 3: "repeat(3, minmax(0, 1fr))", 517 | 4: "repeat(4, minmax(0, 1fr))", 518 | 5: "repeat(5, minmax(0, 1fr))", 519 | 6: "repeat(6, minmax(0, 1fr))", 520 | 7: "repeat(7, minmax(0, 1fr))", 521 | 8: "repeat(8, minmax(0, 1fr))", 522 | 9: "repeat(9, minmax(0, 1fr))", 523 | 10: "repeat(10, minmax(0, 1fr))", 524 | 11: "repeat(11, minmax(0, 1fr))", 525 | 12: "repeat(12, minmax(0, 1fr))", 526 | }, 527 | gridTemplateRows: { 528 | none: "none", 529 | 1: "repeat(1, minmax(0, 1fr))", 530 | 2: "repeat(2, minmax(0, 1fr))", 531 | 3: "repeat(3, minmax(0, 1fr))", 532 | 4: "repeat(4, minmax(0, 1fr))", 533 | 5: "repeat(5, minmax(0, 1fr))", 534 | 6: "repeat(6, minmax(0, 1fr))", 535 | }, 536 | height: ({ theme }) => ({ 537 | auto: "auto", 538 | ...theme("spacing"), 539 | "1/2": "50%", 540 | "1/3": "33.333333%", 541 | "2/3": "66.666667%", 542 | "1/4": "25%", 543 | "2/4": "50%", 544 | "3/4": "75%", 545 | "1/5": "20%", 546 | "2/5": "40%", 547 | "3/5": "60%", 548 | "4/5": "80%", 549 | "1/6": "16.666667%", 550 | "2/6": "33.333333%", 551 | "3/6": "50%", 552 | "4/6": "66.666667%", 553 | "5/6": "83.333333%", 554 | full: "100%", 555 | screen: "100vh", 556 | min: "min-content", 557 | max: "max-content", 558 | fit: "fit-content", 559 | }), 560 | inset: ({ theme }) => ({ 561 | auto: "auto", 562 | ...theme("spacing"), 563 | "1/2": "50%", 564 | "1/3": "33.333333%", 565 | "2/3": "66.666667%", 566 | "1/4": "25%", 567 | "2/4": "50%", 568 | "3/4": "75%", 569 | full: "100%", 570 | }), 571 | keyframes: { 572 | spin: { 573 | to: { 574 | transform: "rotate(360deg)", 575 | }, 576 | }, 577 | ping: { 578 | "75%, 100%": { 579 | transform: "scale(2)", 580 | opacity: "0", 581 | }, 582 | }, 583 | pulse: { 584 | "50%": { 585 | opacity: ".5", 586 | }, 587 | }, 588 | bounce: { 589 | "0%, 100%": { 590 | transform: "translateY(-25%)", 591 | animationTimingFunction: "cubic-bezier(0.8,0,1,1)", 592 | }, 593 | "50%": { 594 | transform: "none", 595 | animationTimingFunction: "cubic-bezier(0,0,0.2,1)", 596 | }, 597 | }, 598 | }, 599 | letterSpacing: { 600 | tighter: "-0.05em", 601 | tight: "-0.025em", 602 | normal: "0em", 603 | wide: "0.025em", 604 | wider: "0.05em", 605 | widest: "0.1em", 606 | }, 607 | lineHeight: { 608 | none: "1", 609 | tight: "1.25", 610 | snug: "1.375", 611 | normal: "1.5", 612 | relaxed: "1.625", 613 | loose: "2", 614 | 3: ".75rem", 615 | 4: "1rem", 616 | 5: "1.25rem", 617 | 6: "1.5rem", 618 | 7: "1.75rem", 619 | 8: "2rem", 620 | 9: "2.25rem", 621 | 10: "2.5rem", 622 | }, 623 | listStyleType: { 624 | none: "none", 625 | disc: "disc", 626 | decimal: "decimal", 627 | }, 628 | margin: ({ theme }) => ({ 629 | auto: "auto", 630 | ...theme("spacing"), 631 | }), 632 | maxHeight: ({ theme }) => ({ 633 | ...theme("spacing"), 634 | full: "100%", 635 | screen: "100vh", 636 | min: "min-content", 637 | max: "max-content", 638 | fit: "fit-content", 639 | }), 640 | maxWidth: ({ theme, breakpoints }) => ({ 641 | none: "none", 642 | 0: "0rem", 643 | xs: "20rem", 644 | sm: "24rem", 645 | md: "28rem", 646 | lg: "32rem", 647 | xl: "36rem", 648 | "2xl": "42rem", 649 | "3xl": "48rem", 650 | "4xl": "56rem", 651 | "5xl": "64rem", 652 | "6xl": "72rem", 653 | "7xl": "80rem", 654 | full: "100%", 655 | min: "min-content", 656 | max: "max-content", 657 | fit: "fit-content", 658 | prose: "65ch", 659 | ...breakpoints(theme("screens")), 660 | }), 661 | minHeight: { 662 | 0: "0px", 663 | full: "100%", 664 | screen: "100vh", 665 | min: "min-content", 666 | max: "max-content", 667 | fit: "fit-content", 668 | }, 669 | minWidth: { 670 | 0: "0px", 671 | full: "100%", 672 | min: "min-content", 673 | max: "max-content", 674 | fit: "fit-content", 675 | }, 676 | objectPosition: { 677 | bottom: "bottom", 678 | center: "center", 679 | left: "left", 680 | "left-bottom": "left bottom", 681 | "left-top": "left top", 682 | right: "right", 683 | "right-bottom": "right bottom", 684 | "right-top": "right top", 685 | top: "top", 686 | }, 687 | opacity: { 688 | 0: "0", 689 | 5: "0.05", 690 | 10: "0.1", 691 | 20: "0.2", 692 | 25: "0.25", 693 | 30: "0.3", 694 | 40: "0.4", 695 | 50: "0.5", 696 | 60: "0.6", 697 | 70: "0.7", 698 | 75: "0.75", 699 | 80: "0.8", 700 | 90: "0.9", 701 | 95: "0.95", 702 | 100: "1", 703 | }, 704 | order: { 705 | first: "-9999", 706 | last: "9999", 707 | none: "0", 708 | 1: "1", 709 | 2: "2", 710 | 3: "3", 711 | 4: "4", 712 | 5: "5", 713 | 6: "6", 714 | 7: "7", 715 | 8: "8", 716 | 9: "9", 717 | 10: "10", 718 | 11: "11", 719 | 12: "12", 720 | }, 721 | padding: ({ theme }) => theme("spacing"), 722 | placeholderColor: ({ theme }) => theme("colors"), 723 | placeholderOpacity: ({ theme }) => theme("opacity"), 724 | outlineColor: ({ theme }) => theme("colors"), 725 | outlineOffset: { 726 | 0: "0px", 727 | 1: "1px", 728 | 2: "2px", 729 | 4: "4px", 730 | 8: "8px", 731 | }, 732 | outlineWidth: { 733 | 0: "0px", 734 | 1: "1px", 735 | 2: "2px", 736 | 4: "4px", 737 | 8: "8px", 738 | }, 739 | ringColor: ({ theme }) => ({ 740 | DEFAULT: theme("colors.blue.500", "#3b82f6"), 741 | ...theme("colors"), 742 | }), 743 | ringOffsetColor: ({ theme }) => theme("colors"), 744 | ringOffsetWidth: { 745 | 0: "0px", 746 | 1: "1px", 747 | 2: "2px", 748 | 4: "4px", 749 | 8: "8px", 750 | }, 751 | ringOpacity: ({ theme }) => ({ 752 | DEFAULT: "0.5", 753 | ...theme("opacity"), 754 | }), 755 | ringWidth: { 756 | DEFAULT: "3px", 757 | 0: "0px", 758 | 1: "1px", 759 | 2: "2px", 760 | 4: "4px", 761 | 8: "8px", 762 | }, 763 | rotate: { 764 | 0: "0deg", 765 | 1: "1deg", 766 | 2: "2deg", 767 | 3: "3deg", 768 | 6: "6deg", 769 | 12: "12deg", 770 | 45: "45deg", 771 | 90: "90deg", 772 | 180: "180deg", 773 | }, 774 | saturate: { 775 | 0: "0", 776 | 50: ".5", 777 | 100: "1", 778 | 150: "1.5", 779 | 200: "2", 780 | }, 781 | scale: { 782 | 0: "0", 783 | 50: ".5", 784 | 75: ".75", 785 | 90: ".9", 786 | 95: ".95", 787 | 100: "1", 788 | 105: "1.05", 789 | 110: "1.1", 790 | 125: "1.25", 791 | 150: "1.5", 792 | }, 793 | scrollMargin: ({ theme }) => ({ 794 | ...theme("spacing"), 795 | }), 796 | scrollPadding: ({ theme }) => theme("spacing"), 797 | sepia: { 798 | 0: "0", 799 | DEFAULT: "100%", 800 | }, 801 | skew: { 802 | 0: "0deg", 803 | 1: "1deg", 804 | 2: "2deg", 805 | 3: "3deg", 806 | 6: "6deg", 807 | 12: "12deg", 808 | }, 809 | space: ({ theme }) => ({ 810 | ...theme("spacing"), 811 | }), 812 | stroke: ({ theme }) => ({ 813 | none: "none", 814 | ...theme("colors"), 815 | }), 816 | strokeWidth: { 817 | 0: "0", 818 | 1: "1", 819 | 2: "2", 820 | }, 821 | textColor: ({ theme }) => theme("colors"), 822 | textDecorationColor: ({ theme }) => theme("colors"), 823 | textDecorationThickness: { 824 | auto: "auto", 825 | "from-font": "from-font", 826 | 0: "0px", 827 | 1: "1px", 828 | 2: "2px", 829 | 4: "4px", 830 | 8: "8px", 831 | }, 832 | textUnderlineOffset: { 833 | auto: "auto", 834 | 0: "0px", 835 | 1: "1px", 836 | 2: "2px", 837 | 4: "4px", 838 | 8: "8px", 839 | }, 840 | textIndent: ({ theme }) => ({ 841 | ...theme("spacing"), 842 | }), 843 | textOpacity: ({ theme }) => theme("opacity"), 844 | transformOrigin: { 845 | center: "center", 846 | top: "top", 847 | "top-right": "top right", 848 | right: "right", 849 | "bottom-right": "bottom right", 850 | bottom: "bottom", 851 | "bottom-left": "bottom left", 852 | left: "left", 853 | "top-left": "top left", 854 | }, 855 | transitionDelay: { 856 | 75: "75ms", 857 | 100: "100ms", 858 | 150: "150ms", 859 | 200: "200ms", 860 | 300: "300ms", 861 | 500: "500ms", 862 | 700: "700ms", 863 | 1000: "1000ms", 864 | }, 865 | transitionDuration: { 866 | DEFAULT: "150ms", 867 | 75: "75ms", 868 | 100: "100ms", 869 | 150: "150ms", 870 | 200: "200ms", 871 | 300: "300ms", 872 | 500: "500ms", 873 | 700: "700ms", 874 | 1000: "1000ms", 875 | }, 876 | transitionProperty: { 877 | none: "none", 878 | all: "all", 879 | DEFAULT: 880 | "color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter", 881 | colors: "color, background-color, border-color, text-decoration-color, fill, stroke", 882 | opacity: "opacity", 883 | shadow: "box-shadow", 884 | transform: "transform", 885 | }, 886 | transitionTimingFunction: { 887 | DEFAULT: "cubic-bezier(0.4, 0, 0.2, 1)", 888 | linear: "linear", 889 | in: "cubic-bezier(0.4, 0, 1, 1)", 890 | out: "cubic-bezier(0, 0, 0.2, 1)", 891 | "in-out": "cubic-bezier(0.4, 0, 0.2, 1)", 892 | }, 893 | translate: ({ theme }) => ({ 894 | ...theme("spacing"), 895 | "1/2": "50%", 896 | "1/3": "33.333333%", 897 | "2/3": "66.666667%", 898 | "1/4": "25%", 899 | "2/4": "50%", 900 | "3/4": "75%", 901 | full: "100%", 902 | }), 903 | width: ({ theme }) => ({ 904 | auto: "auto", 905 | ...theme("spacing"), 906 | "1/2": "50%", 907 | "1/3": "33.333333%", 908 | "2/3": "66.666667%", 909 | "1/4": "25%", 910 | "2/4": "50%", 911 | "3/4": "75%", 912 | "1/5": "20%", 913 | "2/5": "40%", 914 | "3/5": "60%", 915 | "4/5": "80%", 916 | "1/6": "16.666667%", 917 | "2/6": "33.333333%", 918 | "3/6": "50%", 919 | "4/6": "66.666667%", 920 | "5/6": "83.333333%", 921 | "1/12": "8.333333%", 922 | "2/12": "16.666667%", 923 | "3/12": "25%", 924 | "4/12": "33.333333%", 925 | "5/12": "41.666667%", 926 | "6/12": "50%", 927 | "7/12": "58.333333%", 928 | "8/12": "66.666667%", 929 | "9/12": "75%", 930 | "10/12": "83.333333%", 931 | "11/12": "91.666667%", 932 | full: "100%", 933 | screen: "100vw", 934 | min: "min-content", 935 | max: "max-content", 936 | fit: "fit-content", 937 | }), 938 | willChange: { 939 | auto: "auto", 940 | scroll: "scroll-position", 941 | contents: "contents", 942 | transform: "transform", 943 | }, 944 | zIndex: { 945 | auto: "auto", 946 | 0: "0", 947 | 10: "10", 948 | 20: "20", 949 | 30: "30", 950 | 40: "40", 951 | 50: "50", 952 | }, 953 | }, 954 | variantOrder: [ 955 | "first", 956 | "last", 957 | "odd", 958 | "even", 959 | "visited", 960 | "checked", 961 | "empty", 962 | "read-only", 963 | "group-hover", 964 | "group-focus", 965 | "focus-within", 966 | "hover", 967 | "focus", 968 | "focus-visible", 969 | "active", 970 | "disabled", 971 | ], 972 | plugins: [], 973 | }; 974 | -------------------------------------------------------------------------------- /src/cli/core/ClassnamesGenerator.ts: -------------------------------------------------------------------------------- 1 | import _ from "lodash"; 2 | import { TailwindConfigParser } from "./TailwindConfigParser"; 3 | import { nonConfigurableClassNames } from "../lib/non-configurable"; 4 | import * as ClassnamesTypes from "../types/classes"; 5 | import { TConfigTheme, TConfigDarkMode } from "../types/config"; 6 | import { tailwindLabsPlugins } from "../lib/tailwindlabs-plugins"; 7 | import { regularClassGroupKeys } from "./constants/regularClassGroupKeys"; 8 | 9 | /** 10 | * Responsible for generating the types from a parsed config by ConfigScanner. 11 | */ 12 | export class ClassnamesGenerator { 13 | private readonly _prefix: string; 14 | private readonly _separator: string; 15 | private readonly _darkMode: TConfigDarkMode; 16 | private readonly _theme: Omit; 17 | private readonly _configParser: TailwindConfigParser; 18 | private readonly _generatedRegularClassnames: ClassnamesTypes.TAllClassnames; 19 | private readonly _generatedPseudoClassnames: string[]; 20 | 21 | /** 22 | * Initializes a new instance of the `ClassesGenerator` class. 23 | * @param tailwindConfig The _parsed_ TailwindCSS Config. 24 | */ 25 | constructor(parser: TailwindConfigParser) { 26 | this._configParser = parser; 27 | this._prefix = this._configParser.getPrefix(); 28 | this._separator = this._configParser.getSeparator(); 29 | this._darkMode = this._configParser.getDarkMode(); 30 | this._theme = this._configParser.getTheme(); 31 | 32 | this._generatedRegularClassnames = { 33 | Accessibility: this.accessibility(), 34 | Backgrounds: this.backgrounds(), 35 | Borders: this.borders(), 36 | Tables: this.tables(), 37 | Effects: this.effects(), 38 | TransitionsAndAnimations: this.transitionsAndAnimations(), 39 | Filters: this.filters(), 40 | FlexBox: this.flexBox(), 41 | Grid: this.grid(), 42 | Grouping: this.grouping(), 43 | Spacing: this.spacing(), 44 | Interactivity: this.interactivity(), 45 | Layout: this.layout(), 46 | Sizing: this.sizing(), 47 | SVG: this.SVG(), 48 | Transforms: this.transforms(), 49 | Typography: this.typography(), 50 | }; 51 | 52 | const configPlugins = this._configParser.getPlugins(); 53 | if (configPlugins !== null) { 54 | this._generatedRegularClassnames.TailwindLabsPlugins = {}; 55 | const { pluginCustomForms, pluginTypography } = tailwindLabsPlugins; 56 | 57 | if (!!configPlugins.pluginCustomForms) 58 | this._generatedRegularClassnames.TailwindLabsPlugins.pluginCustomForms = pluginCustomForms; 59 | 60 | if (!!configPlugins.pluginTypography) 61 | this._generatedRegularClassnames.TailwindLabsPlugins.pluginTypography = pluginTypography; 62 | } 63 | 64 | this._generatedPseudoClassnames = this.pseudoClasses(); 65 | } 66 | 67 | /** 68 | * Get the generated classnames. 69 | */ 70 | public generate = (): ClassnamesTypes.TAllClassnames => { 71 | return this._generatedRegularClassnames; 72 | }; 73 | 74 | private layout = (): ClassnamesTypes.Layout => { 75 | return { 76 | ...nonConfigurableClassNames.layout, 77 | objectPosition: Object.keys(this._theme.objectPosition).map(x => "object-" + x), 78 | inset: Object.keys(this._theme.inset).flatMap(insetValue => { 79 | return ["inset", "inset-x", "inset-y", "top", "right", "bottom", "left"].map(side => 80 | insetValue.startsWith("-") ? `-${side}-${insetValue.substring(1)}` : `${side}-${insetValue}`, 81 | ); 82 | }), 83 | zIndex: Object.keys(this._theme.zIndex).flatMap(zIndexValue => 84 | zIndexValue.startsWith("-") ? `-z-${zIndexValue.substring(1)}` : `z-${zIndexValue}`, 85 | ), 86 | aspectRatio: Object.keys(this._theme.aspectRatio).map(x => "aspect-" + x), 87 | columns: Object.keys(this._theme.columns).map(x => "columns-" + x), 88 | }; 89 | }; 90 | 91 | private grouping = (): ClassnamesTypes.Grouping => { 92 | return { 93 | group: ["group"], 94 | peer: ["peer"], 95 | }; 96 | }; 97 | 98 | private backgrounds = (): ClassnamesTypes.Backgrounds => { 99 | return { 100 | ...nonConfigurableClassNames.backgrounds, 101 | backgroundOpacity: this.getGeneratedClassesWithOpacities().backgroundOpacities, 102 | backgroundColor: this.generateClassesWithColors("backgroundColor"), 103 | backgroundPosition: Object.keys(this._theme.backgroundPosition).map(x => "bg-" + x), 104 | backgroundSize: Object.keys(this._theme.backgroundSize).map(x => "bg-" + x), 105 | backgroundImage: Object.keys(this._theme.backgroundImage).map(x => "bg-" + x), 106 | gradientColorStops: this.generateClassesWithColors("gradientColorStops").flatMap(val => 107 | ["from", "via", "to"].map(x => x + val.replace("gradient", "")), 108 | ), 109 | }; 110 | }; 111 | 112 | private borders = (): ClassnamesTypes.Borders => { 113 | return { 114 | // Add all non configurable classes in `borders` plugin. 115 | // These are utilities that their names never change e.g. border styles (dashed, solid etc.) 116 | ...nonConfigurableClassNames.borders, 117 | 118 | /* Dynamic border utils */ 119 | borderColor: this.generateClassesWithColors("borderColor"), 120 | borderOpacity: this.getGeneratedClassesWithOpacities().borderOpacities, 121 | borderRadius: Object.keys(this._theme.borderRadius).flatMap(radius => { 122 | const sides = ["t", "r", "b", "l", "tr", "tl", "br", "bl"]; 123 | return sides.map(side => `rounded-${side}-${radius}`).concat(`rounded-${radius}`); 124 | }), 125 | borderWidth: Object.keys(this._theme.borderWidth).flatMap(width => { 126 | const sides = ["t", "r", "b", "l", "x", "y"]; 127 | return sides.map(side => `border-${side}-${width}`).concat(`border-${width}`); 128 | }), 129 | /* Dynamic divide utilities */ 130 | divideColor: this.generateClassesWithColors("divideColor"), 131 | divideOpacity: this.getGeneratedClassesWithOpacities().divideOpacities, 132 | // divide width inherits its values from theme.borderWidth by default 133 | // but theme.divideWidth overrides it. 134 | divideWidth: Object.keys( 135 | _.isEmpty(this._theme.divideWidth) ? this._theme.borderWidth : this._theme.divideWidth, 136 | ) 137 | .concat("reverse") 138 | .flatMap(width => ["x", "y"].map(axis => `divide-${axis}-${width}`)), 139 | 140 | /* Dynamic ring utilities */ 141 | ringColor: this.generateClassesWithColors("ringColor"), 142 | ringWidth: Object.keys(this._theme.ringWidth) 143 | .map(x => "ring-" + x) 144 | .concat("ring-inset"), 145 | ringOpacity: this.getGeneratedClassesWithOpacities().ringOpacities, 146 | ringOffsetColor: this.generateClassesWithColors("ringOffsetColor"), 147 | ringOffsetWidth: Object.keys(this._theme.ringOffsetWidth).map(x => "ring-offset-" + x), 148 | outlineOffset: Object.keys(this._theme.outlineOffset).map(x => "outline-" + x), 149 | outlineWidth: Object.keys(this._theme.outlineWidth).flatMap(width => 150 | ["", "-"].map(direction => direction + "outline-" + width), 151 | ), 152 | outlineColor: this.generateClassesWithColors("outlineColor"), 153 | }; 154 | }; 155 | 156 | private tables = (): ClassnamesTypes.Tables => { 157 | return { 158 | ...nonConfigurableClassNames.tables, 159 | borderSpacing: ["", "-x", "-y"].flatMap(side => { 160 | return Object.keys( 161 | _.isEmpty(this._theme.borderSpacing) ? this._theme.spacing : this._theme.borderSpacing, 162 | ).map(value => `border-spacing${side}-${value}`); 163 | }), 164 | }; 165 | }; 166 | 167 | private effects = (): ClassnamesTypes.Effects => { 168 | return { 169 | ...nonConfigurableClassNames.effects, 170 | boxShadow: Object.keys(this._theme.boxShadow).map(key => `shadow-${key}`), 171 | boxShadowColor: this.generateClassesWithColors("boxShadowColor"), 172 | opacity: this.getGeneratedClassesWithOpacities().opacities, 173 | }; 174 | }; 175 | 176 | private transitionsAndAnimations = (): ClassnamesTypes.TransitionsAndAnimations => { 177 | return { 178 | ...nonConfigurableClassNames.transitionsAndAnimations, 179 | transitionProperty: Object.keys(this._theme.transitionProperty).map(property => "transition-" + property), 180 | transitionDuration: Object.keys(this._theme.transitionDuration).map(value => "duration-" + value), 181 | transitionTimingFunction: Object.keys(this._theme.transitionTimingFunction) 182 | .filter(k => k !== "DEFAULT") // The `DEFAULT` key does not correspond to a classname 183 | .map(value => "ease-" + value), 184 | transitionDelay: Object.keys(this._theme.transitionDelay).map(value => "delay-" + value), 185 | animation: Object.keys(this._theme.animation).map(val => "animate-" + val), 186 | }; 187 | }; 188 | 189 | private transforms = (): ClassnamesTypes.Transforms => { 190 | return { 191 | ...nonConfigurableClassNames.transforms, 192 | scale: ["", "x-", "y-"].flatMap(x => Object.keys(this._theme.scale).map(value => "scale-" + x + value)), 193 | rotate: Object.keys(this._theme.rotate).map(value => 194 | value.startsWith("-") ? "-rotate-" + value.slice(1) : `rotate-${value}`, 195 | ), 196 | // translate gets values from theme.spacing in addition to 50% and 100% variations 197 | // by default and theme.translate overrides this behavior. 198 | translate: ["x", "y"].flatMap(side => { 199 | return Object.keys(_.isEmpty(this._theme.translate) ? this._theme.spacing : this._theme.translate).map( 200 | value => 201 | value.startsWith("-") ? `-translate-${side}-${value.slice(1)}` : `translate-${side}-${value}`, 202 | ); 203 | }), 204 | skew: ["x", "y"].flatMap(side => 205 | Object.keys(this._theme.skew).map(value => 206 | value.startsWith("-") ? `-skew-${side}-${value.substring(1)}` : `skew-${side}-${value}`, 207 | ), 208 | ), 209 | transformOrigin: Object.keys(this._theme.transformOrigin).map(value => "origin-" + value), 210 | }; 211 | }; 212 | 213 | private interactivity = (): ClassnamesTypes.Interactivity => { 214 | const sides = ["", "y", "x", "t", "r", "b", "l"]; 215 | 216 | return { 217 | ...nonConfigurableClassNames.interactivity, 218 | cursor: Object.keys(this._theme.cursor).map(x => "cursor-" + x), 219 | caretColor: this.generateClassesWithColors("caretColor"), 220 | willChange: Object.keys(this._theme.willChange).map(x => "will-change-" + x), 221 | accentColor: this.generateClassesWithColors("accentColor"), 222 | scrollPadding: sides.flatMap(side => { 223 | return Object.keys(this._theme.scrollPadding).map(value => `scroll-p${side}-${value}`); 224 | }), 225 | scrollMargin: sides.flatMap(side => { 226 | return Object.keys(this._theme.scrollMargin).map(value => `scroll-m${side}-${value}`); 227 | }), 228 | }; 229 | }; 230 | 231 | private SVG = (): ClassnamesTypes.SVG => { 232 | return { 233 | ...nonConfigurableClassNames.svg, 234 | fill: Object.keys(this._theme.fill).map(value => "fill-" + value), 235 | stroke: Object.keys(this._theme.stroke).map(value => "stroke-" + value), 236 | strokeWidth: Object.keys(this._theme.strokeWidth).map(value => "stroke-" + value), 237 | }; 238 | }; 239 | 240 | private accessibility = (): ClassnamesTypes.Accessibility => { 241 | return { 242 | ...nonConfigurableClassNames.accessibility, 243 | }; 244 | }; 245 | 246 | private filters = (): ClassnamesTypes.Filters => { 247 | return { 248 | ...nonConfigurableClassNames.filters, 249 | blur: Object.keys(this._theme.blur).map(x => "blur-" + x), 250 | brightness: Object.keys(this._theme.brightness).map(x => "brightness-" + x), 251 | contrast: Object.keys(this._theme.contrast).map(x => "contrast-" + x), 252 | dropShadow: Object.keys(this._theme.dropShadow).map(x => "drop-shadow-" + x), 253 | grayscale: Object.keys(this._theme.grayscale).map(x => "grayscale-" + x), 254 | hueRotate: Object.keys(this._theme.hueRotate).map(x => 255 | x.startsWith("-") ? "-hue-rotate-" + x.slice(1) : "hue-rotate-" + x, 256 | ), 257 | invert: Object.keys(this._theme.invert).map(x => "invert-" + x), 258 | saturate: Object.keys(this._theme.saturate).map(x => "saturate-" + x), 259 | sepia: Object.keys(this._theme.sepia).map(x => "sepia-" + x), 260 | backdropBlur: Object.keys(this._theme.backdropBlur).map(x => "backdrop-blur-" + x), 261 | backdropBrightness: Object.keys(this._theme.backdropBrightness).map(x => "backdrop-brightness-" + x), 262 | backdropContrast: Object.keys(this._theme.backdropContrast).map(x => "backdrop-contrast-" + x), 263 | backdropGrayscale: Object.keys(this._theme.backdropGrayscale).map(x => "backdrop-grayscale-" + x), 264 | backdropHueRotate: Object.keys(this._theme.backdropHueRotate).map(x => 265 | x.startsWith("-") ? "-backdrop-hue-rotate-" + x.slice(1) : "backdrop-hue-rotate-" + x, 266 | ), 267 | backdropInvert: Object.keys(this._theme.backdropInvert).map(x => "backdrop-invert-" + x), 268 | backdropOpacity: Object.keys(this._theme.backdropOpacity).map(x => "backdrop-opacity-" + x), 269 | backdropSaturate: Object.keys(this._theme.backdropSaturate).map(x => "backdrop-saturate-" + x), 270 | backdropSepia: Object.keys(this._theme.backdropSepia).map(x => "backdrop-sepia-" + x), 271 | }; 272 | }; 273 | 274 | private flexBox = (): ClassnamesTypes.FlexBox => { 275 | return { 276 | ...nonConfigurableClassNames.flexBox, 277 | flexBasis: Object.keys(this._theme.flexBasis).map(x => `basis-${x}`), 278 | flexGrow: Object.keys(this._theme.flexGrow).map(x => `grow-${x}`), 279 | flexShrink: Object.keys(this._theme.flexShrink).map(x => `shrink-${x}`), 280 | order: Object.keys(this._theme.order).map(x => `order-${x}`), 281 | }; 282 | }; 283 | 284 | private grid = (): ClassnamesTypes.Grid => { 285 | return { 286 | ...nonConfigurableClassNames.grid, 287 | gridTemplateColumns: Object.keys(this._theme.gridTemplateColumns).map(key => `grid-cols-${key}`), 288 | gridAutoColumns: Object.keys(this._theme.gridAutoColumns).map(key => `auto-cols-${key}`), 289 | gridColumn: Object.keys(this._theme.gridColumn).map(key => `col-${key}`), 290 | gridColumnStart: Object.keys(this._theme.gridColumnStart).map(key => `col-start-${key}`), 291 | gridColumnEnd: Object.keys(this._theme.gridColumnEnd).map(key => `col-end-${key}`), 292 | gridTemplateRows: Object.keys(this._theme.gridTemplateRows).map(key => `grid-rows-${key}`), 293 | gridAutoRows: Object.keys(this._theme.gridAutoRows).map(key => `auto-rows-${key}`), 294 | gridRow: Object.keys(this._theme.gridRow).map(key => `row-${key}`), 295 | gridRowStart: Object.keys(this._theme.gridRowStart).map(key => `row-start-${key}`), 296 | gridRowEnd: Object.keys(this._theme.gridRowEnd).map(key => `row-end-${key}`), 297 | gap: ["gap-", "gap-y-", "gap-x-"].flatMap(x => { 298 | // grid gap inherits its values from theme.spacing by default, but theme.gap overrides it. 299 | return Object.keys(_.isEmpty(this._theme.gap) ? this._theme.spacing : this._theme.gap).map( 300 | gapValue => x + gapValue, 301 | ); 302 | }), 303 | }; 304 | }; 305 | 306 | private spacing = (): ClassnamesTypes.Spacing => { 307 | const sides = ["", "y", "x", "t", "r", "b", "l"]; 308 | return { 309 | padding: sides.flatMap(side => { 310 | return Object.keys(_.isEmpty(this._theme.padding) ? this._theme.spacing : this._theme.padding).map( 311 | value => (value.startsWith("-") ? `-p${side}-${value.slice(1)}` : `p${side}-${value}`), 312 | ); 313 | }), 314 | margin: sides.flatMap(side => { 315 | return Object.keys(_.isEmpty(this._theme.margin) ? this._theme.spacing : this._theme.margin).map( 316 | value => (value.startsWith("-") ? `-m${side}-${value.slice(1)}` : `m${side}-${value}`), 317 | ); 318 | }), 319 | space: ["x", "y"].flatMap(axis => { 320 | return Object.keys(_.isEmpty(this._theme.space) ? this._theme.spacing : this._theme.space) 321 | .concat("reverse") 322 | .map(key => { 323 | if (key.startsWith("-")) { 324 | key = key.slice(1); 325 | return "-space-" + axis + `-${key}`; 326 | } else { 327 | return `space-${axis}-${key}`; 328 | } 329 | }); 330 | }), 331 | }; 332 | }; 333 | 334 | private sizing = (): ClassnamesTypes.Sizing => { 335 | // prettier-ignore 336 | const extraWidthSizing = ['full', 'screen', 'auto', '1/2', '1/3', '2/3', '1/4', '2/4', '3/4', 337 | '1/5', '2/5', '3/5', '4/5', '1/6', '2/6', '3/6', '4/6', '5/6', '1/12', '2/12', '3/12', '4/12', 338 | '5/12', '6/12', '7/12', '8/12', '9/12', '10/12', '11/12']; 339 | const extraHeightSizing = ["full", "screen"]; 340 | 341 | return { 342 | ...nonConfigurableClassNames.sizing, 343 | // width values come from theme.spacing + `extraWidthSizing` by default 344 | // and theme.width overrides this default behavior. 345 | // prettier-ignore 346 | width: (_.isEmpty(this._theme.width) 347 | ? Object.keys(this._theme.spacing).concat(extraWidthSizing) 348 | : Object.keys(this._theme.width)).map(x => 'w-' + x), 349 | minWidth: Object.keys(this._theme.minWidth).map(x => "min-w-" + x), 350 | maxWidth: Object.keys(this._theme.maxWidth).map(x => "max-w-" + x), 351 | // height values come from theme.spacing + `extraHeightSizing` by default 352 | // and overridden by theme.height. 353 | // prettier-ignore 354 | height: (_.isEmpty(this._theme.height) 355 | ? Object.keys(this._theme.spacing).concat(extraHeightSizing) 356 | : Object.keys(this._theme.height)).map(x => 'h-' + x), 357 | minHeight: Object.keys(this._theme.minHeight).map(x => "min-h-" + x), 358 | maxHeight: Object.keys(this._theme.maxHeight).map(x => "max-h-" + x), 359 | }; 360 | }; 361 | 362 | private typography = (): ClassnamesTypes.Typography => { 363 | return { 364 | ...nonConfigurableClassNames.typography, 365 | fontFamily: Object.keys(this._theme.fontFamily).map(value => "font-" + value), 366 | fontSize: Object.keys(this._theme.fontSize).map(size => "text-" + size), 367 | fontWeight: Object.keys(this._theme.fontWeight).map(weight => "font-" + weight), 368 | letterSpacing: Object.keys(this._theme.letterSpacing).map(value => "tracking-" + value), 369 | lineHeight: Object.keys(this._theme.lineHeight).map(value => "leading-" + value), 370 | listStyleType: Object.keys(this._theme.listStyleType).map(value => "list-" + value), 371 | placeholderColor: this.generateClassesWithColors("placeholderColor"), 372 | placeholderOpacity: this.getGeneratedClassesWithOpacities().placeholderOpacities, 373 | textColor: this.generateClassesWithColors("textColor"), 374 | textOpacity: this.getGeneratedClassesWithOpacities().textOpacities, 375 | content: Object.keys(this._theme.content).map(x => "content-" + x), 376 | textIndent: Object.keys(this._theme.textIndent).map(x => "indent-" + x), 377 | textDecorationColor: this.generateClassesWithColors("textDecorationColor"), 378 | textDecorationThickness: Object.keys(this._theme.textDecorationThickness).map(x => "decoration-" + x), 379 | textUnderlineOffset: Object.keys(this._theme.textUnderlineOffset).map(x => "underline-offset-" + x), 380 | }; 381 | }; 382 | 383 | // Generate the types for pseudo classes as hover:, focus: etc. 384 | // and return them in a string array to be parsed and converted into a template string that 385 | // will be a part of the final generated file. See `FileContentGenerator` class. 386 | private pseudoClasses = (): string[] => { 387 | // Initialize a pseudoClasses array with base values. 388 | const pseudoClasses: string[] = ["peer", "group"]; 389 | if (this._darkMode === "class") pseudoClasses.push("dark"); 390 | 391 | // Get the variants from config 392 | const variants = this._configParser.getVariants(); 393 | 394 | for (const regularClassGroupKey of regularClassGroupKeys) { 395 | Object.keys(this._generatedRegularClassnames).map(key => { 396 | // If the current key is found to be a member of the generated regular classes group... 397 | if ( 398 | _.has( 399 | this._generatedRegularClassnames[key as keyof ClassnamesTypes.TAllClassnames], 400 | regularClassGroupKey, 401 | ) 402 | ) { 403 | // Get the value of the found generated class group 404 | let generatedClassGroup = _.get( 405 | this._generatedRegularClassnames, 406 | `${key}.${regularClassGroupKey}`, 407 | ) as unknown as string[]; 408 | 409 | // Duplicate classnames with an important (!) prefix 410 | const generatedClassGroupWithImportantPrefix = generatedClassGroup.map(cls => "!" + cls); 411 | // Append the classnames with important prefix to the regular classnames 412 | generatedClassGroup = generatedClassGroup.concat(generatedClassGroupWithImportantPrefix); 413 | // Append the classnames with important prefix to the pseudo classes array 414 | generatedClassGroupWithImportantPrefix.map(cls => pseudoClasses.push(cls)); 415 | 416 | // For every member of the found regular classes group... 417 | generatedClassGroup.map(classname => { 418 | // Generate the classname of each variant... 419 | variants.map(variant => { 420 | // Append the variant to the classname and push to the pseudoClasses array. 421 | pseudoClasses.push(variant + this._separator + this._prefix + classname); 422 | }); 423 | }); 424 | } 425 | }); 426 | } 427 | 428 | // After all is done, return the generated pseudo classes types array 429 | return pseudoClasses; 430 | }; 431 | 432 | private generateClassesWithColors = (property: ClassesWithColors): string[] => { 433 | // Get the key-value pairs of the passed property 434 | const [propertyKeys, propertyValues] = this._configParser.getThemeProperty(property); 435 | 436 | // Convert the config property names into utility class names 437 | const utilName = property 438 | .replace("Color", "") // gradientColorStops -> gradientStops, borderColor -> border etc. 439 | .replace("Stops", "") // gradientStops -> gradient 440 | .replace("ringOffset", "ring-offset") 441 | .replace("boxShadow", "shadow") 442 | .replace("textDecoration", "decoration") 443 | .replace("background", "bg"); 444 | 445 | const classnamesWithColors = propertyKeys 446 | // For every key of the property... 447 | .flatMap((colorName, i) => { 448 | // Exclude `DEFAULT` keys from the keys collection as they do not correspond to any classname. 449 | if (propertyKeys[i] === "DEFAULT") return null; 450 | 451 | // Get the value that corresponds to that key. NOTE: It can be `string` or an `object` of shades. 452 | const colorValue = propertyValues[i]; 453 | 454 | // If the value is a nested object of color shades... 455 | if (typeof colorValue === "object" && colorValue !== null) { 456 | // Loop over the deep objects and return the result for each key of the object. 457 | return Object.keys(colorValue).flatMap(shade => { 458 | if (utilName === "border") { 459 | return ["", "t", "r", "b", "l", "x", "y"].map( 460 | side => `${utilName}-${side.length > 0 ? side + "-" : ""}${colorName}-${shade}`, 461 | ); 462 | } else { 463 | return `${utilName}-${colorName}-${shade}`; 464 | } 465 | }); 466 | } 467 | // Otherwise... 468 | else { 469 | // Return the result of merging the utility name with color value 470 | if (utilName === "border") { 471 | return ["", "t", "r", "b", "l"].map( 472 | side => `${utilName}-${side.length > 0 ? side + "-" : ""}${colorName}`, 473 | ); 474 | } else { 475 | return `${utilName}-${colorName}`; 476 | } 477 | } 478 | }) 479 | .filter(Boolean) as string[]; 480 | 481 | // // Add the opacities short hand suffix `/{opacity}`: "bg-red-100/50" 482 | // const classnamesWithColorsAndOpacitySuffix = Object.keys( 483 | // this._configParser.getTheme().opacity, 484 | // ).flatMap(op => classnamesWithColors.map(cls => cls + '/' + op)); 485 | 486 | return classnamesWithColors; 487 | }; 488 | 489 | private getGeneratedClassesWithOpacities = (): ClassesWithOpacities => { 490 | const allOpacities = this._configParser.getTheme().opacity; 491 | 492 | // prettier-ignore 493 | type TOpacityProp = | 'divideOpacity' | 'textOpacity' | 'backgroundOpacity' 494 | | 'borderOpacity' | 'placeholderOpacity' | 'ringOpacity' 495 | const getOpacity = (themePropertyName: TOpacityProp, outputNamePrefix: string): string[] => { 496 | const generatedOpacities = generateOpacities(allOpacities, this._theme, themePropertyName); 497 | 498 | return Object.keys(generatedOpacities).map(opacity => `${outputNamePrefix}-opacity-${opacity}`); 499 | }; 500 | 501 | function generateOpacities( 502 | defaultOpacities: Record, 503 | theme: TConfigTheme, 504 | property: keyof Omit, 505 | ): Record { 506 | const themeOpacities = _.isEmpty(theme[property]) ? defaultOpacities : theme[property]; 507 | const extendedThemeOpacities = theme.extend?.[property]; 508 | const result = extendedThemeOpacities ? { ...themeOpacities, ...extendedThemeOpacities } : themeOpacities; 509 | 510 | return result as Record; 511 | } 512 | 513 | return { 514 | opacities: Object.keys(allOpacities).map(opacity => `opacity-${opacity}`), 515 | textOpacities: getOpacity("textOpacity", "text"), 516 | backgroundOpacities: getOpacity("backgroundOpacity", "bg"), 517 | borderOpacities: getOpacity("borderOpacity", "border"), 518 | divideOpacities: getOpacity("divideOpacity", "divide"), 519 | placeholderOpacities: getOpacity("placeholderOpacity", "placeholder"), 520 | ringOpacities: getOpacity("ringOpacity", "ring"), 521 | }; 522 | }; 523 | } 524 | 525 | type ClassesWithColors = 526 | | "caretColor" 527 | | "backgroundColor" 528 | | "divideColor" 529 | | "placeholderColor" 530 | | "textColor" 531 | | "borderColor" 532 | | "ringColor" 533 | | "ringOffsetColor" 534 | | "gradientColorStops" 535 | | "boxShadowColor" 536 | | "outlineColor" 537 | | "textDecorationColor" 538 | | "accentColor"; 539 | 540 | type ClassesWithOpacities = { 541 | opacities: string[]; 542 | textOpacities: string[]; 543 | backgroundOpacities: string[]; 544 | borderOpacities: string[]; 545 | divideOpacities: string[]; 546 | placeholderOpacities: string[]; 547 | ringOpacities: string[]; 548 | }; 549 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ## [3.2.0](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v3.1.0...v3.2.0) (2025-05-03) 6 | 7 | 8 | ### Features 9 | 10 | * add aria, layout, flexblox & typography classnames ([f95730a](https://github.com/muhammadsammy/tailwindcss-classnames/commit/f95730aaa2a7fbea1fe4754dc34f7a0bb3993593)) 11 | 12 | 13 | ### Bug Fixes 14 | 15 | * linting errors ([cfbae92](https://github.com/muhammadsammy/tailwindcss-classnames/commit/cfbae922c359418c66d24f6b63e015ca1f466304)) 16 | 17 | ## [3.1.0](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v3.0.7...v3.1.0) (2023-05-21) 18 | 19 | ### Features 20 | 21 | - add `backdrop`, `enabled` and `optional` variants ([a1c57e5](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/a1c57e511e0dcb38fd6ccccbe3f19473d35c53ce)) 22 | - add `contrast-more` and `contrast-less` variants ([8720a8b](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/8720a8b62dab95de067a2c0618ed7c19256c4451)) 23 | - add `grid-flow-dense` utility ([f70f2eb](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/f70f2eb4b9d46acc99f11ef6135fb2ad0f7dbf78)) 24 | - add `mix-blend-plus-lighter` utility ([edcfdca](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/edcfdca123ca964e67b7611e27cbd30d137f9063)) 25 | - add new `border-spacing` utilities ([4ab9a62](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/4ab9a62eea8db3b7b0f5e01e3e43fda27d486e39)) 26 | - add`text-start` and `text-end` utilities ([f6955a0](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/f6955a0ee1c01f840bd3ed21867a8258b075b5f8)) 27 | - support customizing class name when using darkMode: 'class' (fixes [#398](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/398)) ([853e7d3](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/853e7d327d3e47364ff2479341a23389f43bf778)) 28 | 29 | ### Bug Fixes 30 | 31 | - rename colors import in updateDefaultConfig script ([7de09c6](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/7de09c6efa8ca0fdbd8e67120f099d495f8c7120)) 32 | 33 | ### [3.0.7](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v3.0.6...v3.0.7) (2022-11-02) 34 | 35 | ### Bug Fixes 36 | 37 | - add basic group and peer helpers ([#446](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/446)) ([036e5c8](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/036e5c8000ccec7febe35c28a57f34b689569b79)) 38 | 39 | ### [3.0.6](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v3.0.5...v3.0.6) (2022-08-15) 40 | 41 | ### Bug Fixes 42 | 43 | - add missing main categories utility functions ([#439](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/439)) ([b5c4d15](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/b5c4d152942ad46b74ac501cb03f6702cd94802e)) 44 | 45 | ### [3.0.5](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v3.0.4...v3.0.5) (2022-05-10) 46 | 47 | ### Bug Fixes 48 | 49 | - adds proper indexing when generating colors ([#412](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/412)) ([0e500b6](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/0e500b6b6b44bec35f50fd49d5dfee51fcb899fd)) 50 | 51 | ### [3.0.4](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v3.0.3...v3.0.4) (2022-04-09) 52 | 53 | ### Bug Fixes 54 | 55 | - support darkMode manual 'class' option ([#399](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/399)) ([7cd6881](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/7cd6881a4b97980bddb72ea17427c3e8dd5b0586)) 56 | 57 | ### [3.0.3](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v3.0.2...v3.0.3) (2022-03-17) 58 | 59 | ### Bug Fixes 60 | 61 | - use correct prefix for ring-inset class ([#390](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/390)) ([22b0be9](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/22b0be9e9ad1532e09fb8cdabf0adffa30f2eaa8)) 62 | 63 | ### [3.0.2](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v3.0.1...v3.0.2) (2022-01-14) 64 | 65 | ### Bug Fixes 66 | 67 | - generate new lib classnames ([bc47da3](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/bc47da3288e7a2784f5ed21abe2494ae7a609376)) 68 | - pin colors package to 1.4.0 (fixes [#362](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/362)) ([e8132b4](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/e8132b40449ad85f3eee99a3c8b34d0dd4877f54)) 69 | 70 | ### [3.0.1](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v3.0.0...v3.0.1) (2021-12-24) 71 | 72 | ### Bug Fixes 73 | 74 | - add missing RTL and LTR modifiers ([5e9a353](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/5e9a353777dce6815f820c75ca55997c1900ce83)) 75 | 76 | ## [3.0.0](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.2.6...v3.0.0) (2021-12-17) 77 | 78 | ### ⚠ BREAKING CHANGES 79 | 80 | - rename overflow-clip & overflow-ellipsis to text-clip & text-ellipsis 81 | 82 | ### Features 83 | 84 | - add `placeholder` variant ([866ac55](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/866ac553037e8d1a5955fe33120641b478ec3b3d)), closes [#338](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/338) 85 | - add `border-hidden` utility ([df94219](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/df9421930de9eb05a3407cd61511d65425f54a27)), closes [#335](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/335) 86 | - add `border-x` and `border-y` width and color utilities ([c702c46](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/c702c46554722b379e61c430e096e9e4b136279e)), closes [#334](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/334) 87 | - add `file` variant for `::file-selector-button` pseudo element ([d51fe20](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/d51fe2098e9efda2dc4cf81a4a6e17fcde7d55a4)), closes [#339](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/339) 88 | - add `grow-*` and `shrink-*` utilities, deprecate `flex-grow-*` and `flex-shrink-*` ([73ee65d](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/73ee65da78250866dfef4bbb1275b7737bc07ace)), closes [#333](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/333) 89 | - add `open` variant ([b261695](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/b261695fb46a71f3efcabb7a423ab35a44af5eb3)), closes [#341](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/341) 90 | - add `overflow-clip`, `overflow-x-clip` and `overflow-y-clip` utilities ([f0c23ec](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/f0c23ecec81594a746f2779188fe4f74539707ce)), closes [#336](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/336) 91 | - add `print` variant for targeting printed media ([0a1be3d](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/0a1be3d95ccdca5bdbf77201fd2f5846fd59f8ca)), closes [#337](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/337) 92 | - add `scroll-behavior` utilities ([c51e665](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/c51e66534cde1c44c90f1edd95485a2e7ef2bbef)), closes [#330](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/330) 93 | - add `scroll-margin` and `scroll-padding` utilities ([e3503e9](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/e3503e9618f6231166606ef8a05920ffff63239a)) 94 | - add `scroll-snap` utilities ([e7d5070](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/e7d5070b0008fa109389e09974cb5deb7dc0990f)), closes [#329](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/329) 95 | - add `touch-action` utilities ([2d695e4](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/2d695e47fa3daff626e89fd0b9fe22d4aec08096)), closes [#331](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/331) 96 | - add classnames with important modifiers to utility functions ([02a3555](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/02a3555c7434089690dcf25c05082dbae0b35b33)) 97 | - add colored box shadow utilities ([b92a42a](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/b92a42ada7dce1b67fc57314cec79c27abb41e55)), closes [#318](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/318) 98 | - add flex basis utilites (closes [#332](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/332)) ([8e900bb](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/8e900bbd2f45dbbe66e52ece6363d02dccb9435c)) 99 | - add new layout and typography utilities ([c5e839e](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/c5e839e561c9ed813e0d19c25689b90ce8b1ef0f)) 100 | - add new outline utilites ([07da44a](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/07da44a4a61aebae4f1a7940986b1e58b8b80775)) 101 | - add portrait and landscape variants ([f89ec5a](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/f89ec5a9e4fddac060d1a4429aa1984a5ca37ac8)), closes [#340](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/340) 102 | - add pseudoclassnames to their category function ([224fb7a](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/224fb7a08dd0897cb93d218750d74f6c12ff44e1)) 103 | - add variants to the cli as it's removed from the new config ([2bef20c](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/2bef20c57752554ee7e89e908cf7ce414f2de39a)) 104 | - **cli:** generate per-category classnames ([805396f](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/805396ff6c149154c3860cf9b32f24f18f514f79)) 105 | - enable jit features all the time ([84f281b](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/84f281b08d70954fdbd4523bb2a5a81f46b8f193)) 106 | - generate utility function for all category types ( [#293](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/293)) ([1fa8a9b](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/1fa8a9b96ec543641da63a3fd0aa444310f8b6f0)) 107 | - generate utility functions for subcategories instead of categories ([9486398](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/9486398483b5ca24b683637d93ea2031b566ce18)) 108 | - rename `decoration-slice` and `decoration-break` to `box-decoration-*` ([543e868](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/543e8682ab74e6ffdd3989cf6446e690cbc50180)), closes [#344](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/344) 109 | - rename overflow-clip & overflow-ellipsis to text-clip & text-ellipsis ([050b6e4](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/050b6e46740e56ad4f8a1d657a861c56d5813a16)) 110 | - support `accent-color` utilities ([b343833](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/b34383362eb67fa5bae83bd745bfd78f874e53bc)), closes [#328](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/328) 111 | - support `will-change` utilities ([0033a52](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/0033a52a45dc9e62c54443fef5af1c61069a856f)), closes [#343](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/343) 112 | - update config closure evaluator to evaluate new tailwind3 configs ([440c1ed](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/440c1ed7cc5790a6a112e267955de073f7f6b1a1)) 113 | 114 | ### Bug Fixes 115 | 116 | - disable duplicate breakpoint pseudoclass variants generation ([912519a](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/912519aae83a86fbd6b389b3aa6dd87674bffa62)) 117 | - generate correct module exports ([3fac1c1](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/3fac1c1381a7e9d4599229ae5ab3a6c9044368d2)) 118 | - pass the parser into the fileContentGenerator instead of prefix ([bce47a8](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/bce47a815bdab3b6c9675ae80611cf5f18235611)) 119 | - use correct condition for adding a dark mode variant ([82cadf0](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/82cadf0a9ea693307db2789de9b0c0391175a025)) 120 | 121 | ### Performance Improvements 122 | 123 | - disable JIT opacity prefix feature ([e2d9673](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/e2d9673b119c436f669693a42a702d8dc7ce9b82)) 124 | - use TS template literal types to generate pseudoclassess types ([e614729](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/e614729448a3b75621a6ad2f1ab84d56c671aaf2)) 125 | 126 | ### [2.2.6](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.2.5...v2.2.6) (2021-12-07) 127 | 128 | ### Bug Fixes 129 | 130 | - **flexbox:** add 'justify-evenly' ([#312](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/312)) ([e2d21ed](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/e2d21ed67bce12334dadb8e121a4536402e493a5)) 131 | 132 | ### [2.2.5](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.2.4...v2.2.5) (2021-10-15) 133 | 134 | ### Bug Fixes 135 | 136 | - stop using default config when input arg is provided ([#290](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/290)) ([#291](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/291)) ([a25a815](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/a25a815528a31b0f636c69c50e2f1f9be557eef4)) 137 | 138 | ### [2.2.4](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.2.3...v2.2.4) (2021-10-07) 139 | 140 | ### Bug Fixes 141 | 142 | - add condition when generating backdropHueRotate ([9557847](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/9557847dda6362de0e1ed01f467c56365591f17c)) 143 | - add condition when generating borderColor ([3192ea8](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/3192ea8c135d71ab3b14dc50e1259cbd2c889c7e)) 144 | - add condition when generating hueRotate ([89c0b2e](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/89c0b2ea44033f029bf71c24bb75ed0400232f52)) 145 | 146 | ### [2.2.3](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.2.2...v2.2.3) (2021-07-21) 147 | 148 | ### Bug Fixes 149 | 150 | - generate lib types ([4df5f06](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/4df5f06ef8a4215142d84b5e2d9341904c7f4dcd)) 151 | 152 | ### [2.2.2](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.2.1...v2.2.2) (2021-07-21) 153 | 154 | ### Bug Fixes 155 | 156 | - add `self-baseline` utility ([6f3a05f](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/6f3a05fc2cf4aaa3a4f38c43ce5540e83c9c1b8b)) 157 | 158 | ### [2.2.1](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.2.0...v2.2.1) (2021-06-23) 159 | 160 | ### Bug Fixes 161 | 162 | - generate lib types ([d4bc700](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/d4bc7000108c9825cd64c1e0f65f8761f2e018bf)) 163 | 164 | ## [2.2.0](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.1.3...v2.2.0) (2021-06-23) 165 | 166 | ### Features 167 | 168 | - add 'content' utilities in JIT mode ([47c04bd](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/47c04bdd6605c4cb5bddad926744554b046f87ea)) 169 | - add blur-none by default (Closes [#230](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/230)) ([7d317b7](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/7d317b72d11e65152a3599137da9345d812e2ea9)) 170 | - add caret-color utilities ([5ecbcf3](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/5ecbcf35557db4d93865b0d94a835de2fc7cdd09)), closes [#235](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/235) 171 | - add exhaustive pseudo-class and pseudo-element variant support ([#252](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/252)) ([9cb18e6](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/9cb18e6bc190aeb51fa60d8dd77ef11e0bb4c118)) 172 | - add per-side border color utilities for JIT mode enabled configs ([6ec97b9](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/6ec97b9151257094e07bf0c66cfe9c49bc5edf65)) 173 | - add support for the new background origin utils ([2bc9840](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/2bc98406f9a864dfb211e3692dd65de623aaf127)), closes [#241](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/241) 174 | - add universal shorthand color opacity syntax ([38f27dd](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/38f27ddebe1690fcd74256723489b2d19187874c)) 175 | 176 | ### Bug Fixes 177 | 178 | - add missing classnames that does not have the opacity short hand suffix ([a48e16b](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/a48e16b0b6165f53578a6ee884b7e1a2b3157284)) 179 | - only generate classnames opacity short hand when JIT mode is enabled ([75902d9](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/75902d90c58f12d810befd51dfef650cc41d9a33)) 180 | 181 | ### [2.1.3](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.1.2...v2.1.3) (2021-05-19) 182 | 183 | ### Bug Fixes 184 | 185 | - Fixed issues with theme.extend configurations are ignored for specific properties ([c780aaa](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/c780aaa4bd7c109a5d1b5de1c80ca41415a7d220)) 186 | 187 | ### [2.1.2](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.1.1...v2.1.2) (2021-05-06) 188 | 189 | ### Bug Fixes 190 | 191 | - **performance:** using clsx in place of classnames package ([611a0f4](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/611a0f4dda143f812f2bfaf00ca8b02864321547)), closes [#126](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/126) 192 | 193 | ### [2.1.1](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.1.0...v2.1.1) (2021-04-28) 194 | 195 | ### Bug Fixes 196 | 197 | - pseudoClasses formatted incorrectly with prefix ([#213](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/213)) ([240476d](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/240476d4dbbcf7ba6f081a68968698010766790b)) 198 | 199 | ## [2.1.0](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.0.7...v2.1.0) (2021-04-11) 200 | 201 | ### Features 202 | 203 | - **jit:** generate important (!) modifier before classnames ([9a3b64f](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/9a3b64fdaf5f9f103f7eae3e3155c307c6819b15)) 204 | - add `box-decoration-break` utilities ([65416ca](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/65416caa3491fc2da71118f187aed726e961762c)), closes [#193](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/193) 205 | - add `isolation` utilities ([0529a87](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/0529a873e726ca9927ab3e742dbd8bac215288d7)), closes [#194](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/194) 206 | - add `mix-blend-mode` and `background-blend-mode` utilities ([#200](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/200)) ([a6c8e87](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/a6c8e87659eca548c5f3c6a7b47eae02aa6ccf37)), closes [#195](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/195) 207 | - add CSS Filters classnames ([#198](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/198)) ([84a8c48](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/84a8c4832877ceda1609b2b5d1daa08d92d3cfe9)) 208 | - add support for display : `inline-table`, `list-item` utilities ([6a500af](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/6a500afb4f4a491bdc2ff5f558af53128038cbcb)), closes [#192](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/192) 209 | - generate all variants when JIT mode is enabled ([c95cef5](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/c95cef51e9bba5d11591692adf5183e0b183c158)) 210 | 211 | ### [2.0.7](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.0.6...v2.0.7) (2021-02-25) 212 | 213 | ### Bug Fixes 214 | 215 | - add missing `process` global to the node vm context ([0e401e3](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/0e401e3f0633282e19dfc5fe6274538072719a7a)) 216 | 217 | ### [2.0.6](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v2.0.5...v2.0.6) (2021-02-24) 218 | 219 | ### Bug Fixes 220 | 221 | - make a workaround for config relative imports issues ([#170](https://github.com/muhammadsammy/tailwindcss-classnames/issues/170)) ([e1abd7c](https://github.com/muhammadsammy/tailwindcss-classnames/commit/e1abd7c7a538fe880c8e4342f2c0d575575c5f2a)) 222 | 223 | ### [2.0.5](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.0.4...v2.0.5) (2021-02-23) 224 | 225 | ### Bug Fixes 226 | 227 | - generate lib types with latest changes ([0a7a654](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/0a7a6547555bd4a3c7b2bb46c69762859017dd78)) 228 | 229 | ### [2.0.4](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/v2.0.3...v2.0.4) (2021-02-20) 230 | 231 | ### ⚠ BREAKING CHANGES 232 | 233 | - rename CLI args and improve its output (resolves #116) 234 | - remove pseudoselector functions 235 | 236 | ### Features 237 | 238 | - add `max-width-prose` class (fixes [#101](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/101)) ([#113](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/113)) ([c130f57](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/c130f5780c701d7beeb444721a1a7804b49bff32)) 239 | - add `overflow-ellipsis` and `overflow-clip` utilities (close [#109](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/109)) ([d8fd228](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/d8fd22877ce6209d9a37674070a3a8f90b2b980b)) 240 | - add `transform-gpu` utility classname (closes [#110](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/110)) ([53f4973](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/53f4973e0ac0c3c77f58c5ba9be0908796ad737e)) 241 | - add compatibility with TailwindCSS v1.7 ([#32](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/32)) ([83562f3](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/83562f30fe614a1490d6f6df648f8c97530c0cee)) 242 | - add cursor-helper by default ([2fa990e](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/2fa990e6b0d20e584e26f34c202c6e08f4e7ee55)) 243 | - add default export ([4f987ec](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/4f987ecd91d197f57a86afdce847dd0ce5112acf)) 244 | - add default export ([2ffbdce](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/2ffbdceecc25dfaa1c57486a2635424dc02615f2)) 245 | - add more dark mode varints by default ([43fee47](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/43fee47a1b1a1647437be57093103921731090c4)) 246 | - add new config scales (closes [#99](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/99), [#111](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/111), [#105](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/105), [#106](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/106)) ([#114](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/114)) ([b632094](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/b632094ecfca10941a9fe3ec7a52f9b676761024)) 247 | - add ring utility classnames (closes [#97](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/97)) ([#112](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/112)) ([4b12183](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/4b1218306d52ffad856ad241df92d165f855384b)) 248 | - add theme extend values to scanned theme ([95d9d4c](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/95d9d4c9d92cefbf5be9d88c7365a57ec430b5bc)) 249 | - add types for new classes introduced in tailwindcss 1.9 ([#59](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/59)) ([823d56c](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/823d56cd8cc21ee6482e7d541e1bbeda55fd8c93)) 250 | - bump version ([987343c](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/987343c1dc25f0cc44cafc0fedb82d58e0ee70dc)) 251 | - default to disabling hover and focus variants for font weight ([c22de68](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/c22de68a86f49b7242a6b2091a1b28f387641d46)) 252 | - detect config file if it exists to avoid prompting the user (closes [#144](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/144)) ([69b7e55](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/69b7e55ca49734a62af7fa40e379a403cf9d4104)) 253 | - enable variants extention (resolves [#102](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/102)) ([380e5d7](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/380e5d7113c3f95274328bb45bce84d1b09de92b)) 254 | - generate classes with color with respect to each classes key ([d582974](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/d5829748adfbc662dea318a16d98f4c1b199c194)) 255 | - generate layout types from theme config ([d127695](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/d1276958501700a94b6230261a0f93dd41285a82)) 256 | - generate lib types with new colors, dark mode ([72bc948](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/72bc9481b51eadf5376a2e2397aceddc9683e7c1)) 257 | - generate padding, margin and space classes from theme ([8bfa8eb](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/8bfa8eb5eb71647edc3433897683e77ce4719236)) 258 | - generate sizing classes types from theme config ([35c6530](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/35c6530441386706edba23634004375f27111300)) 259 | - get theme values from closures referencing other values in config ([f10d9f9](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/f10d9f9fdc776fc47eeeef45c6cf91e9dbac21c0)) 260 | - make lib compatible with tailwindcss 1.8 ([#52](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/52)) ([664d2af](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/664d2af999e7670d7a389efc82964a95fbd24179)) 261 | - remove `clear-fix` utility from layout/float ([7556452](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/7556452bf64cc8fc3f007c506cf64b0078bff785)) 262 | - remove `scrolling-touch` and `scrolling-auto` from layout/overflow ([8e10edb](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/8e10edbb4135c6ffd350b7cdcbfcafb5957f55a2)) 263 | - remove `shadow-outline` and `shadow-xs` (closes [#92](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/92)) ([6c8db2d](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/6c8db2d8e1c2b8c171a57f23259274028f4bbf40)) 264 | - rename `whitespace-no-wrap` utility class to `whitespace-nowrap` ([dafec5d](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/dafec5de8508b1798c46eab3e5b11cfcae5e47b0)) 265 | - rename CLI args and improve its output (resolves [#116](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/116)) ([b1e5e43](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/b1e5e431753bb23415692b3630943e43ac99fa6e)) 266 | - support dark mode classes ([#67](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/67)) ([a4bcd0b](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/a4bcd0bfffd5a732af04d1f71358230398b3e5b4)) 267 | - support the new color palette by default ([6acb30b](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/6acb30bdeb505631d4d593c43f1dac4898017bb7)) 268 | - update the default tailwind config from v2 ([#115](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/115)) ([16b0b26](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/16b0b261b44622c5cb3ebe3205559ed359a76989)) 269 | - use new name for flex no wrap `flex-nowrap` ([b47865e](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/b47865ea1f86222fb531af3d81d297900d0df0e1)) 270 | - **plugins:** add typography plugin support ([#44](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/44)) ([7b8eabb](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/7b8eabbbdba03132e97bc400f0181c77a5c96cf3)) 271 | - **types:** add TKey ([#42](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/42)) ([8011ab3](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/8011ab3d279fda7920cea4c0445ae5ff977bf841)) 272 | - add classes for @tailwindcss/custom-forms plugin ([e5cb2bb](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/e5cb2bbf3016eb0976572f1b9c94fb4dc2effda3)) 273 | - add css grid properties ([6fa27aa](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/6fa27aa5df96d018598175703b0bd27ca98e5ff6)) 274 | - add flexGrow types from theme ([359a693](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/359a6932015bf2eedeafae84eb761ad00aa799fa)) 275 | - add line height classes type generation ([23d5fd0](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/23d5fd0226db4f9559e60e53533677d79a14a779)) 276 | - add order classes types generation from theme ([fd24095](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/fd24095a6e1f0fc75c66713edeae2b4bcb9314dd)) 277 | - add placeholder color and opacity types generation ([e465e89](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/e465e89411b307d8cc61c42a8eebf9669e01cd2f)) 278 | - add pre-commit hooks ([a711130](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/a7111304e56e67a1fb89fbdb6786ce663812bb0e)) 279 | - add text opacity type generation ([2239109](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/2239109c4953a40678c36f27059fc2c3dd01573d)) 280 | - add type generation for flex shrink ([d31bb56](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/d31bb56162ab6c87d7016337e3b975de3106f600)) 281 | - bump version to 1.3.6 ([0cc6858](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/0cc6858b370d004934ea228a51a1d903803cea3b)) 282 | - generat list style type types ([13289af](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/13289af34fab9fb12dabb8608cec08b271de3d16)) 283 | - generate all backgrounds-related types ([269361e](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/269361ef89da05ba1f18b912abbde06c0488acc4)) 284 | - generate border radius types from theme ([c0ae9e4](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/c0ae9e4f8e6d1ee47df36951e9abcc0151e3aef9)) 285 | - generate border width types from theme ([b733566](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/b7335661c18b508f3317699880128b51f7c0686b)) 286 | - generate divide width types from theme ([9f7df54](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/9f7df5435a1c66044a827fa1efabc52780246c16)) 287 | - generate effects types from theme ([3ceb290](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/3ceb29037a548b4c492d73a095788f4bb04b54c1)) 288 | - generate font family types ([950156d](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/950156dab0daadf1fb93fdb06751fd40fc9af1e8)) 289 | - generate font size types ([6dbd3a7](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/6dbd3a790aa9e55bad991d4b324426f7ab0f09c7)) 290 | - generate font weight types ([45ae183](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/45ae183cc9679c429930c79fdce921883faa5661)) 291 | - generate grid column start/end types ([3b90dbc](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/3b90dbc8e06c4587d2f6db981958401ec4b31bc2)) 292 | - generate grid gap types ([cb70a1a](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/cb70a1a1729c0d60b055b00520326934d553b2c4)) 293 | - generate grid row start/end types ([9a173a7](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/9a173a78ff9b85c2aec6d1f0c37259125323f9b9)) 294 | - generate grid template rows types ([da9950e](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/da9950e0a70181fd83a7ad2eef869cf5b821eb21)) 295 | - generate interactivity classes types from theme config ([7cb6062](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/7cb60626c91fe5d5fab5f796cdf870115f4c125d)) 296 | - generate letter spacing types from tailwind config ([c389a79](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/c389a79c48ee61b27752417470f2a8943b12d544)) 297 | - generate SVG types ([3ce6d80](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/3ce6d802ab3c1238202f545776c17e5584ed358f)) 298 | - generate transforms classes types from theme config ([599a2e3](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/599a2e363be1f8326e389c5bddd671dbfe818374)) 299 | - generate transition duration types from theme ([c4819e2](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/c4819e2fbeb063461d4cece547c3fcd9a0023af6)) 300 | - generate transition property types from theme ([822414c](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/822414c3e883c05dcb15b7db97db46a94b75f151)) 301 | - generate transition timing function and delay from theme ([5842b6e](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/5842b6e6c423d42c86bd7aced1639305f560b801)) 302 | - generate types for grid template columns ([8e0e5d5](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/8e0e5d51e66bf88aca8b420f5a2b1813ab9e8e6c)) 303 | - implemet importing types from external file ([7c07343](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/7c07343afdd3904ca2decdae23bd04891812a25d)) 304 | - opacity from theme ([0d10706](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/0d107061b4f2c473d2aaf5ee2f52c8b670fbfbe1)) 305 | - text-opacity support ([ae196ce](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/ae196ce285d8b07d2fcb44313647fe2e3e66103a)) 306 | 307 | ### Bug Fixes 308 | 309 | - add group prefix ([#55](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/55)) ([52f10eb](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/52f10eb13cce21eda24913fb4c8d0d624a363f17)) 310 | - add missing 'transition' type ([bf4bb5e](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/bf4bb5ed16c7a758a9f362efd8ee4b6748e47753)) 311 | - add missing generated divide color and opacity ([0d56d53](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/0d56d53d9bd75866cef77830c5cb918b94c191d6)) 312 | - add missing pseudoclasses for gap, accessiblity and inset classes ([9c7d3a3](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/9c7d3a329cf6536481e9a0e4f5ef8d2504dee2a2)) 313 | - Add missing types to cli.ts ([4caa355](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/4caa355101bf9346f0ef6930f980984d753f83b9)) 314 | - add result of property modification to returned classes with colors ([fe458c9](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/fe458c9071d2327e4b916dcf75b5a212260cf3d2)) 315 | - avoid variable shadowing ([c84c73c](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/c84c73cd6b43788bec5c18bcd59fac9922416333)) 316 | - backgrounds group memeber types references ([0b5867e](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/0b5867ec7d35014065483f43898be179866b8ce1)) 317 | - correct typo in customClassesFilename parameter name ([a0e8a3b](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/a0e8a3b116bba5aed20b231fc6e3b9ddb689b3f3)) 318 | - detect default classes from the new 'DEFAULT' string ([b14973a](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/b14973ae93996d555842cdb7a8a112db95c792ef)) 319 | - functions in theme.extend overrides the theme not extend it ([#49](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/49)) ([3be8b6f](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/3be8b6f9678e8560ee89f8b686f3ff0bdbcc11fe)) 320 | - generate actual backgrounds group memeber types ([ead0bc0](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/ead0bc0a0ac951f6ce771c09273253312da0b51e)) 321 | - generate pseudoclasses for generated classes not the default ones ([bc618aa](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/bc618aab09a7bef7b6dfe70e2c008b66e8fe813d)) 322 | - ignore default keys in transition timing function config ([5a36e8e](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/5a36e8e16608605e4c1c381915409dd2048c5feb)) 323 | - ignore idea folder ([ece221e](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/ece221eccd9323e8b8ad6c00526ab745b61ef9ae)) 324 | - prevent utility functions from mutating original theme values ([b414bf0](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/b414bf051ecd4fc143de324bf4b405d4ebd7daed)) 325 | - remove `default` suffix from all types except types known to use it ([845b9bc](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/845b9bc12a640a3709b7c596bf7c8ca55064464b)) 326 | - return evaluated theme from ConfigScanner.getThemeProperty method ([5dbb337](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/5dbb337e7518c4fc35ddbb07b62f3b615ce0a899)) 327 | - use and emit custom classes ([7fd741c](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/7fd741ca7f6a09ec653c71988f984a35a0dde869)) 328 | - **types:** add missing 'group' type for group-\* variants (fixes [#53](https://www.github.com/muhammadsammy/tailwindcss-classnames/issues/53)) ([dbf7f20](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/dbf7f2009989246eea91e587d14a248a57733258)) 329 | - **types:** group type replaces group-hover/ group-focus variants ([7381d13](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/7381d13252eb58cdc44073020856995692dfe711)) 330 | - prefix generated background position and size classes with ([f9dcd04](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/f9dcd04f29b6260fd6246919d5080de1675114e6)) 331 | - remove false positive warning message for pseudo-classes generation ([d9663d6](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/d9663d63ef5c2f86f8899ad98cdb5a806d7dde2e)) 332 | - remove hard coded values in translate generation ([5fca805](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/5fca805e28887aaecaf301647ca4b38cc11d2ca6)) 333 | - use correct lodash package imports ([3a041b3](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/3a041b3f35a7969d18cb22f92bf0d7fd7d7c67be)) 334 | - use correct prefix for font sizes types ([c5b6640](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/c5b66408a52122be70f02aa96a62660a967d49d9)) 335 | 336 | ### Code Refactoring 337 | 338 | - remove pseudoselector functions ([6c46bc5](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/6c46bc5bf3aa40994577d7ba3d11a9264e4bdc38)) 339 | 340 | ### [2.0.4](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.9.0...v2.0.4) (2021-02-20) 341 | 342 | ### ⚠ BREAKING CHANGES 343 | 344 | - rename CLI args and improve its output (resolves #116) 345 | 346 | ### Features 347 | 348 | - add `max-width-prose` class (fixes [#101](https://github.com/muhammadsammy/tailwindcss-classnames/issues/101)) ([#113](https://github.com/muhammadsammy/tailwindcss-classnames/issues/113)) ([c130f57](https://github.com/muhammadsammy/tailwindcss-classnames/commit/c130f5780c701d7beeb444721a1a7804b49bff32)) 349 | - add `overflow-ellipsis` and `overflow-clip` utilities (close [#109](https://github.com/muhammadsammy/tailwindcss-classnames/issues/109)) ([d8fd228](https://github.com/muhammadsammy/tailwindcss-classnames/commit/d8fd22877ce6209d9a37674070a3a8f90b2b980b)) 350 | - add `transform-gpu` utility classname (closes [#110](https://github.com/muhammadsammy/tailwindcss-classnames/issues/110)) ([53f4973](https://github.com/muhammadsammy/tailwindcss-classnames/commit/53f4973e0ac0c3c77f58c5ba9be0908796ad737e)) 351 | - add cursor-helper by default ([2fa990e](https://github.com/muhammadsammy/tailwindcss-classnames/commit/2fa990e6b0d20e584e26f34c202c6e08f4e7ee55)) 352 | - add more dark mode varints by default ([43fee47](https://github.com/muhammadsammy/tailwindcss-classnames/commit/43fee47a1b1a1647437be57093103921731090c4)) 353 | - add new config scales (closes [#99](https://github.com/muhammadsammy/tailwindcss-classnames/issues/99), [#111](https://github.com/muhammadsammy/tailwindcss-classnames/issues/111), [#105](https://github.com/muhammadsammy/tailwindcss-classnames/issues/105), [#106](https://github.com/muhammadsammy/tailwindcss-classnames/issues/106)) ([#114](https://github.com/muhammadsammy/tailwindcss-classnames/issues/114)) ([b632094](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b632094ecfca10941a9fe3ec7a52f9b676761024)) 354 | - add ring utility classnames (closes [#97](https://github.com/muhammadsammy/tailwindcss-classnames/issues/97)) ([#112](https://github.com/muhammadsammy/tailwindcss-classnames/issues/112)) ([4b12183](https://github.com/muhammadsammy/tailwindcss-classnames/commit/4b1218306d52ffad856ad241df92d165f855384b)) 355 | - default to disabling hover and focus variants for font weight ([c22de68](https://github.com/muhammadsammy/tailwindcss-classnames/commit/c22de68a86f49b7242a6b2091a1b28f387641d46)) 356 | - detect config file if it exists to avoid prompting the user (closes [#144](https://github.com/muhammadsammy/tailwindcss-classnames/issues/144)) ([69b7e55](https://github.com/muhammadsammy/tailwindcss-classnames/commit/69b7e55ca49734a62af7fa40e379a403cf9d4104)) 357 | - enable variants extention (resolves [#102](https://github.com/muhammadsammy/tailwindcss-classnames/issues/102)) ([380e5d7](https://github.com/muhammadsammy/tailwindcss-classnames/commit/380e5d7113c3f95274328bb45bce84d1b09de92b)) 358 | - generate lib types with new colors, dark mode ([72bc948](https://github.com/muhammadsammy/tailwindcss-classnames/commit/72bc9481b51eadf5376a2e2397aceddc9683e7c1)) 359 | - remove `clear-fix` utility from layout/float ([7556452](https://github.com/muhammadsammy/tailwindcss-classnames/commit/7556452bf64cc8fc3f007c506cf64b0078bff785)) 360 | - remove `scrolling-touch` and `scrolling-auto` from layout/overflow ([8e10edb](https://github.com/muhammadsammy/tailwindcss-classnames/commit/8e10edbb4135c6ffd350b7cdcbfcafb5957f55a2)) 361 | - remove `shadow-outline` and `shadow-xs` (closes [#92](https://github.com/muhammadsammy/tailwindcss-classnames/issues/92)) ([6c8db2d](https://github.com/muhammadsammy/tailwindcss-classnames/commit/6c8db2d8e1c2b8c171a57f23259274028f4bbf40)) 362 | - rename `whitespace-no-wrap` utility class to `whitespace-nowrap` ([dafec5d](https://github.com/muhammadsammy/tailwindcss-classnames/commit/dafec5de8508b1798c46eab3e5b11cfcae5e47b0)) 363 | - rename CLI args and improve its output (resolves [#116](https://github.com/muhammadsammy/tailwindcss-classnames/issues/116)) ([b1e5e43](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b1e5e431753bb23415692b3630943e43ac99fa6e)) 364 | - support dark mode classes ([#67](https://github.com/muhammadsammy/tailwindcss-classnames/issues/67)) ([a4bcd0b](https://github.com/muhammadsammy/tailwindcss-classnames/commit/a4bcd0bfffd5a732af04d1f71358230398b3e5b4)) 365 | - support the new color palette by default ([6acb30b](https://github.com/muhammadsammy/tailwindcss-classnames/commit/6acb30bdeb505631d4d593c43f1dac4898017bb7)) 366 | - update the default tailwind config from v2 ([#115](https://github.com/muhammadsammy/tailwindcss-classnames/issues/115)) ([16b0b26](https://github.com/muhammadsammy/tailwindcss-classnames/commit/16b0b261b44622c5cb3ebe3205559ed359a76989)) 367 | - use new name for flex no wrap `flex-nowrap` ([b47865e](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b47865ea1f86222fb531af3d81d297900d0df0e1)) 368 | 369 | ### Bug Fixes 370 | 371 | - detect default classes from the new 'DEFAULT' string ([b14973a](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b14973ae93996d555842cdb7a8a112db95c792ef)) 372 | - ignore default keys in transition timing function config ([5a36e8e](https://github.com/muhammadsammy/tailwindcss-classnames/commit/5a36e8e16608605e4c1c381915409dd2048c5feb)) 373 | - use and emit custom classes ([7fd741c](https://github.com/muhammadsammy/tailwindcss-classnames/commit/7fd741ca7f6a09ec653c71988f984a35a0dde869)) 374 | 375 | ### [2.0.3](https://www.github.com/muhammadsammy/tailwindcss-classnames/compare/2.0.1...v2.0.3) (2021-02-19) 376 | 377 | ### Features 378 | 379 | - add cursor-helper by default ([2fa990e](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/2fa990e6b0d20e584e26f34c202c6e08f4e7ee55)) 380 | - add more dark mode varints by default ([43fee47](https://www.github.com/muhammadsammy/tailwindcss-classnames/commit/43fee47a1b1a1647437be57093103921731090c4)) 381 | 382 | ### [2.0.1](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.9.0...v2.0.1) (2021-02-07) 383 | 384 | ### ⚠ BREAKING CHANGES 385 | 386 | - rename CLI args and improve its output (resolves #116) 387 | 388 | ### Features 389 | 390 | - add `max-width-prose` class (fixes [#101](https://github.com/muhammadsammy/tailwindcss-classnames/issues/101)) ([#113](https://github.com/muhammadsammy/tailwindcss-classnames/issues/113)) ([c130f57](https://github.com/muhammadsammy/tailwindcss-classnames/commit/c130f5780c701d7beeb444721a1a7804b49bff32)) 391 | - add `overflow-ellipsis` and `overflow-clip` utilities (close [#109](https://github.com/muhammadsammy/tailwindcss-classnames/issues/109)) ([d8fd228](https://github.com/muhammadsammy/tailwindcss-classnames/commit/d8fd22877ce6209d9a37674070a3a8f90b2b980b)) 392 | - add `transform-gpu` utility classname (closes [#110](https://github.com/muhammadsammy/tailwindcss-classnames/issues/110)) ([53f4973](https://github.com/muhammadsammy/tailwindcss-classnames/commit/53f4973e0ac0c3c77f58c5ba9be0908796ad737e)) 393 | - add new config scales (closes [#99](https://github.com/muhammadsammy/tailwindcss-classnames/issues/99), [#111](https://github.com/muhammadsammy/tailwindcss-classnames/issues/111), [#105](https://github.com/muhammadsammy/tailwindcss-classnames/issues/105), [#106](https://github.com/muhammadsammy/tailwindcss-classnames/issues/106)) ([#114](https://github.com/muhammadsammy/tailwindcss-classnames/issues/114)) ([b632094](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b632094ecfca10941a9fe3ec7a52f9b676761024)) 394 | - add ring utility classnames (closes [#97](https://github.com/muhammadsammy/tailwindcss-classnames/issues/97)) ([#112](https://github.com/muhammadsammy/tailwindcss-classnames/issues/112)) ([4b12183](https://github.com/muhammadsammy/tailwindcss-classnames/commit/4b1218306d52ffad856ad241df92d165f855384b)) 395 | - default to disabling hover and focus variants for font weight ([c22de68](https://github.com/muhammadsammy/tailwindcss-classnames/commit/c22de68a86f49b7242a6b2091a1b28f387641d46)) 396 | - detect config file if it exists to avoid prompting the user (closes [#144](https://github.com/muhammadsammy/tailwindcss-classnames/issues/144)) ([69b7e55](https://github.com/muhammadsammy/tailwindcss-classnames/commit/69b7e55ca49734a62af7fa40e379a403cf9d4104)) 397 | - enable variants extention (resolves [#102](https://github.com/muhammadsammy/tailwindcss-classnames/issues/102)) ([380e5d7](https://github.com/muhammadsammy/tailwindcss-classnames/commit/380e5d7113c3f95274328bb45bce84d1b09de92b)) 398 | - generate lib types with new colors, dark mode ([72bc948](https://github.com/muhammadsammy/tailwindcss-classnames/commit/72bc9481b51eadf5376a2e2397aceddc9683e7c1)) 399 | - remove `clear-fix` utility from layout/float ([7556452](https://github.com/muhammadsammy/tailwindcss-classnames/commit/7556452bf64cc8fc3f007c506cf64b0078bff785)) 400 | - remove `scrolling-touch` and `scrolling-auto` from layout/overflow ([8e10edb](https://github.com/muhammadsammy/tailwindcss-classnames/commit/8e10edbb4135c6ffd350b7cdcbfcafb5957f55a2)) 401 | - remove `shadow-outline` and `shadow-xs` (closes [#92](https://github.com/muhammadsammy/tailwindcss-classnames/issues/92)) ([6c8db2d](https://github.com/muhammadsammy/tailwindcss-classnames/commit/6c8db2d8e1c2b8c171a57f23259274028f4bbf40)) 402 | - rename `whitespace-no-wrap` utility class to `whitespace-nowrap` ([dafec5d](https://github.com/muhammadsammy/tailwindcss-classnames/commit/dafec5de8508b1798c46eab3e5b11cfcae5e47b0)) 403 | - rename CLI args and improve its output (resolves [#116](https://github.com/muhammadsammy/tailwindcss-classnames/issues/116)) ([b1e5e43](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b1e5e431753bb23415692b3630943e43ac99fa6e)) 404 | - support dark mode classes ([#67](https://github.com/muhammadsammy/tailwindcss-classnames/issues/67)) ([a4bcd0b](https://github.com/muhammadsammy/tailwindcss-classnames/commit/a4bcd0bfffd5a732af04d1f71358230398b3e5b4)) 405 | - support the new color palette by default ([6acb30b](https://github.com/muhammadsammy/tailwindcss-classnames/commit/6acb30bdeb505631d4d593c43f1dac4898017bb7)) 406 | - update the default tailwind config from v2 ([#115](https://github.com/muhammadsammy/tailwindcss-classnames/issues/115)) ([16b0b26](https://github.com/muhammadsammy/tailwindcss-classnames/commit/16b0b261b44622c5cb3ebe3205559ed359a76989)) 407 | - use new name for flex no wrap `flex-nowrap` ([b47865e](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b47865ea1f86222fb531af3d81d297900d0df0e1)) 408 | 409 | ### Bug Fixes 410 | 411 | - detect default classes from the new 'DEFAULT' string ([b14973a](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b14973ae93996d555842cdb7a8a112db95c792ef)) 412 | - ignore default keys in transition timing function config ([5a36e8e](https://github.com/muhammadsammy/tailwindcss-classnames/commit/5a36e8e16608605e4c1c381915409dd2048c5feb)) 413 | 414 | ## [2.0.0](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.9.0...v2.0.0) (2021-01-07) 415 | 416 | ### ⚠ BREAKING CHANGES 417 | 418 | - rename CLI args and improve its output (resolves #116) 419 | 420 | ### Features 421 | 422 | - add `max-width-prose` class (fixes [#101](https://github.com/muhammadsammy/tailwindcss-classnames/issues/101)) ([#113](https://github.com/muhammadsammy/tailwindcss-classnames/issues/113)) ([c130f57](https://github.com/muhammadsammy/tailwindcss-classnames/commit/c130f5780c701d7beeb444721a1a7804b49bff32)) 423 | - add `overflow-ellipsis` and `overflow-clip` utilities (close [#109](https://github.com/muhammadsammy/tailwindcss-classnames/issues/109)) ([d8fd228](https://github.com/muhammadsammy/tailwindcss-classnames/commit/d8fd22877ce6209d9a37674070a3a8f90b2b980b)) 424 | - add `transform-gpu` utility classname (closes [#110](https://github.com/muhammadsammy/tailwindcss-classnames/issues/110)) ([53f4973](https://github.com/muhammadsammy/tailwindcss-classnames/commit/53f4973e0ac0c3c77f58c5ba9be0908796ad737e)) 425 | - add new config scales (closes [#99](https://github.com/muhammadsammy/tailwindcss-classnames/issues/99), [#111](https://github.com/muhammadsammy/tailwindcss-classnames/issues/111), [#105](https://github.com/muhammadsammy/tailwindcss-classnames/issues/105), [#106](https://github.com/muhammadsammy/tailwindcss-classnames/issues/106)) ([#114](https://github.com/muhammadsammy/tailwindcss-classnames/issues/114)) ([b632094](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b632094ecfca10941a9fe3ec7a52f9b676761024)) 426 | - add ring utility classnames (closes [#97](https://github.com/muhammadsammy/tailwindcss-classnames/issues/97)) ([#112](https://github.com/muhammadsammy/tailwindcss-classnames/issues/112)) ([4b12183](https://github.com/muhammadsammy/tailwindcss-classnames/commit/4b1218306d52ffad856ad241df92d165f855384b)) 427 | - default to disabling hover and focus variants for font weight ([c22de68](https://github.com/muhammadsammy/tailwindcss-classnames/commit/c22de68a86f49b7242a6b2091a1b28f387641d46)) 428 | - enable variants extention (resolves [#102](https://github.com/muhammadsammy/tailwindcss-classnames/issues/102)) ([380e5d7](https://github.com/muhammadsammy/tailwindcss-classnames/commit/380e5d7113c3f95274328bb45bce84d1b09de92b)) 429 | - generate lib types with new colors, dark mode ([72bc948](https://github.com/muhammadsammy/tailwindcss-classnames/commit/72bc9481b51eadf5376a2e2397aceddc9683e7c1)) 430 | - remove `clear-fix` utility from layout/float ([7556452](https://github.com/muhammadsammy/tailwindcss-classnames/commit/7556452bf64cc8fc3f007c506cf64b0078bff785)) 431 | - remove `scrolling-touch` and `scrolling-auto` from layout/overflow ([8e10edb](https://github.com/muhammadsammy/tailwindcss-classnames/commit/8e10edbb4135c6ffd350b7cdcbfcafb5957f55a2)) 432 | - remove `shadow-outline` and `shadow-xs` (closes [#92](https://github.com/muhammadsammy/tailwindcss-classnames/issues/92)) ([6c8db2d](https://github.com/muhammadsammy/tailwindcss-classnames/commit/6c8db2d8e1c2b8c171a57f23259274028f4bbf40)) 433 | - rename `whitespace-no-wrap` utility class to `whitespace-nowrap` ([dafec5d](https://github.com/muhammadsammy/tailwindcss-classnames/commit/dafec5de8508b1798c46eab3e5b11cfcae5e47b0)) 434 | - rename CLI args and improve its output (resolves [#116](https://github.com/muhammadsammy/tailwindcss-classnames/issues/116)) ([b1e5e43](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b1e5e431753bb23415692b3630943e43ac99fa6e)) 435 | - support dark mode classes ([#67](https://github.com/muhammadsammy/tailwindcss-classnames/issues/67)) ([a4bcd0b](https://github.com/muhammadsammy/tailwindcss-classnames/commit/a4bcd0bfffd5a732af04d1f71358230398b3e5b4)) 436 | - support the new color palette by default ([6acb30b](https://github.com/muhammadsammy/tailwindcss-classnames/commit/6acb30bdeb505631d4d593c43f1dac4898017bb7)) 437 | - update the default tailwind config from v2 ([#115](https://github.com/muhammadsammy/tailwindcss-classnames/issues/115)) ([16b0b26](https://github.com/muhammadsammy/tailwindcss-classnames/commit/16b0b261b44622c5cb3ebe3205559ed359a76989)) 438 | - use new name for flex no wrap `flex-nowrap` ([b47865e](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b47865ea1f86222fb531af3d81d297900d0df0e1)) 439 | 440 | ### Bug Fixes 441 | 442 | - detect default classes from the new 'DEFAULT' string ([b14973a](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b14973ae93996d555842cdb7a8a112db95c792ef)) 443 | - ignore default keys in transition timing function config ([5a36e8e](https://github.com/muhammadsammy/tailwindcss-classnames/commit/5a36e8e16608605e4c1c381915409dd2048c5feb)) 444 | 445 | ## [1.9.0](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.8.3...v1.9.0) (2020-10-18) 446 | 447 | ### Features 448 | 449 | - add types for new classes introduced in tailwindcss 1.9 ([#59](https://github.com/muhammadsammy/tailwindcss-classnames/issues/59)) ([823d56c](https://github.com/muhammadsammy/tailwindcss-classnames/commit/823d56cd8cc21ee6482e7d541e1bbeda55fd8c93)) 450 | 451 | ### Bug Fixes 452 | 453 | - return evaluated theme from ConfigScanner.getThemeProperty method ([5dbb337](https://github.com/muhammadsammy/tailwindcss-classnames/commit/5dbb337e7518c4fc35ddbb07b62f3b615ce0a899)) 454 | 455 | ### [1.8.3](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.8.2...v1.8.3) (2020-09-20) 456 | 457 | ### Bug Fixes 458 | 459 | - add group prefix ([#55](https://github.com/muhammadsammy/tailwindcss-classnames/issues/55)) ([52f10eb](https://github.com/muhammadsammy/tailwindcss-classnames/commit/52f10eb13cce21eda24913fb4c8d0d624a363f17)) 460 | - remove `default` suffix from all types except types known to use it ([845b9bc](https://github.com/muhammadsammy/tailwindcss-classnames/commit/845b9bc12a640a3709b7c596bf7c8ca55064464b)) 461 | 462 | ### [1.8.2](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.8.1...v1.8.2) (2020-09-15) 463 | 464 | ### Bug Fixes 465 | 466 | - **types:** group type replaces group-hover/ group-focus variants ([7381d13](https://github.com/muhammadsammy/tailwindcss-classnames/commit/7381d13252eb58cdc44073020856995692dfe711)) 467 | 468 | ### [1.8.1](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.6.1...v1.8.1) (2020-09-15) 469 | 470 | ### Features 471 | 472 | - make lib compatible with tailwindcss 1.8 ([#52](https://github.com/muhammadsammy/tailwindcss-classnames/issues/52)) ([664d2af](https://github.com/muhammadsammy/tailwindcss-classnames/commit/664d2af999e7670d7a389efc82964a95fbd24179)) 473 | - **plugins:** add typography plugin support ([#44](https://github.com/muhammadsammy/tailwindcss-classnames/issues/44)) ([7b8eabb](https://github.com/muhammadsammy/tailwindcss-classnames/commit/7b8eabbbdba03132e97bc400f0181c77a5c96cf3)) 474 | - **types:** add TKey ([#42](https://github.com/muhammadsammy/tailwindcss-classnames/issues/42)) ([8011ab3](https://github.com/muhammadsammy/tailwindcss-classnames/commit/8011ab3d279fda7920cea4c0445ae5ff977bf841)) 475 | 476 | ### Bug Fixes 477 | 478 | - **types:** add missing 'group' type for group-\* variants (fixes [#53](https://github.com/muhammadsammy/tailwindcss-classnames/issues/53)) ([dbf7f20](https://github.com/muhammadsammy/tailwindcss-classnames/commit/dbf7f2009989246eea91e587d14a248a57733258)) 479 | - add missing 'transition' type ([bf4bb5e](https://github.com/muhammadsammy/tailwindcss-classnames/commit/bf4bb5ed16c7a758a9f362efd8ee4b6748e47753)) 480 | - functions in theme.extend overrides the theme not extend it ([#49](https://github.com/muhammadsammy/tailwindcss-classnames/issues/49)) ([3be8b6f](https://github.com/muhammadsammy/tailwindcss-classnames/commit/3be8b6f9678e8560ee89f8b686f3ff0bdbcc11fe)) 481 | 482 | ## [1.8.0](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.6.1...v1.8.0) (2020-09-14) 483 | 484 | ### Features 485 | 486 | - make lib compatible with tailwindcss 1.8 ([#52](https://github.com/muhammadsammy/tailwindcss-classnames/issues/52)) ([664d2af](https://github.com/muhammadsammy/tailwindcss-classnames/commit/664d2af999e7670d7a389efc82964a95fbd24179)) 487 | - **plugins:** add typography plugin support ([#44](https://github.com/muhammadsammy/tailwindcss-classnames/issues/44)) ([7b8eabb](https://github.com/muhammadsammy/tailwindcss-classnames/commit/7b8eabbbdba03132e97bc400f0181c77a5c96cf3)) 488 | - **types:** add TKey ([#42](https://github.com/muhammadsammy/tailwindcss-classnames/issues/42)) ([8011ab3](https://github.com/muhammadsammy/tailwindcss-classnames/commit/8011ab3d279fda7920cea4c0445ae5ff977bf841)) 489 | 490 | ### Bug Fixes 491 | 492 | - add missing 'transition' type ([bf4bb5e](https://github.com/muhammadsammy/tailwindcss-classnames/commit/bf4bb5ed16c7a758a9f362efd8ee4b6748e47753)) 493 | - functions in theme.extend overrides the theme not extend it ([#49](https://github.com/muhammadsammy/tailwindcss-classnames/issues/49)) ([3be8b6f](https://github.com/muhammadsammy/tailwindcss-classnames/commit/3be8b6f9678e8560ee89f8b686f3ff0bdbcc11fe)) 494 | 495 | ### [1.7.2](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.6.1...v1.7.2) (2020-09-11) 496 | 497 | ### Bug Fixes 498 | 499 | - add missing 'transition' type ([bf4bb5e](https://github.com/muhammadsammy/tailwindcss-classnames/commit/bf4bb5ed16c7a758a9f362efd8ee4b6748e47753)) 500 | - functions in theme.extend overrides the theme not extend it ([#49](https://github.com/muhammadsammy/tailwindcss-classnames/issues/49)) ([3be8b6f](https://github.com/muhammadsammy/tailwindcss-classnames/commit/3be8b6f9678e8560ee89f8b686f3ff0bdbcc11fe)) 501 | 502 | ### [1.7.1](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.6.1...v1.7.1) (2020-09-10) 503 | 504 | ### Bug Fixes 505 | 506 | - functions in theme.extend overrides the theme not extend it ([#49](https://github.com/muhammadsammy/tailwindcss-classnames/issues/49)) ([3be8b6f](https://github.com/muhammadsammy/tailwindcss-classnames/commit/3be8b6f9678e8560ee89f8b686f3ff0bdbcc11fe)) 507 | 508 | ## [1.7.0](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.6.1...v1.7.0) (2020-09-04) 509 | 510 | ### Features 511 | 512 | - **plugins:** add typography plugin support ([#44](https://github.com/muhammadsammy/tailwindcss-classnames/issues/44)) ([7b8eabb](https://github.com/muhammadsammy/tailwindcss-classnames/commit/7b8eabbbdba03132e97bc400f0181c77a5c96cf3)) 513 | - **types:** add TKey ([#42](https://github.com/muhammadsammy/tailwindcss-classnames/issues/42)) ([8011ab3](https://github.com/muhammadsammy/tailwindcss-classnames/commit/8011ab3d279fda7920cea4c0445ae5ff977bf841)) 514 | 515 | ### [1.6.1](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.6.0...v1.6.1) (2020-08-31) 516 | 517 | ### Bug Fixes 518 | 519 | - add missing pseudoclasses for gap, accessiblity and inset classes ([9c7d3a3](https://github.com/muhammadsammy/tailwindcss-classnames/commit/9c7d3a329cf6536481e9a0e4f5ef8d2504dee2a2)) 520 | 521 | ## [1.6.0](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.4.1...v1.6.0) (2020-08-30) 522 | 523 | ### Features 524 | 525 | - add compatibility with TailwindCSS v1.7 ([#32](https://github.com/muhammadsammy/tailwindcss-classnames/issues/32)) ([83562f3](https://github.com/muhammadsammy/tailwindcss-classnames/commit/83562f30fe614a1490d6f6df648f8c97530c0cee)) 526 | - add default export ([4f987ec](https://github.com/muhammadsammy/tailwindcss-classnames/commit/4f987ecd91d197f57a86afdce847dd0ce5112acf)) 527 | - add default export ([2ffbdce](https://github.com/muhammadsammy/tailwindcss-classnames/commit/2ffbdceecc25dfaa1c57486a2635424dc02615f2)) 528 | 529 | ## [1.5.0](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.4.1...v1.5.0) (2020-08-20) 530 | 531 | ### Features 532 | 533 | - add compatibility with TailwindCSS v1.7 ([#32](https://github.com/muhammadsammy/tailwindcss-classnames/issues/32)) ([83562f3](https://github.com/muhammadsammy/tailwindcss-classnames/commit/83562f30fe614a1490d6f6df648f8c97530c0cee)) 534 | 535 | ### [1.4.1](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.4.0...v1.4.1) (2020-07-05) 536 | 537 | ### Bug Fixes 538 | 539 | - use correct prefix for font sizes types ([c5b6640](https://github.com/muhammadsammy/tailwindcss-classnames/commit/c5b66408a52122be70f02aa96a62660a967d49d9)) 540 | 541 | ## [1.4.0](https://github.com/muhammadsammy/tailwindcss-classnames/compare/v1.3.9...v1.4.0) (2020-07-04) 542 | 543 | ### ⚠ BREAKING CHANGES 544 | 545 | - remove pseudoselector functions 546 | 547 | ### Features 548 | 549 | - add flexGrow types from theme ([359a693](https://github.com/muhammadsammy/tailwindcss-classnames/commit/359a6932015bf2eedeafae84eb761ad00aa799fa)) 550 | - add line height classes type generation ([23d5fd0](https://github.com/muhammadsammy/tailwindcss-classnames/commit/23d5fd0226db4f9559e60e53533677d79a14a779)) 551 | - add order classes types generation from theme ([fd24095](https://github.com/muhammadsammy/tailwindcss-classnames/commit/fd24095a6e1f0fc75c66713edeae2b4bcb9314dd)) 552 | - add placeholder color and opacity types generation ([e465e89](https://github.com/muhammadsammy/tailwindcss-classnames/commit/e465e89411b307d8cc61c42a8eebf9669e01cd2f)) 553 | - add text opacity type generation ([2239109](https://github.com/muhammadsammy/tailwindcss-classnames/commit/2239109c4953a40678c36f27059fc2c3dd01573d)) 554 | - add theme extend values to scanned theme ([95d9d4c](https://github.com/muhammadsammy/tailwindcss-classnames/commit/95d9d4c9d92cefbf5be9d88c7365a57ec430b5bc)) 555 | - add type generation for flex shrink ([d31bb56](https://github.com/muhammadsammy/tailwindcss-classnames/commit/d31bb56162ab6c87d7016337e3b975de3106f600)) 556 | - generate list style type types ([13289af](https://github.com/muhammadsammy/tailwindcss-classnames/commit/13289af34fab9fb12dabb8608cec08b271de3d16)) 557 | - generate all backgrounds-related types ([269361e](https://github.com/muhammadsammy/tailwindcss-classnames/commit/269361ef89da05ba1f18b912abbde06c0488acc4)) 558 | - generate border radius types from theme ([c0ae9e4](https://github.com/muhammadsammy/tailwindcss-classnames/commit/c0ae9e4f8e6d1ee47df36951e9abcc0151e3aef9)) 559 | - generate border width types from theme ([b733566](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b7335661c18b508f3317699880128b51f7c0686b)) 560 | - generate classes with color with respect to each classes key ([d582974](https://github.com/muhammadsammy/tailwindcss-classnames/commit/d5829748adfbc662dea318a16d98f4c1b199c194)) 561 | - generate divide width types from theme ([9f7df54](https://github.com/muhammadsammy/tailwindcss-classnames/commit/9f7df5435a1c66044a827fa1efabc52780246c16)) 562 | - generate effects types from theme ([3ceb290](https://github.com/muhammadsammy/tailwindcss-classnames/commit/3ceb29037a548b4c492d73a095788f4bb04b54c1)) 563 | - generate font family types ([950156d](https://github.com/muhammadsammy/tailwindcss-classnames/commit/950156dab0daadf1fb93fdb06751fd40fc9af1e8)) 564 | - generate font size types ([6dbd3a7](https://github.com/muhammadsammy/tailwindcss-classnames/commit/6dbd3a790aa9e55bad991d4b324426f7ab0f09c7)) 565 | - generate font weight types ([45ae183](https://github.com/muhammadsammy/tailwindcss-classnames/commit/45ae183cc9679c429930c79fdce921883faa5661)) 566 | - generate grid column start/end types ([3b90dbc](https://github.com/muhammadsammy/tailwindcss-classnames/commit/3b90dbc8e06c4587d2f6db981958401ec4b31bc2)) 567 | - generate grid gap types ([cb70a1a](https://github.com/muhammadsammy/tailwindcss-classnames/commit/cb70a1a1729c0d60b055b00520326934d553b2c4)) 568 | - generate grid row start/end types ([9a173a7](https://github.com/muhammadsammy/tailwindcss-classnames/commit/9a173a78ff9b85c2aec6d1f0c37259125323f9b9)) 569 | - generate grid template rows types ([da9950e](https://github.com/muhammadsammy/tailwindcss-classnames/commit/da9950e0a70181fd83a7ad2eef869cf5b821eb21)) 570 | - generate interactivity classes types from theme config ([7cb6062](https://github.com/muhammadsammy/tailwindcss-classnames/commit/7cb60626c91fe5d5fab5f796cdf870115f4c125d)) 571 | - generate layout types from theme config ([d127695](https://github.com/muhammadsammy/tailwindcss-classnames/commit/d1276958501700a94b6230261a0f93dd41285a82)) 572 | - generate letter spacing types from tailwind config ([c389a79](https://github.com/muhammadsammy/tailwindcss-classnames/commit/c389a79c48ee61b27752417470f2a8943b12d544)) 573 | - generate padding, margin and space classes from theme ([8bfa8eb](https://github.com/muhammadsammy/tailwindcss-classnames/commit/8bfa8eb5eb71647edc3433897683e77ce4719236)) 574 | - generate sizing classes types from theme config ([35c6530](https://github.com/muhammadsammy/tailwindcss-classnames/commit/35c6530441386706edba23634004375f27111300)) 575 | - generate SVG types ([3ce6d80](https://github.com/muhammadsammy/tailwindcss-classnames/commit/3ce6d802ab3c1238202f545776c17e5584ed358f)) 576 | - generate transforms classes types from theme config ([599a2e3](https://github.com/muhammadsammy/tailwindcss-classnames/commit/599a2e363be1f8326e389c5bddd671dbfe818374)) 577 | - generate transition duration types from theme ([c4819e2](https://github.com/muhammadsammy/tailwindcss-classnames/commit/c4819e2fbeb063461d4cece547c3fcd9a0023af6)) 578 | - generate transition property types from theme ([822414c](https://github.com/muhammadsammy/tailwindcss-classnames/commit/822414c3e883c05dcb15b7db97db46a94b75f151)) 579 | - generate transition timing function and delay from theme ([5842b6e](https://github.com/muhammadsammy/tailwindcss-classnames/commit/5842b6e6c423d42c86bd7aced1639305f560b801)) 580 | - generate types for grid template columns ([8e0e5d5](https://github.com/muhammadsammy/tailwindcss-classnames/commit/8e0e5d51e66bf88aca8b420f5a2b1813ab9e8e6c)) 581 | - get theme values from closures referencing other values in config ([f10d9f9](https://github.com/muhammadsammy/tailwindcss-classnames/commit/f10d9f9fdc776fc47eeeef45c6cf91e9dbac21c0)) 582 | 583 | ### Bug Fixes 584 | 585 | - add missing generated divide color and opacity ([0d56d53](https://github.com/muhammadsammy/tailwindcss-classnames/commit/0d56d53d9bd75866cef77830c5cb918b94c191d6)) 586 | - generate pseudoclasses for generated classes not the default ones ([bc618aa](https://github.com/muhammadsammy/tailwindcss-classnames/commit/bc618aab09a7bef7b6dfe70e2c008b66e8fe813d)) 587 | - prevent utility functions from mutating original theme values ([b414bf0](https://github.com/muhammadsammy/tailwindcss-classnames/commit/b414bf051ecd4fc143de324bf4b405d4ebd7daed)) 588 | - remove false positive warning message for pseudo-classes generation ([d9663d6](https://github.com/muhammadsammy/tailwindcss-classnames/commit/d9663d63ef5c2f86f8899ad98cdb5a806d7dde2e)) 589 | - remove hard coded values in translate generation ([5fca805](https://github.com/muhammadsammy/tailwindcss-classnames/commit/5fca805e28887aaecaf301647ca4b38cc11d2ca6)) 590 | 591 | ## 0.1.0 592 | 593 | - First release 594 | --------------------------------------------------------------------------------