diff --git a/.eslint-doc-generatorrc.js b/.eslint-doc-generatorrc.js
new file mode 100644
index 00000000..150d3496
--- /dev/null
+++ b/.eslint-doc-generatorrc.js
@@ -0,0 +1,25 @@
+/* eslint-disable unicorn/prevent-abbreviations */
+/** @type {import('eslint-doc-generator').GenerateOptions} */
+const config = {
+ // configEmoji: [['recommended', '✅']],
+ // ignoreConfig: ['all', 'flat/all', 'flat/recommended'],
+ ignoreDeprecatedRules: true,
+ // ruleDocNotices: [],
+ // ruleDocSectionExclude: [],
+ // ruleDocSectionInclude: [],
+ ruleDocTitleFormat: "desc",
+ ruleListColumns: [
+ "name",
+ "description",
+ "configsError",
+ "configsWarn",
+ "fixable",
+ "hasSuggestions",
+ "requiresTypeChecking",
+ ],
+ // ruleListSplit: [],
+ // urlConfigs: 'https://github.com/...#preset-configs-eslintconfigjs',
+};
+
+// eslint-disable-next-line no-undef
+module.exports = config;
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index e95181d1..e82a5d32 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -2,9 +2,8 @@
name: Bug report
about: Create a report to help us improve
title: "[BUG] "
-labels: 'bug'
-assignees: ''
-
+labels: "bug"
+assignees: ""
---
**Describe the bug**
@@ -12,9 +11,10 @@ A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
-1. Go to '...'
-2. Click on '....'
-3. Scroll down to '....'
+
+1. Go to '…'
+2. Click on '…'
+3. Scroll down to '…'
4. See error
**Expected behavior**
@@ -24,10 +24,11 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Environment (please complete the following information):**
- - OS: [e.g. macOS, windows 10]
- - Softwares + version used:
- - [e.g. VSCode 1.54.3]
- - [... Terminal 2.9.5, npm 6.14.5, node v14.5.0]
+
+- OS: [e.g. macOS, windows 10]
+- Softwares + version used:
+ - [e.g. VSCode 1.54.3]
+ - [… Terminal 2.9.5, npm 6.14.5, node v14.5.0]
**Additional context**
Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index eb589c12..e7098919 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -2,13 +2,12 @@
name: Feature request
about: Suggest an idea for this project
title: "[Feature request] "
-labels: 'enhancement'
-assignees: ''
-
+labels: "enhancement"
+assignees: ""
---
**Is your feature request related to a problem? Please describe.**
-A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+A clear and concise description of what the problem is. Ex. I'm always frustrated when […]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 747e6b69..15e214cc 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -27,8 +27,8 @@ Please also list any relevant details for your test configuration
**Test Configuration**:
- OS + version: e.g. macOS Mojave
-- NPM version: ...
-- Node version: ...
+- NPM version: …
+- Node version: …
## Checklist:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
deleted file mode 100644
index 80b1e69d..00000000
--- a/.github/workflows/build.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-name: build
-on: [push]
-jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- # waiting on: https://github.com/actions/setup-node/issues/531
- - run: corepack enable
- - uses: actions/setup-node@v4
- with:
- node-version: 21
- cache: npm
- - run: npm ci
-
- - name: test build package on node@21 (current)
- run: |
- node --version
- npm --version
- npm run test
-
- # Not using a matrix here since it's simpler
- # to just duplicate it and not spawn new instances
-
- - uses: actions/setup-node@v4
- with:
- node-version: 20
- - name: test build package on node@20 (LTS)
- run: |
- node --version
- npm --version
- npm run test
-
- - uses: actions/setup-node@v4
- with:
- node-version: 18
- - name: test build package on node@18 (LTS)
- run: |
- node --version
- npm --version
- npm run test
diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml
new file mode 100644
index 00000000..db74b2df
--- /dev/null
+++ b/.github/workflows/run-tests.yml
@@ -0,0 +1,29 @@
+on:
+ - push
+
+jobs:
+ run-tests:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - uses: pnpm/action-setup@v4
+ name: Install pnpm
+
+ - name: Install Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ cache: "pnpm"
+
+ - name: Install dependencies
+ run: pnpm install
+
+ - name: Run the tests
+ run: |
+ node --version
+ pnpm --version
+ pnpm run lint
+ pnpm run test
diff --git a/.gitignore b/.gitignore
index 22d59e5e..c4588cef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,41 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# Dependencies
node_modules
+.pnp
+.pnp.js
+
+# Local env files
+.env
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+# Testing
+coverage
+
+# Turbo
+.turbo
+
+# Vercel
+.vercel
+
+# Build Outputs
+.next/
+out/
+build
+dist
+
+
+# Debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Misc
.DS_Store
+*.pem
.idea
+/lib
+*.tsbuildinfo
diff --git a/.nvmrc b/.nvmrc
index 9dfef472..016efd8a 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v18.12.0
+v20.10.0
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index f82fc396..d8c6e084 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,4 +1,10 @@
{
+ "editor.codeActionsOnSave": {
+ "source.fixAll.eslint": "explicit"
+ },
"editor.defaultFormatter": "esbenp.prettier-vscode",
- "editor.formatOnSave": true
-}
\ No newline at end of file
+ "editor.formatOnSave": true,
+ "files.associations": {
+ "*.css": "tailwindcss"
+ }
+}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9cbf0de0..fd120467 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -7,10 +7,70 @@ email, or any other method with the owners of this repository before making a ch
Please note we have a [code of conduct](CODE_OF_CONDUCT.md), please follow it in all your interactions with the project.
-## Development
+## Getting started with development
-You can use [Corepack](https://nodejs.org/api/corepack.html) to ensure you're using the same package
-manager. Run `corepack enabled` before running `npm install`.
+I worked on this repo using `pnpm` but it should work with other package manager.
+
+### Install
+
+`pnpm i`
+
+### Build
+
+`pnpm build`
+
+### Test
+
+`pnpm test`
+
+or
+
+`pnpm test:jest`
+
+#### `jest` or `vitest`
+
+Tests were setup to work with `jest` and `vitest` both comes with pros and cons…
+
+I would recommend Vitest but I also added Jest in case you want it.
+
+| Jest | Vitest |
+| :----------------------- | :--------------------------------------------- |
+| Based on `commonjs` | Based on `ESM` |
+| ✅ Mocking | ✅ Mocking |
+| ✅ Snapshots | ✅ Snapshots |
+| ✅ Parallel testing | ✅ Parallel testing |
+| ✅ Fast | ✅ Often faster |
+| - | ✅ Support benches |
+| ❌ Require `ts-jest` lib | ❌ Requires `setupFile` and `vitest.config.ts` |
+
+NB: In order to use, the [`RuleTester`](https://typescript-eslint.io/packages/rule-tester) from `@typescript-eslint/rule-tester`, we must:
+
+- Have a `tsconfig.json` with:
+ ```
+ {
+ "compilerOptions": {
+ "module": "nodenext",
+ "moduleResolution": "nodenext"
+ }
+ }
+ ```
+ More info can be found on [`v6`: Cannot find module `@typescript-eslint/*` or its corresponding type declarations](https://github.com/typescript-eslint/typescript-eslint/issues/7284).
+ > You can use `bundler`, `node16`, or `nodenext` for `moduleResolution`.
+- Use `eslint` with `v8`, [`typescript-eslint` does not support `v9` yet](https://github.com/typescript-eslint/typescript-eslint/issues/8211)
+
+### Docs
+
+`pnpm docs:init` will create new files for each rule if necessary.
+
+`pnpm docs:update` will update existing files and the rules list.
+
+You can see an example of generated documentation in the next section.
+
+## Additional resources
+
+See [`eslint-plugin-example-typed-linting`](https://github.com/typescript-eslint/examples/tree/main/packages/eslint-plugin-example-typed-linting) for an example plugin that supports typed linting.
+
+Another example of eslint-plugin using `typescript-eslint` is [`eslint-plugin-vitest`](https://github.com/vitest-dev/eslint-plugin-vitest)…
## Pull Request Process
diff --git a/README.md b/README.md
index 74cf5502..6a1d8c56 100644
--- a/README.md
+++ b/README.md
@@ -1,300 +1,92 @@
# eslint-plugin-tailwindcss
-  
-

-Rules enforcing best practices and consistency using [Tailwind CSS](https://tailwindcss.com/).
-
-While you can use the official plugin [`prettier-plugin-tailwindcss`](https://www.npmjs.com/package/prettier-plugin-tailwindcss) for ordering your classnames...
-
-**`eslint-plugin-tailwindcss` offers more than 5 other rules, that you can benefit from on top of `prettier-plugin-tailwindcss`. Sounds good ? Keep reading 👇**
-
-## Supported Rules
-
-Learn more about each supported rules by reading their documentation:
+## Rules
-- [`classnames-order`](docs/rules/classnames-order.md): order classnames for consistency and it makes merge conflict a bit easier to resolve
-- [`enforces-negative-arbitrary-values`](docs/rules/enforces-negative-arbitrary-values.md): make sure to use negative arbitrary values classname without the negative classname e.g. `-top-[5px]` should become `top-[-5px]`
-- [`enforces-shorthand`](docs/rules/enforces-shorthand.md): merge multiple classnames into shorthand if possible e.g. `mx-5 my-5` should become `m-5`
-- [`migration-from-tailwind-2`](docs/rules/migration-from-tailwind-2.md) for easy upgrade from Tailwind CSS `v2` to `v3`.
- Warning: at the moment you should [temporary turn off the `no-custom-classname`](https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/88) rule if you want to see the warning from `migration-from-tailwind-2`
-- [`no-arbitrary-value`](docs/rules/no-arbitrary-value.md): forbid using arbitrary values in classnames (turned off by default)
-- [`no-custom-classname`](docs/rules/no-custom-classname.md): only allow classnames from Tailwind CSS and the values from the `whitelist` option
-- [`no-contradicting-classname`](docs/rules/no-contradicting-classname.md): e.g. avoid `p-2 p-3`, different Tailwind CSS classnames (`pt-2` & `pt-3`) but targeting the same property several times for the same variant.
-- [`no-unnecessary-arbitrary-value`](docs/rules/no-unnecessary-arbitrary-value.md): e.g. replacing `m-[1.25rem]` by its configuration based classname `m-5`
-
-Using ESLint extension for Visual Studio Code, you will get these messages
-
-
-You can can the same information on your favorite command line software as well.
-
-## 🤝 Support `eslint-plugin-tailwindcss`
+
-| 🥰 How you can support us? | 💪 They did it! |
-| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| **Premium Sponsors**
Support us by becoming a sponsor.
[Become a recurring sponsor](https://github.com/sponsors/francoismassart?frequency=recurring) | |
-| **Current Sponsors**
Any amount is appreciated. |
|
-| **Past sponsors**
Even if this is just a one-time thing.
[Become a backer](https://github.com/sponsors/francoismassart?frequency=one-time) |
|
-| **Contributors**
This project can evolve thanks to all the people who contribute.
You are welcome to [contribute](CONTRIBUTING.md) to this project by reporting issues, feature requests or even opening Pull Requests. | |
-| **Supporters**
Talk about the plugin on your social networks | eslint-plugin-tailwindcss on Twitter |
+🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
+💡 Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
-## Latest changelog
+| Name | Description | 🔧 | 💡 |
+| :------------------------------------------------- | :---------------------------------------------------------------------------------- | :- | :- |
+| [classnames-order](docs/rules/classnames-order.md) | Enforces a consistent order for the Tailwind CSS classnames, based on the compiler. | 🔧 | 💡 |
-- fix: [`no-arbitrary-value` rule is too broad](https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/318)
-- fix: [support `tag.div` and `tag(Component)`](https://github.com/francoismassart/eslint-plugin-tailwindcss/pull/302) (by [nihalgonsalves](https://github.com/nihalgonsalves) 🙏)
-- feat: [**support flat config and ESLint 9**](https://github.com/francoismassart/eslint-plugin-tailwindcss/pull/330) (by [kazupon](https://github.com/kazupon) 🙏)
-- feat: new rule [**`no-unnecessary-arbitrary-value`**](docs/rules/no-unnecessary-arbitrary-value.md) 🎉
-- fix: retro compatibility for older Tailwind CSS (before typescript config)
-- fix: [composable touch action classnames](https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/293)
-- fix: [`shadow-md` + `shadow-[#color]`can be used together 🤝](https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/298)
-- fix: [`tabular-nums` and `slashed-zero` can be used together 🤝](https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/316)
-- fix: [`size-*` based `size`, `spacing`, `width` and `height` 🤓](https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/315)
-- fix: [there is no `size-screen` 😅](https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/307)
-- fix: [edge cases with whitespace in `enforces-shorthand`](https://github.com/francoismassart/eslint-plugin-tailwindcss/pull/308)(by [kachkaev](https://github.com/kachkaev) 🙏)
-- fix: [parsing spreads in function call returns](https://github.com/francoismassart/eslint-plugin-tailwindcss/pull/285)(by [egorpavlikhin](https://github.com/egorpavlikhin) 🙏)
-- feat: [support for Tailwind CSS 3.4.0](https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/297)
-- ci: [add github actions workflow](https://github.com/francoismassart/eslint-plugin-tailwindcss/pull/303) (by [nihalgonsalves](https://github.com/nihalgonsalves) 🙏)
-- fix: [bg-center mark as conflicting with bg-[image:xxx]](https://github.com/francoismassart/eslint-plugin-tailwindcss/pull/260)
-- feat: [support enforcing truncate shorthand](https://github.com/francoismassart/eslint-plugin-tailwindcss/pull/255) (by [bezbac](https://github.com/bezbac) 🙏)
-- fix: [parsing spreads in object expressions](https://github.com/francoismassart/eslint-plugin-tailwindcss/pull/251) (by [bezbac](https://github.com/bezbac) 🙏)
-- fix: [do not handle non-ASCII whitespace as separator](https://github.com/francoismassart/eslint-plugin-tailwindcss/pull/246) (by [uhyo](https://github.com/uhyo) 🙏)
-- fix: [prefix support for named group/peer syntax](https://github.com/francoismassart/eslint-plugin-tailwindcss/pull/244) (by [bezbac](https://github.com/bezbac) 🙏)
-- feat: [support tailwind config in typescript](https://github.com/francoismassart/eslint-plugin-tailwindcss/pull/242) (by [quesabe](https://github.com/quesabe) 🙏)
- **You may have to upgrade your Tailwind CSS version to `3.3.2`**
+
-[View all releases on github](https://github.com/francoismassart/eslint-plugin-tailwindcss/releases)
+## Settings
-## Screencasts on our YouTube Channel
-
-| | [ESLint plugin Tailwind CSS](https://www.youtube.com/@eslint-plugin-tailwind-css)
youtube.com/@eslint-plugin-tailwindcss |
-| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-
-## Installation
-
-### 1. Install `eslint` and `eslint-plugin-tailwindcss`
-
-You'll first need to install [ESLint](http://eslint.org):
-
-```
-$ npm i -D eslint eslint-plugin-tailwindcss
-
-```
-
-### 2. Create Configuration file
-
-#### `.eslintrc`
-
-Use .eslintrc.\* file to configure rules in ESLint < v9. See also: https://eslint.org/docs/latest/use/configure/.
-
-```js
-module.exports = {
- root: true,
- extends: ["plugin:tailwindcss/recommended"],
-};
-```
-
-If you would like to know about configuration, Learn more in [ESLint docs](https://eslint.org/docs/latest/use/configure/configuration-files)
-
-#### `eslint.config.js`
-
-Use `eslint.config.js` file to configure rules. This is the default in ESLint v9, but can be used starting from ESLint v8.57.0. See also: https://eslint.org/docs/latest/use/configure/configuration-files-new.
+You should specify settings that will be shared across all the plugin rules. ([More about eslint shared settings](https://eslint.org/docs/latest/use/configure/configuration-files#configuring-shared-settings))
```js
-import tailwind from "eslint-plugin-tailwindcss";
-
-export default [...tailwind.configs["flat/recommended"]];
-```
-
-If you would like to know about configuration, Learn more in [ESLint docs](https://eslint.org/docs/latest/use/configure/configuration-files-new)
-
-### 3. Configure ESLint parsers
-
-Depending on the languages you are using in your project you must tell which parser will analyze your source files.
-
-Our recommendations:
-
-#### For `.eslintrc`
-
-- For `js[x]`, `react`, `ts[x]`:
- - Install the parser: `npm i -D @typescript-eslint/parser`
- - Assign it to your files in `eslintrc`:
- ```json5
- overrides: [
- {
- files: ['*.ts', '*.tsx', '*.js'],
- parser: '@typescript-eslint/parser',
- },
- ],
- ```
-- For `vue.js`:
- - Install the parser: `npm i -D vue-eslint-parser`
- - Assign it to your files in `eslintrc`:
- ```json5
- overrides: [
- {
- files: ['*.vue'],
- parser: 'vue-eslint-parser',
- },
- ],
- ```
-- For `HTML` and similar:
- - Install the parser: `npm i -D @angular-eslint/template-parser`
- - Assign it to your files in `eslintrc`:
- ```json5
- overrides: [
- {
- files: ['*.html', '*.blade.php'],
- parser: '@angular-eslint/template-parser',
- },
- ],
- ```
-
-> We removed the default parsers which were added to `v3.8.2` because it created negative impact on dependencies resolution, bundle size increase and possible conflicts with existing configurations.
-
-#### For `eslint.config.js`
-
-- For `js[x]`, `ts[x]`:
-
- - Install the parser: `npm i -D @eslint/js typescript-eslint`
- - Assign it to your files in `eslint.config.js`:
-
- ```js
- import js from "@eslint/js";
- import ts from "typescript-eslint";
- import tailwind from "eslint-plugin-tailwindcss";
-
- export default [
- // add eslint built-in
- js.configs.recommended,
- // add `typescript-eslint` flat config simply
- // if you would like use more another configuration,
- // see the section: https://typescript-eslint.io/getting-started#details
- ...ts.configs.recommended,
- ...tailwind.configs["flat/recommended"],
- ];
- ```
-
-- For `vue.js`:
-
- - Install the parser: `npm i -D eslint-plugin-vue`
- - Assign it to your files in `eslint.config.js`:
-
- ```js
- import vue from "eslint-plugin-vue";
- import tailwind from "eslint-plugin-tailwindcss";
-
- export default [
- // add `eslint-plugin-vue` flat config simply
- // if you would like use more another configuration,
- // see the section: https://eslint.vuejs.org/user-guide/#bundle-configurations-eslint-config-js
- ...vue.configs["flat/recommended"],
- ...tailwind.configs["flat/recommended"],
- ];
- ```
-
-### 4. Add a npm script
-
-In your `package.json` add one or more script(s) to run eslint targeting your source files:
-
-```json5
-"scripts": {
- "lint": "eslint ./src",
- "lint:debug": "eslint ./src --debug",
- "lint:fix": "eslint ./src --fix"
-},
+// eslint.config.mjs
+{
+ settings: {
+ tailwindcss: {
+ // Attributes/props that could contain Tailwind CSS classes...
+ // Optional, default values: ["class", "className", "ngClass", "@apply"]
+ attributes: ["class"],
+ // The absolute path pointing to you main Tailwind CSS v4 config file.
+ // It must be a `.css` file (v4), not a `.js` file (v3)
+ // REQUIRED, default value will not help
+ cssConfigPath: dirname(fileURLToPath(import.meta.url)) + "/styles/tailwind.css",
+ // Functions/tagFunctions that will be parsed by the plugin.
+ // Optional, default values: ["classnames", "clsx", "ctl", "cva", "tv", "tw"]
+ functions: ["twClasses"]
+ },
+ }
+}
```
-### 5. Run the linting task
-
-`npm run lint` can do the job on demand but you can also get live feedback using [VS Code ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint), **just make sure you restart VS Code** as it can be required for the plugin to work as expected.
+The default settings are exported via the [`DEFAULT_SETTINGS`](src/utils/parse-plugin-settings.ts).
-## More settings
+## Made fro Tailwind CSS v4
-The rules accept settings meant to fit your own choices, make sure to read the [documentation of each rule](https://github.com/francoismassart/eslint-plugin-tailwindcss/tree/master/docs/rules).
+Version 4 of the `eslint-plugin-tailwindcss` is:
-### Optional shared settings
+- re-written from scratch
+- using TypeScript
+- Based as much as possible on internal assets of Tailwind CSS:
+ - via the [`prettier-plugin-tailwindcss` plugin](https://www.npmjs.com/package/prettier-plugin-tailwindcss)
+ - via [`tailwind-api-utils`](https://github.com/hyoban/tailwind-api-utils)
+- only compatible with:
+ - Tailwind CSS v4.x.x
+ - ESLint flat config format
-Most rules share the same settings, instead of duplicating the options all over the place...
+## Status
-You should define the [shared settings](https://eslint.org/docs/user-guide/configuring#adding-shared-settings) that will be shared across all the plugin rules.
+This branch was started back in 2024, and I was quickly stuck while trying to use the internal mechanics of the `tailwindcss` package.
-All these settings already have nice default values that are explained in the documentation.
+Simple tasks, like loading the CSS config, was impossible inside an ESLint plugin because ESLint plugins are synchronous by design while the tailwindcss package uses plenty of async functions.
-#### For `.eslintrc`
-
-FYI, here are the `default` values:
-
-```json5
-{
- settings: {
- tailwindcss: {
- // These are the default values but feel free to customize
- callees: ["classnames", "clsx", "ctl"],
- config: "tailwind.config.js", // returned from `loadConfig()` utility if not provided
- cssFiles: [
- "**/*.css",
- "!**/node_modules",
- "!**/.*",
- "!**/dist",
- "!**/build",
- ],
- cssFilesRefreshRate: 5_000,
- removeDuplicates: true,
- skipClassAttribute: false,
- whitelist: [],
- tags: [], // can be set to e.g. ['tw'] for use in tw`bg-blue`
- classRegex: "^class(Name)?$", // can be modified to support custom attributes. E.g. "^tw$" for `twin.macro`
- },
- },
-}
-```
+😇 Hopefully, [hyoban](https://github.com/hyoban) made [`tailwind-api-utils`](https://github.com/hyoban/tailwind-api-utils) and [demonstrated in a PR](https://github.com/hyoban/eslint-plugin-tailwindcss/pull/3) how I could use it via [`synckit`](https://www.npmjs.com/package/synckit) 👏.
-#### For `eslint.config.js`
+## Work in progress
-```js
-import tailwind from "eslint-plugin-tailwindcss";
+This version is far from finished, yet it is available and open for contributions.
-export default [
- ...tailwind.configs["flat/recommended"],
- {
- settings: {
- tailwindcss: {
- // These are the default values but feel free to customize
- callees: ["classnames", "clsx", "ctl"],
- config: "tailwind.config.js", // returned from `loadConfig()` utility if not provided
- cssFiles: [
- "**/*.css",
- "!**/node_modules",
- "!**/.*",
- "!**/dist",
- "!**/build",
- ],
- cssFilesRefreshRate: 5_000,
- removeDuplicates: true,
- skipClassAttribute: false,
- whitelist: [],
- tags: [], // can be set to e.g. ['tw'] for use in tw`bg-blue`
- classRegex: "^class(Name)?$", // can be modified to support custom attributes. E.g. "^tw$" for `twin.macro`
- },
- },
- },
-];
-```
+### Completed steps
-The plugin will look for each setting in this order and stops searching as soon as it finds the settings:
+- restore the automated tests running on the merge requests of the repo
+- implement and test the usage of `tailwind-api-utils`
+- read the settings from eslint (shared settings & rules settings)
-1. In the rule option argument (rule level)
-2. In the shared settings (plugin level)
-3. Default value of the requested setting (plugin level)...
+### Next steps
-## Upcoming Rules
+- create the config utility
+- implement the `classnames-order` rule and its tests
-- `validate-modifiers`: I don't know if possible, but I'd like to make sure all the modifiers prefixes of a classname are valid e.g. `yolo:bg-red` should throw an error...
+## Contributing
-- `no-redundant-variant`: e.g. avoid `mx-5 sm:mx-5`, no need to redefine `mx` in `sm:` variant as it uses the same value (`5`)
+The project is open to all developers, you can [contribute the `eslint-plugin-tailwindcss`](CONTRIBUTING.md).
-- `only-valid-arbitrary-values`:
+## 🤝 Support `eslint-plugin-tailwindcss`
- - e.g. avoid `top-[42]`, only `0` value can be unitless.
- - e.g. avoid `text-[rgba(10%,20%,30,50%)]`, can't mix `%` and `0-255`.
+| 🥰 How you can support us? | 💪 They did it! |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **Premium Sponsors**
Support us by becoming a sponsor.
[Become a recurring sponsor](https://github.com/sponsors/francoismassart?frequency=recurring) |
|
+| **Current Sponsors**
Any amount is appreciated. |
|
+| **Past sponsors**
Even if this is just a one-time thing.
[Become a backer](https://github.com/sponsors/francoismassart?frequency=one-time) |
|
+| **Contributors**
This project can evolve thanks to all the people who contribute.
You are welcome to [contribute](CONTRIBUTING.md) to this project by reporting issues, feature requests or even opening Pull Requests. | |
+| **Supporters**
Talk about the plugin on your social networks | [Share the word on Bluesky](https://bsky.app/search?q=eslint-plugin-tailwindcss) or [Reach my profile](https://bsky.app/profile/francoismassart.be) |
diff --git a/docs/rules/README.md b/docs/rules/README.md
new file mode 100644
index 00000000..4336a047
--- /dev/null
+++ b/docs/rules/README.md
@@ -0,0 +1,11 @@
+# Be careful when you edit the docs
+
+## Each rule's documentation is partially generated
+
+Running `pnpm docs:init` will create new files if needed.
+
+Running `pnpm docs:update` will update the existing docs.
+
+## Generated sections
+
+The generated sections are surrounded by HTML comments mentioning "auto-generated".
\ No newline at end of file
diff --git a/docs/rules/classnames-order.md b/docs/rules/classnames-order.md
index 5fb6f922..7f015a35 100644
--- a/docs/rules/classnames-order.md
+++ b/docs/rules/classnames-order.md
@@ -1,77 +1,13 @@
-# Use a consistent orders for the Tailwind CSS classnames, based on the official order (tailwindcss/classnames-order)
+# Enforces a consistent order for the Tailwind CSS classnames, based on the compiler
-Enforces a consistent order of the Tailwind CSS classnames and its variants.
+🔧💡 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) and manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
-> **Note**: Since version `3.6.0`, the ordering is solely done using the [order process from the official `prettier-plugin-tailwindcss`](https://tailwindcss.com/blog/automatic-class-sorting-with-prettier#how-classes-are-sorted)
+
-## Rule Details
+## Options
-Examples of **incorrect** code for this rule:
+
-```html
-