### Configure string matcher example Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/configuration/advanced.md Example configuration using the strings matcher. ```json { "selectors": [ { "kind": "callee", "name": "^tw$", "match": [ { "type": "strings" } ] } ] } ``` -------------------------------- ### Project Setup and Development Commands Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/CONTRIBUTING.md Commands for cloning the repository, installing dependencies, running tests, and managing build tasks. These scripts are essential for local development and ensuring code quality. ```bash git clone https://github.com/schoero/eslint-plugin-better-tailwindcss.git cd eslint-plugin-better-tailwindcss npm install git checkout -b feat/your-feature-name npm test npm run install:v3 npm run test:v3 npm run install:v4 npm run test:v4 npm run lint:fix npm run typecheck npm run build git add . git commit -m "feat: add new feature" git push origin feat/your-feature-name ``` -------------------------------- ### Define path structure example Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/configuration/advanced.md Shows how object paths are represented in the configuration. ```json { "root": { "nested-key": { "values": [ { "value": "this will get linted" } ] } } } ``` -------------------------------- ### Install vue-eslint-parser Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/vue.md Installs the necessary dependency to allow ESLint to parse Vue files. ```shell npm i -D vue-eslint-parser ``` -------------------------------- ### Configure selectors in JSON Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/configuration/advanced.md Example configuration for targeting a specific method call. ```jsonc { "selectors": [ { "kind": "callee", "path": "^classes\\.push$", "match": [{ "type": "strings" }] } ] } ``` -------------------------------- ### Install HTML ESLint Parser Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/html.md Install the required parser dependency to enable ESLint to process HTML files. ```bash npm i -D @html-eslint/parser ``` -------------------------------- ### Position Component Classes (start) Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-class-order.md Demonstrates the 'componentClassPosition: 'start'' option, which places predefined component classes (like 'btn', 'card') at the beginning of the class list. This assumes these classes are defined in the Tailwind configuration. ```tsx // ✅ GOOD: with option { componentClassPosition: 'start' } // 'btn' and 'card' are defined as component classes in the tailwind config
; ``` -------------------------------- ### Install TypeScript ESLint dependencies Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/typescript.md Commands to install the necessary TypeScript parser packages for ESLint integration. ```bash npm i -D typescript-eslint ``` ```bash npm i -D @typescript-eslint/parser ``` -------------------------------- ### Enforce Logical Properties Examples Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-logical-properties.md Demonstrates the difference between using physical direction classes and their recommended logical counterparts. ```tsx // ❌ BAD: physical direction classes
; ``` ```tsx // ✅ GOOD: logical direction classes
; ``` -------------------------------- ### Good Example: Single Class Per Line with Grouping Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-line-wrapping.md Demonstrates setting each class on its own line with empty line grouping using `{ classesPerLine: 1, group: 'emptyLine' }`. ```tsx // ✅ GOOD: with { classesPerLine: 1, group: 'emptyLine' }
; ``` -------------------------------- ### Position Unknown Classes (start) Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-class-order.md Shows the 'unknownClassPosition: 'start'' option, which places classes not recognized by Tailwind's configuration at the beginning of the class list. This can help in identifying or managing custom or third-party classes. ```tsx // ✅ GOOD: with option { unknownClassPosition: 'start' } // 'unknown-class' is not defined in the tailwind config
; ``` -------------------------------- ### Example Usage of SearchBox with classNames Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/configuration/advanced.md Demonstrates how to apply custom class names to the SearchBox component, which can be targeted by the custom selector. ```tsx ; ``` -------------------------------- ### Install @typescript-eslint/parser for Legacy ESLint Config Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/tsx.md Installs the @typescript-eslint/parser package, necessary for using ESLint with TypeScript files under the legacy configuration system. ```sh npm i -D @typescript-eslint/parser ``` -------------------------------- ### Example of string matcher behavior Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/configuration/advanced.md Demonstrates which strings are targeted by the strings matcher. ```tsx tw( "this will get linted", { className: "this will not get linted by this matcher" } ); ``` -------------------------------- ### Install ESLint Dependencies for Angular (Legacy Config) Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/angular.md Installs the necessary ESLint packages for Angular and TypeScript development using the legacy configuration format. This is required for linting Tailwind CSS classes in older ESLint setups. ```sh npm i -D angular-eslint @typescript-eslint/parser ``` -------------------------------- ### Good Example: Grouping with 'emptyLine' Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-line-wrapping.md Demonstrates how to group Tailwind classes with empty lines between variants using the `{ group: 'emptyLine' }` option. ```tsx // ✅ GOOD: with option { group: 'emptyLine' }
; ``` -------------------------------- ### Good Example: Grouping with 'newLine' Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-line-wrapping.md Shows how to group Tailwind classes with new lines between variants using the `{ group: 'newLine' }` option. ```tsx // ✅ GOOD: with option { group: 'newLine' }
; ``` -------------------------------- ### Install typescript-eslint for ESLint Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/tsx.md Installs the typescript-eslint package as a development dependency, which is required for ESLint to parse and lint TypeScript/TSX files effectively. ```sh npm i -D typescript-eslint ``` -------------------------------- ### Good Example: No Grouping with Print Width Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-line-wrapping.md Illustrates formatting without explicit grouping, relying on `printWidth` to wrap lines, using `{ group: 'never', printWidth: 80 }`. ```tsx // ✅ GOOD: with option { group: 'never', printWidth: 80 }
; ``` -------------------------------- ### Enforce Tailwind CSS Class Order (official) Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-class-order.md This example shows the 'order: official' configuration, which likely follows Tailwind CSS's recommended or official ordering convention. It presents a 'GOOD' example adhering to this specific order. ```tsx // ✅ GOOD: with option { order: 'official' }
; ``` -------------------------------- ### Good Example: Single Line Preference with Large Print Width Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-line-wrapping.md Shows how `preferSingleLine: true` with a large `printWidth` results in a single line of classes, using `{ group: "newLine", preferSingleLine: true, printWidth: 120 }`. ```tsx // ✅ GOOD: with { group: "newLine", preferSingleLine: true, printWidth: 120 }
; ``` -------------------------------- ### Good Example: Single Line Preference with Smaller Print Width Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-line-wrapping.md Illustrates `preferSingleLine: true` with a smaller `printWidth` still wrapping lines but maintaining a single line for grouped variants, using `{ group: "newLine", preferSingleLine: true, printWidth: 80 }`. ```tsx // ✅ GOOD: with { group: "newLine", preferSingleLine: true, printWidth: 80 }
; ``` -------------------------------- ### Install svelte-eslint-parser for ESLint Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/svelte.md Installs the necessary parser for ESLint to handle Svelte files. This is a prerequisite for linting Tailwind CSS classes within Svelte components. ```sh npm i -D svelte-eslint-parser ``` -------------------------------- ### Bad Example: Unformatted Tailwind Classes Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-line-wrapping.md Shows the default unformatted state of Tailwind CSS classes, which can become difficult to read. ```tsx // ❌ BAD
; ``` -------------------------------- ### Enforce Tailwind CSS Class Order (asc) Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-class-order.md This example demonstrates how to use the 'order: asc' option to enforce an ascending order for Tailwind CSS classes within HTML elements. It shows a 'BAD' example with random order and a 'GOOD' example with the correct ascending order. ```tsx // ❌ BAD: all classes are in random order
; // ✅ GOOD: with option { order: 'asc' }
; ``` -------------------------------- ### Install ESLint Dependencies for Tailwind CSS Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/css.md Installs the necessary ESLint plugin and custom syntax for parsing Tailwind CSS `@apply` directives in CSS files. This is a prerequisite for linting Tailwind CSS classes. ```sh npm i -D @eslint/css tailwind-csstree ``` -------------------------------- ### Monorepo Setup for Better Tailwind ESLint Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/README.md Configure the 'cwd' setting for better-tailwindcss in monorepos to resolve Tailwind configurations per file group. This ensures the plugin correctly identifies Tailwind setups in different packages. ```javascript export default [ { files: ["packages/website/**/*.{js,jsx,cjs,mjs,ts,tsx}"], settings: { "better-tailwindcss": { cwd: "./packages/website" } } }, { files: ["packages/app/**/*.{js,jsx,cjs,mjs,ts,tsx}"], settings: { "better-tailwindcss": { cwd: "./packages/app" } } } ]; ``` -------------------------------- ### Install ESLint Dependencies for Angular Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/angular.md Installs the necessary ESLint packages for Angular and TypeScript development, which are prerequisites for linting Tailwind CSS classes. ```sh npm i -D angular-eslint typescript-eslint ``` -------------------------------- ### Enforce Tailwind CSS Variant Order (Good Example) Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-variant-order.md Demonstrates the correct variant order for Tailwind CSS class names. This follows Tailwind's recommended order. ```tsx // ✅ GOOD: variants follow Tailwind's recommended order
; ``` -------------------------------- ### Disallow Child Variants Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/no-restricted-classes.md This example shows how to disallow the use of child variants (e.g., `*:mx-0`) by configuring the `restrict` option with a pattern that matches the `*:` prefix. ```tsx // ❌ BAD: disallow the use of the child variants with option `{ restrict: ["^\\*+:.*"] }`
; // ~~~~~~ ``` -------------------------------- ### Enforce Tailwind CSS Variant Order (Bad Example) Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-variant-order.md Demonstrates an incorrect variant order for Tailwind CSS class names. Ensure variants follow Tailwind's recommended order. ```tsx // ❌ BAD: variants are not in Tailwind's recommended order
; ``` -------------------------------- ### Disallow `text-green-500` Class Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/no-restricted-classes.md This example demonstrates how to disallow the `text-green-500` class using the `restrict` option with a pattern that targets the class name. ```tsx // ❌ BAD: disallow the use of the `text-green-500` class with option `{ restrict: [{ pattern: "^(.*)-green-500$", message: "Restricted class: Use '$1-success' instead." }] }`
; // ~~~~~~~~~~~~~~ Restricted class: Use 'text-success' instead. ``` -------------------------------- ### Configure ESLint for Vue Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/vue.md Provides configuration examples for integrating the plugin with Vue files. Includes both modern flat config and legacy JSON formats. ```javascript // eslint.config.js import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss"; import { defineConfig } from "eslint/config"; import eslintParserVue from "vue-eslint-parser"; export default defineConfig({ extends: [ eslintPluginBetterTailwindcss.configs.recommended ], settings: { "better-tailwindcss": { entryPoint: "src/global.css", tailwindConfig: "tailwind.config.js" } }, files: ["**/*.vue"], languageOptions: { parser: eslintParserVue } }); ``` ```jsonc // .eslintrc.json { "extends": [ "plugin:better-tailwindcss/legacy-recommended" ], "settings": { "better-tailwindcss": { "entryPoint": "src/global.css", "tailwindConfig": "tailwind.config.js" } }, "parser": "vue-eslint-parser" } ``` -------------------------------- ### Configure ESLint for TypeScript Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/typescript.md Examples for setting up the plugin using both modern flat config and legacy JSON formats. These configurations define the plugin settings, parser, and rule overrides for Tailwind CSS. ```javascript import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss"; import { defineConfig } from "eslint/config"; import { parser as eslintParserTypeScript } from "typescript-eslint"; export default defineConfig({ extends: [ eslintPluginBetterTailwindcss.configs.recommended ], settings: { "better-tailwindcss": { entryPoint: "src/global.css", tailwindConfig: "tailwind.config.js" } }, files: ["**/*.{ts,tsx,cts,mts}"], languageOptions: { parser: eslintParserTypeScript, parserOptions: { project: true } } }); ``` ```json { "extends": [ "plugin:better-tailwindcss/legacy-recommended" ], "settings": { "better-tailwindcss": { "entryPoint": "src/global.css", "tailwindConfig": "tailwind.config.js" } }, "parser": "@typescript-eslint/parser" } ``` -------------------------------- ### Configure ESLint Flat Config for Svelte Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/svelte.md Sets up ESLint using the flat config format to lint Tailwind CSS classes in Svelte files. It requires installing `svelte-eslint-parser` and configuring the plugin with Tailwind CSS paths. ```js // eslint.config.js import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss"; import { defineConfig } from "eslint/config"; import eslintParserSvelte from "svelte-eslint-parser"; export default defineConfig({ // enable all recommended rules extends: [ eslintPluginBetterTailwindcss.configs.recommended ], // if needed, override rules to configure them individually // rules: { // "better-tailwindcss/enforce-consistent-line-wrapping": ["warn", { printWidth: 100 }] // }, settings: { "better-tailwindcss": { // tailwindcss 4: the path to the entry file of the css based tailwind config (eg: `src/global.css`) entryPoint: "src/global.css", // tailwindcss 3: the path to the tailwind config file (eg: `tailwind.config.js`) tailwindConfig: "tailwind.config.js" } }, files: ["**/*.svelte"], languageOptions: { parser: eslintParserSvelte } }); ``` -------------------------------- ### Enforce Tailwind CSS Class Order (desc) Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-class-order.md This example illustrates the use of the 'order: desc' option for enforcing a descending order of Tailwind CSS classes. It contrasts a poorly ordered class list with one that adheres to the descending order. ```tsx // ✅ GOOD: with option { order: 'desc' }
; ``` -------------------------------- ### Configure ESLint for Tailwind CSS in HTML Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/html.md Configure ESLint to use the better-tailwindcss plugin with HTML files. Includes examples for modern flat configuration and legacy JSON configuration. ```javascript import eslintParserHTML from "@html-eslint/parser"; import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss"; import { defineConfig } from "eslint/config"; export default defineConfig({ extends: [ eslintPluginBetterTailwindcss.configs.recommended ], settings: { "better-tailwindcss": { entryPoint: "src/global.css", tailwindConfig: "tailwind.config.js" } }, files: ["**/*.html"], languageOptions: { parser: eslintParserHTML } }); ``` ```json { "extends": [ "plugin:better-tailwindcss/legacy-recommended" ], "settings": { "better-tailwindcss": { "entryPoint": "src/global.css", "tailwindConfig": "tailwind.config.js" } }, "parser": "@html-eslint/parser" } ``` -------------------------------- ### Configure path option for cva Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/configuration/advanced.md Demonstrates using the path option to target specific nested object values in cva. ```json { "selectors": [ { "kind": "callee", "name": "^cva$", "match": [ { "type": "objectValues", "path": "^compoundVariants\[\\d+\]\\.(?:className|class)$" } ] } ] } ``` ```tsx ; ``` -------------------------------- ### Configure ESLint settings for better-tailwindcss Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/settings/settings.md Add a settings key to your ESLint configuration file to define global options for the plugin. ```jsonc // eslint.config.js { // "plugins": {... }, // "rules": { ... }, "settings": { "better-tailwindcss": { // ... } } } ``` -------------------------------- ### Enforce collapsed margin utilities Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-canonical-classes.md Collapses multiple individual margin utilities into a single shorthand utility. Enable 'collapse' option for this behavior. Recommended to disable 'enforce-shorthand-classes' when using this. ```tsx
; ``` ```tsx
; ``` -------------------------------- ### VSCode Oxlint Auto-fix Configuration Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/README.md Configure VSCode to automatically fix Tailwind classes on save using Oxlint. This requires the VSCode Oxc plugin to be installed. ```jsonc { // enable VSCode to fix tailwind classes on save "editor.codeActionsOnSave": { "source.fixAll.oxc": "explicit" } } ``` -------------------------------- ### Configure Restricted Classes with Custom Messages and Fixes Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/no-restricted-classes.md Use this configuration to disallow specific classes, providing custom error messages and automatic fixes. The `pattern` uses regular expressions, and matched groups can be referenced in `message` and `fix` using `$1`, `$2`, etc. ```json { "restrict": [{ "fix": "$1$2-success$3", "message": "Restricted class: Use '$1$2-success$3' instead.", "pattern": "^([a-zA-Z0-9:/_-]*:)?(text|bg)-green-500(\/[0-9]{1,3})?$" }] } ``` -------------------------------- ### Selector Matcher Configuration Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/configuration/advanced.md Defines the available matcher types for targeting specific code structures for linting. ```APIDOC ## Selector Matchers ### Description Defines how the plugin identifies code to lint using different matcher types. ### Matcher Types - **objectKeys** (object): Matches object keys. Supports an optional `path` regex to narrow matching. - **objectValues** (object): Matches object values. Supports an optional `path` regex to narrow matching. - **anonymousFunctionReturn** (object): Matches values returned from anonymous functions. Requires a `match` array of nested matchers. ### Path Option Details The `path` option allows narrowing matches using regex against the object path (e.g., `root.nested.values[0]`). ### Configuration Example ```json { "selectors": [ { "kind": "callee", "name": "^tw$", "match": [ { "type": "objectKeys", "path": "^compoundVariants\\[\\d+\\].(?:className|class)$" }, { "type": "objectValues", "path": "^compoundVariants\\[\\d+\\].(?:className|class)$" }, { "type": "anonymousFunctionReturn", "match": [{ "type": "strings" }] } ] } ] } ``` ``` -------------------------------- ### Global Settings Configuration Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/settings/settings.md The settings object allows for global configuration of shared options across all rules. These global options can be overridden by rule-specific configurations. ```APIDOC ## Global Settings Configuration ### Description Configure global options for the `eslint-plugin-better-tailwindcss` across all rules. Rule-specific options will always override these global settings. ### Method Configuration via `eslint.config.js` (or similar ESLint configuration file). ### Endpoint N/A (Configuration Object) ### Parameters #### Request Body (within `settings` object) - **`better-tailwindcss`** (object) - Required - The namespace for better-tailwindcss settings. - **`entryPoint`** (string) - Optional - The path to the entry file of the CSS-based Tailwind config (e.g., `src/global.css`). Relative to the [current working directory](#cwd). If not specified, the plugin falls back to the default configuration. - **`tailwindConfig`** (string) - Optional - The path to the `tailwind.config.js` file. Relative to the [current working directory](#cwd). If not specified, the plugin attempts to find it automatically or falls back to the default. For Tailwind CSS v4 and CSS-based configs, use `entryPoint` instead. - **`tsconfig`** (string) - Optional - The path to the `tsconfig.json` file. Relative to the [current working directory](#cwd). If not specified, the plugin attempts to find it automatically. Used to resolve TypeScript path aliases. Default: `undefined`. - **`cwd`** (string) - Optional - The working directory used to resolve Tailwind CSS and related config files. Useful for monorepos. Resolved relative to the ESLint process's current working directory. If not specified, it defaults to the ESLint process's current working directory. Default: `undefined`. - **`detectComponentClasses`** (boolean) - Optional - If `true`, allows the rule to detect and not report custom component classes (e.g., `card`, `btn`). Default: `false`. - **`rootFontSize`** (number | undefined) - Optional - The font size of the `` element in pixels. Used to determine if arbitrary values can be replaced with predefined sizing scales. Default: `undefined` (falls back to 16px unless changed by CSS). - **`messageStyle`** (string) - Optional - Customize the display style of linting messages. Options: `"visual"` (visualizes whitespaces/line breaks), `"compact"` (single-line, suitable for CI), `"raw"` (raw information without visualization). Default: `"visual"` (or `"compact"` in CI environments). - **`selectors`** (Array of Selectors) - Optional - A flat list of selectors that determines where Tailwind class strings are linted. Only string literals matched by these selectors are treated as Tailwind class candidates. Default: See [defaults API](../api/defaults.md). ### Request Example ```jsonc // eslint.config.js { // "plugins": {... }, // "rules": { ... }, "settings": { "better-tailwindcss": { "entryPoint": "src/global.css", "tailwindConfig": "tailwind.config.js", "tsconfig": "./tsconfig.json", "cwd": "./packages/my-app", "detectComponentClasses": true, "rootFontSize": 16, "messageStyle": "compact", "selectors": [ "*.className", "*.class" ] } } } ``` ### Response N/A (Configuration Object) ### Success Response (200) N/A (Configuration Object) ### Response Example N/A (Configuration Object) ``` -------------------------------- ### VSCode ESLint Auto-fix Configuration Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/README.md Enable VSCode to automatically fix Tailwind classes on save by configuring ESLint's code actions. Ensure the ESLint VSCode plugin is installed. ```jsonc { // enable VSCode to fix tailwind classes on save "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" } } ``` -------------------------------- ### Target specific call arguments Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/configuration/advanced.md Configures linting for the first argument of the last curried call. ```jsonc { "selectors": [ { "kind": "callee", "name": "^tw$", "targetCall": "last", "targetArgument": "first" } ] } ``` ```tsx tw("keep", "ignore")("this will get linted", "this will not"); ``` -------------------------------- ### Use Updated Tailwind CSS Class: shrink Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/no-deprecated-classes.md This example demonstrates the correct usage of the updated 'shrink-1' class in Tailwind CSS, which replaces the deprecated 'flex-shrink-1' class. This code adheres to the rule. ```tsx // ✅ GOOD: using updated shrink class
; ``` -------------------------------- ### Configure ESLint Flat Config for Tailwind CSS Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/javascript.md This snippet shows how to configure the eslint-plugin-better-tailwindcss using ESLint's flat config format. It includes enabling recommended rules and setting Tailwind CSS configuration paths like the entry point or tailwind config file. ```javascript // eslint.config.js import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss"; import { defineConfig } from "eslint/config"; export default defineConfig({ // enable all recommended rules extends: [ eslintPluginBetterTailwindcss.configs.recommended ], // if needed, override rules to configure them individually // rules: { // "better-tailwindcss/enforce-consistent-line-wrapping": ["warn", { printWidth: 100 }] // }, settings: { "better-tailwindcss": { // tailwindcss 4: the path to the entry file of the css based tailwind config (eg: `src/global.css`) entryPoint: "src/global.css", // tailwindcss 3: the path to the tailwind config file (eg: `tailwind.config.js`) tailwindConfig: "tailwind.config.js" } } }); ``` -------------------------------- ### Detect Deprecated Tailwind CSS Class: flex-shrink Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/no-deprecated-classes.md This example highlights the incorrect usage of the deprecated 'flex-shrink-1' class in Tailwind CSS. The rule flags this, recommending the use of the 'shrink-1' class instead. ```tsx // ❌ BAD: using deprecated flex-shrink class
; ``` -------------------------------- ### Use Updated Tailwind CSS Class: shadow-sm Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/no-deprecated-classes.md This example shows the correct usage of the updated 'shadow-sm' class in Tailwind CSS, which replaces the deprecated 'shadow' class. The rule allows this code. ```tsx // ✅ GOOD: using updated shadow class
; ``` -------------------------------- ### Valid Tailwind Classes in JSX Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/no-conflicting-classes.md This example shows a correct usage of Tailwind CSS classes in JSX, where no conflicting classes are present. The rule would not flag this code, as 'flex' and 'w-full' do not conflict. ```jsx // ✅ GOOD: no conflicting classes
; ``` -------------------------------- ### Detect Deprecated Tailwind CSS Class: shadow Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/no-deprecated-classes.md This example demonstrates the incorrect usage of the deprecated 'shadow' class in Tailwind CSS. The rule flags this as an error, suggesting the use of 'shadow-sm' as the replacement. ```tsx // ❌ BAD: using deprecated shadow class
; ``` -------------------------------- ### Rule Configuration: no-restricted-classes Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/no-restricted-classes.md Configuration details for the no-restricted-classes rule, including the restrict option and common selector settings. ```APIDOC ## Rule: no-restricted-classes ### Description Disallow the usage of certain classes. This can be used to enforce semantic color names, disallow arbitrary values, child variants, or the !important modifier. ### Options #### restrict - **Type**: `string[] | { pattern: string, message?: string, fix?: string }[]` - **Default**: `[]` - **Description**: The classes that should be disallowed. Patterns are treated as regular expressions. Matched groups can be referenced in messages or fixes using $1, $2, etc. #### selectors - **Type**: Array of Selectors - **Default**: See defaults API - **Description**: Flat list of selectors that determines where Tailwind class strings are linted. ### Configuration Example ```json { "rules": { "better-tailwindcss/no-restricted-classes": ["error", { "restrict": [{ "fix": "$1$2-success$3", "message": "Restricted class: Use '$1$2-success$3' instead.", "pattern": "^([a-zA-Z0-9:/_-]*:)?(text|bg)-green-500(\\/[0-9]{1,3})?$" }] }] } } ``` ``` -------------------------------- ### Configure ESLint for Custom Algolia Attributes Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/configuration/advanced.md Set up your `eslint.config.js` to include a custom attribute selector that matches values within Algolia's `classNames` objects. This requires importing necessary types and functions from the `eslint-plugin-better-tailwindcss` package. ```js // eslint.config.js import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss"; import { getDefaultSelectors } from "eslint-plugin-better-tailwindcss/defaults"; import { SelectorKind } from "eslint-plugin-better-tailwindcss/types"; import { defineConfig } from "eslint/config"; export default defineConfig({ plugins: { "better-tailwindcss": eslintPluginBetterTailwindcss }, settings: { "better-tailwindcss": { entryPoint: "app/globals.css", selectors: [ ...getDefaultSelectors(), // preserve default selectors { kind: SelectorKind.Attribute, match: [{ type: "objectValues" }], name: "^classNames$" } ] } } }); // ... ``` -------------------------------- ### Configure ESLint Legacy Config for Tailwind CSS Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/javascript.md This snippet demonstrates configuring the eslint-plugin-better-tailwindcss using ESLint's legacy configuration format (.eslintrc.json). It covers extending recommended rules and specifying Tailwind CSS settings. ```jsonc // .eslintrc.json { // enable all recommended rules "extends": [ "plugin:better-tailwindcss/legacy-recommended" ], // if needed, override rules to configure them individually // "rules": { // "better-tailwindcss/enforce-consistent-line-wrapping": ["warn", { "printWidth": 100 }] // }, "settings": { "better-tailwindcss": { // tailwindcss 4: the path to the entry file of the css based tailwind config (eg: `src/global.css`) "entryPoint": "src/global.css", // tailwindcss 3: the path to the tailwind config file (eg: `tailwind.config.js`) "tailwindConfig": "tailwind.config.js" } } } ``` -------------------------------- ### Detect Conflicting Tailwind Classes in JSX Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/no-conflicting-classes.md This example demonstrates how the ESLint rule detects conflicting Tailwind CSS classes in a JSX element. It highlights a scenario where 'flex' and 'grid' are used together, both affecting the 'display' property, which is flagged as a conflict. ```jsx // ❌ BAD: Conflicting class detected: "flex" and "grid" apply the same css properties: "display"
; ``` -------------------------------- ### Configure ESLint Flat Config for Astro Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/astro.md Sets up ESLint to parse and lint Astro files using `astro-eslint-parser` and `eslint-plugin-better-tailwindcss`. It enables recommended rules and configures Tailwind CSS paths. This configuration is for ESLint's modern flat config system. ```javascript // eslint.config.js import eslintParserAstro from "astro-eslint-parser"; import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss"; import { defineConfig } from "eslint/config"; import { parser as eslintParserTypeScript } from "typescript-eslint"; export default defineConfig({ // enable all recommended rules extends: [ eslintPluginBetterTailwindcss.configs.recommended ], // if needed, override rules to configure them individually // rules: { // "better-tailwindcss/enforce-consistent-line-wrapping": ["warn", { printWidth: 100 }] // }, settings: { "better-tailwindcss": { // tailwindcss 4: the path to the entry file of the css based tailwind config (eg: `src/global.css`) entryPoint: "src/global.css", // tailwindcss 3: the path to the tailwind config file (eg: `tailwind.config.js`) tailwindConfig: "tailwind.config.js" } }, files: ["**/*.astro"], languageOptions: { parser: eslintParserAstro, parserOptions: { // optionally use TypeScript parser within for Astro files parser: eslintParserTypeScript } } }); ``` -------------------------------- ### Configure ESLint Legacy Config for Astro Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/astro.md Configures ESLint using the legacy `.eslintrc.json` format to lint Astro files with `astro-eslint-parser` and `eslint-plugin-better-tailwindcss`. It enables legacy recommended rules and specifies Tailwind CSS configuration paths. This is suitable for projects not yet migrated to ESLint's flat config. ```jsonc // .eslintrc.json { // enable all recommended rules "extends": [ "plugin:better-tailwindcss/legacy-recommended" ], // if needed, override rules to configure them individually // "rules": { // "better-tailwindcss/enforce-consistent-line-wrapping": ["warn", { "printWidth": 100 }] // }, "settings": { "better-tailwindcss": { // tailwindcss 4: the path to the entry file of the css based tailwind config (eg: `src/global.css`) "entryPoint": "src/global.css", // tailwindcss 3: the path to the tailwind config file (eg: `tailwind.config.js`) "tailwindConfig": "tailwind.config.js" } }, "parser": "astro-eslint-parser", "parserOptions": { // optionally use TypeScript parser within for Astro files "parser": "@typescript-eslint/parser" } } ``` -------------------------------- ### Disallow Unnecessary Whitespace in Tailwind Classes (TSX) Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/no-unnecessary-whitespace.md This snippet demonstrates the 'no-unnecessary-whitespace' rule in a TSX context. It shows examples of 'bad' code with random whitespace and 'good' code with only necessary whitespace preserved. The rule aims to clean up class attribute strings. ```tsx // ❌ BAD: random unnecessary whitespace
; ``` ```tsx // ✅ GOOD: only necessary whitespace is remaining
; ``` -------------------------------- ### Position Unknown Classes (end) Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-class-order.md Demonstrates the 'unknownClassPosition: 'end'' option, placing unknown classes at the end of the class list. This provides another way to manage and visually separate classes that are not part of the standard Tailwind configuration. ```tsx // ✅ GOOD: with option { unknownClassPosition: 'end' } // 'unknown-class' is not defined in the tailwind config
; ``` -------------------------------- ### Enforce CSS Variable Syntax in Tailwind Classes Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-variable-syntax.md Examples demonstrating the enforcement of 'shorthand' versus 'variable' syntax for CSS variables in Tailwind CSS class strings. The rule validates against the configured syntax option to ensure compatibility with Tailwind CSS versions. ```tsx // ❌ BAD: Incorrect css variable syntax with option `syntax: "shorthand"`
; // ✅ GOOD: With option `syntax: "shorthand"` in Tailwind CSS v4
; // ✅ GOOD: With option `syntax: "shorthand"` in Tailwind CSS v3
; // ❌ BAD: Incorrect css variable syntax with option `syntax: "variable"` in Tailwind CSS v4
; // ❌ BAD: Incorrect css variable syntax with option `syntax: "variable"` in Tailwind CSS v3
; // ✅ GOOD: With option `syntax: "variable"`
; ``` -------------------------------- ### Configure ESLint for Tailwind CSS Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/jsx.md Demonstrates how to integrate the plugin into ESLint using both the modern flat configuration format and the legacy JSON format. It includes settings for defining Tailwind configuration paths and enabling JSX parsing. ```javascript // eslint.config.js import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss"; import { defineConfig } from "eslint/config"; export default defineConfig({ extends: [ eslintPluginBetterTailwindcss.configs.recommended ], settings: { "better-tailwindcss": { entryPoint: "src/global.css", tailwindConfig: "tailwind.config.js" } }, languageOptions: { parserOptions: { ecmaFeatures: { jsx: true } } } }); ``` ```json // .eslintrc.json { "extends": [ "plugin:better-tailwindcss/legacy-recommended" ], "settings": { "better-tailwindcss": { "entryPoint": "src/global.css", "tailwindConfig": "tailwind.config.js" } }, "parserOptions": { "ecmaFeatures": { "jsx": true }, "ecmaVersion": "latest" } } ``` -------------------------------- ### Configure ESLint Legacy Config for Svelte Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/svelte.md Sets up ESLint using the legacy config format (`.eslintrc.json`) to lint Tailwind CSS classes in Svelte files. This configuration includes enabling recommended rules and specifying Tailwind CSS paths. ```jsonc // .eslintrc.json { // enable all recommended rules "extends": [ "plugin:better-tailwindcss/legacy-recommended" ], // if needed, override rules to configure them individually // "rules": { // "better-tailwindcss/enforce-consistent-line-wrapping": ["warn", { "printWidth": 100 }] // }, "settings": { "better-tailwindcss": { // tailwindcss 4: the path to the entry file of the css based tailwind config (eg: `src/global.css`) "entryPoint": "src/global.css", // tailwindcss 3: the path to the tailwind config file (eg: `tailwind.config.js`) "tailwindConfig": "tailwind.config.js" } }, "parser": "svelte-eslint-parser" } ``` -------------------------------- ### Position Component Classes (end) Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/enforce-consistent-class-order.md Illustrates the 'componentClassPosition: 'end'' option, positioning component classes at the end of the class list. This is useful for maintaining a consistent structure where component-specific styles follow utility classes. ```tsx // ✅ GOOD: with option { componentClassPosition: 'end' } // 'btn' and 'card' are defined as component classes in the tailwind config
; ``` -------------------------------- ### Configure ESLint Flat Config for Tailwind CSS Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/parsers/css.md Sets up ESLint using the flat config format to lint Tailwind CSS classes in CSS files. It includes enabling recommended rules from `eslint-plugin-better-tailwindcss`, configuring Tailwind CSS paths, and specifying the custom syntax for CSS files. ```js import css from "@eslint/css"; import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss"; import { defineConfig } from "eslint/config"; import { tailwind4 } from "tailwind-csstree"; export default defineConfig({ // enable all recommended rules extends: [ eslintPluginBetterTailwindcss.configs.recommended ], // if needed, override rules to configure them individually // rules: { // "better-tailwindcss/enforce-consistent-line-wrapping": ["warn", { printWidth: 100 }] // }, settings: { "better-tailwindcss": { // tailwindcss 4: the path to the entry file of the css based tailwind config (eg: `src/global.css`) entryPoint: "src/global.css", // tailwindcss 3: the path to the tailwind config file (eg: `tailwind.config.js`) tailwindConfig: "tailwind.config.js" } }, files: ["**/*.css"], language: "css/css", languageOptions: { customSyntax: tailwind4, tolerant: true }, plugins: { css } }); ``` -------------------------------- ### Rule Testing with lint Helper Source: https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/CONTRIBUTING.md Demonstrates how to use the project's testing abstraction to validate ESLint rules across multiple frameworks like Angular, Astro, HTML, JSX, Svelte, and Vue. It utilizes the lint helper from the test utilities to define valid and invalid test cases. ```typescript import { describe, it } from "vitest"; import { yourRule } from "better-tailwindcss:rules/your-rule.js"; import { lint } from "better-tailwindcss:tests/utils/lint.js"; describe(yourRule.name, () => { it("should describe what it does", () => { lint(yourRule, { invalid: [ { angular: '', angularOutput: '', html: '', htmlOutput: '', jsx: '() => ', jsxOutput: '() => ', svelte: '', svelteOutput: '', vue: '', vueOutput: '', errors: 1, options: [{ /* rule options */ }] } ], valid: [ { angular: '', html: '', jsx: '() => ', svelte: '', vue: '', options: [{ /* rule options */ }] } ] }); }); }); ```