Skip to content

Commit 07302ff

Browse files
feat: new rule no-unnecessary-arbitrary-value
commit 917a18572ee60be710480a385550593bb0f2fcc9 Author: francoismassart <francois.massart@gmail.com> Date: Sat Feb 24 18:20:04 2024 +0100 3.15.0-beta.3 commit a5c052a458eacf2e5de6c1cfa7046f4421ea06d1 Author: francoismassart <francois.massart@gmail.com> Date: Sat Feb 24 18:19:29 2024 +0100 fix: issues with TemplateLiteral and range commit 29f692d3df5cee22fef007c769fa2720c97636aa Author: francoismassart <francois.massart@gmail.com> Date: Fri Feb 23 12:06:28 2024 +0100 3.15.0-beta.2 commit fe58cb6974176a5b1be14593545d87c87d3047ca Author: francoismassart <francois.massart@gmail.com> Date: Fri Feb 23 12:06:25 2024 +0100 fix: prevent error on undefined commit 7bfb7ac749f41a62a30fbd54540cb2d12c1720d5 Author: francoismassart <francois.massart@gmail.com> Date: Fri Feb 23 11:20:59 2024 +0100 3.15.0-beta.1 commit eff6483792944db38cac9c82e7bb9f5597c30a7c Author: francoismassart <francois.massart@gmail.com> Date: Fri Feb 23 11:20:44 2024 +0100 fix: broken range commit a6d8e8230a11f5d8aa3bae05f5ba4009c18b7ca6 Author: francoismassart <francois.massart@gmail.com> Date: Fri Feb 23 10:01:25 2024 +0100 3.15.0-beta.0 commit 6be63b6bc1f6ff258a19cb52a5cd095da5ffa7df Author: francoismassart <francois.massart@gmail.com> Date: Fri Feb 23 09:16:45 2024 +0100 chore: add no-unnecessary-arbitrary-value rule to recommended preset commit cf51ad020396f195bbcf0a480b6c480c621c190e Author: francoismassart <francois.massart@gmail.com> Date: Thu Feb 22 17:23:04 2024 +0100 feat: new rule no-unnecessary-arbitrary-value
1 parent e9c42d8 commit 07302ff

File tree

11 files changed

+925
-21
lines changed

11 files changed

+925
-21
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Learn more about each supported rules by reading their documentation:
2222
- [`no-arbitrary-value`](docs/rules/no-arbitrary-value.md): forbid using arbitrary values in classnames (turned off by default)
2323
- [`no-custom-classname`](docs/rules/no-custom-classname.md): only allow classnames from Tailwind CSS and the values from the `whitelist` option
2424
- [`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.
25+
- [`no-unnecessary-arbitrary-value`](docs/rules/no-unnecessary-arbitrary-value.md): e.g. replacing `m-[1.25rem]` by its configuration based classname `m-5`
2526

2627
Using ESLint extension for Visual Studio Code, you will get these messages
2728
![detected-errors](.github/output.png)
@@ -40,6 +41,7 @@ You can can the same information on your favorite command line software as well.
4041

4142
## Latest changelog
4243

44+
- feat: new rule [**`no-unnecessary-arbitrary-value`**](docs/rules/no-unnecessary-arbitrary-value.md) 🎉
4345
- fix: retro compatibility for older Tailwind CSS (before typescript config)
4446
- fix: [composable touch action classnames](https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/293)
4547
- fix: [`shadow-md` + `shadow-[#color]`can be used together 🤝](https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/298)
@@ -215,5 +217,3 @@ The plugin will look for each setting in this order and stops searching as soon
215217

216218
- e.g. avoid `top-[42]`, only `0` value can be unitless.
217219
- e.g. avoid `text-[rgba(10%,20%,30,50%)]`, can't mix `%` and `0-255`.
218-
219-
- `no-unnecessary-arbitrary-value`: e.g. replacing `h-[0]` by its configuration based classname `h-0`.
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Avoid unjustified arbitrary classnames (no-unnecessary-arbitrary-value)
2+
3+
Arbitrary values are handy but you should stick to regular classnames defined in the Tailwind CSS config file as much as you can.
4+
5+
## Rule Details
6+
7+
Given the default configuration in which `h-auto` exists... There is no need to use an arbitrary classname.
8+
9+
Examples of **incorrect** code for this rule:
10+
11+
```html
12+
<div class="h-[auto]">height</div>
13+
```
14+
15+
Examples of **correct** code for this rule:
16+
17+
```html
18+
<div class="h-auto">height</div>
19+
```
20+
21+
### The rule can handle `0` values with or without their units
22+
23+
Given the default configuration in which `h-0` exists... There is no need to use an arbitrary classname.
24+
25+
Examples of **incorrect** code with `0` based value:
26+
27+
```html
28+
<div class="h-[0%]">Use `h-0` (`0px`) instead</div>
29+
```
30+
31+
Examples of **correct** code with `0` based value:
32+
33+
```html
34+
<div class="h-0">Use `h-0` (`0px`) instead</div>
35+
```
36+
37+
### The rule can handle negative & double negative
38+
39+
Given the default configuration... There is no need to use an arbitrary classname.
40+
41+
Examples of **incorrect** code for negative arbitrary values:
42+
43+
```html
44+
<div class="m-[-1.25rem] -z-[-10]">[Double] negative values</div>
45+
```
46+
47+
Examples of **correct** code for negative arbitrary values:
48+
49+
```html
50+
<div class="-m-5 z-10">[Double] negative values</div>
51+
```
52+
53+
### Options
54+
55+
```js
56+
...
57+
"tailwindcss/no-unnecessary-arbitrary-value": [<enabled>, {
58+
"callees": Array<string>,
59+
"config": <string>|<object>,
60+
"skipClassAttribute": <boolean>,
61+
"tags": Array<string>,
62+
}]
63+
...
64+
```
65+
66+
### `callees` (default: `["classnames", "clsx", "ctl", "cva", "tv"]`)
67+
68+
If you use some utility library like [@netlify/classnames-template-literals](https://github.com/netlify/classnames-template-literals), you can add its name to the list to make sure it gets parsed by this rule.
69+
70+
For best results, gather the declarative classnames together, avoid mixing conditional classnames in between, move them at the end.
71+
72+
### `ignoredKeys` (default: `["compoundVariants", "defaultVariants"]`)
73+
74+
Using libraries like `cva`, some of its object keys are not meant to contain classnames in its value(s).
75+
You can specify which key(s) won't be parsed by the plugin using this setting.
76+
For example, `cva` has `compoundVariants` and `defaultVariants`.
77+
NB: As `compoundVariants` can have classnames inside its `class` property, you can also use a callee to make sure this inner part gets parsed while its parent is ignored.
78+
79+
### `config` (default: generated by `tailwindcss/lib/lib/load-config`)
80+
81+
By default the plugin will try to load the file returned by the official `loadConfig()` utility.
82+
83+
This allows the plugin to use your customized `colors`, `spacing`, `screens`...
84+
85+
You can provide another path or filename for your Tailwind CSS config file like `"config/tailwind.js"`.
86+
87+
If the external file cannot be loaded (e.g. incorrect path or deleted file), an empty object `{}` will be used instead.
88+
89+
It is also possible to directly inject a configuration as plain `object` like `{ prefix: "tw-", theme: { ... } }`.
90+
91+
Finally, the plugin will [merge the provided configuration](https://tailwindcss.com/docs/configuration#referencing-in-java-script) with [Tailwind CSS's default configuration](https://github.com/tailwindlabs/tailwindcss/blob/master/stubs/defaultConfig.stub.js).
92+
93+
### `skipClassAttribute` (default: `false`)
94+
95+
Set `skipClassAttribute` to `true` if you only want to lint the classnames inside one of the `callees`.
96+
While, this will avoid linting the `class` and `className` attributes, it will still lint matching `callees` inside of these attributes.
97+
98+
### `tags` (default: `[]`)
99+
100+
Optional, if you are using tagged templates, you should provide the tags in this array.
101+
102+
### `classRegex` (default: `"^class(Name)?$"`)
103+
104+
Optional, can be used to support custom attributes
105+
106+
## Further Reading
107+
108+
If there is exactly one equivalent regular classname, this rule will fix the issue for you by replacing the arbitrary classnames by their unique substitutes.
109+
110+
But if there are several possible substitutes for an arbitrary classname, then you can manually perform the replacement.

0 commit comments

Comments
 (0)