@maz-ui/stylelint-config 5.0.0-canary.ef64a02.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -2
- package/dist/index.d.mts +99 -16
- package/dist/index.d.ts +99 -16
- package/dist/index.mjs +203 -25
- package/package.json +17 -16
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Reusable [Stylelint](https://stylelint.io/) configuration for Vue/Nuxt/JS/TS pro
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- 🚀 **Stylelint Standard base** — opinionated, maintained by the Stylelint team
|
|
8
|
-
- 🎨 **Tailwind v4** — at-rule whitelist, `
|
|
8
|
+
- 🎨 **Tailwind v4** — at-rule whitelist, validation rules via `stylelint-plugin-tailwindcss` (3 strictness levels)
|
|
9
9
|
- 🌍 **RTL-friendly** — logical properties via `stylelint-use-logical-spec`
|
|
10
10
|
- 🔠 **Property ordering** — Recess-based by default, alphabetical or off
|
|
11
11
|
- 💚 **Vue/HTML/SCSS** — auto-detected from your `package.json`
|
|
@@ -34,7 +34,7 @@ Vue, Tailwind and SCSS are auto-detected from your `package.json`.
|
|
|
34
34
|
defineConfig({
|
|
35
35
|
vue: true, // auto-detected from `vue`/`nuxt` deps
|
|
36
36
|
html: false,
|
|
37
|
-
tailwind: true, // auto-detected from `tailwindcss` dep
|
|
37
|
+
tailwind: true, // auto-detected from `tailwindcss` dep — see "Tailwind" below
|
|
38
38
|
scss: false, // auto-detected from `sass`/`sass-embedded`/`node-sass`
|
|
39
39
|
logical: true, // recommend logical CSS properties (RTL-friendly)
|
|
40
40
|
order: 'recess', // 'recess' | 'alphabetical' | false
|
|
@@ -46,9 +46,81 @@ defineConfig({
|
|
|
46
46
|
overrides: [
|
|
47
47
|
{ files: ['**/*.legacy.css'], rules: { 'color-no-invalid-hex': null } },
|
|
48
48
|
],
|
|
49
|
+
extends: ['stylelint-config-clean-order'], // layer extra shareable configs
|
|
50
|
+
logLevel: 'default', // 'silent' | 'default' | 'debug' | 'verbose' — see "Logging" below
|
|
49
51
|
})
|
|
50
52
|
```
|
|
51
53
|
|
|
54
|
+
### Logging
|
|
55
|
+
|
|
56
|
+
The preset can log what it resolves and applies, which is handy when you don't understand why a rule is on or off. Pass a `logLevel` (powered by `@maz-ui/node`'s consola-based logger):
|
|
57
|
+
|
|
58
|
+
| Value | What you see |
|
|
59
|
+
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
60
|
+
| `'silent'` | Nothing. |
|
|
61
|
+
| `'default'` _(default)_ | A titled box summarizing the resolved support (vue, tailwind, scss, html, logical, order) and whether each value was auto-detected or explicit. |
|
|
62
|
+
| `'debug'` | Above + each plugin / extends / overrides addition (`Loaded stylelint-use-logical-spec`, `Tailwind: loaded N plugins for "minimal" policy`, …). |
|
|
63
|
+
| `'verbose'` | Above + final shape (full `extends` list, plugin/rule/override/ignore counts). |
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
defineConfig({ logLevel: 'debug' })
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Tailwind support
|
|
70
|
+
|
|
71
|
+
| Value | Behavior |
|
|
72
|
+
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
73
|
+
| `true` _(or auto-detected)_ | Same as `'minimal'`. |
|
|
74
|
+
| `'minimal'` _(default when on)_ | At-rule whitelist + `import-notation: 'string'` + `at-rule-no-deprecated`. **No plugin loaded.** |
|
|
75
|
+
| `'recommended'` | `'minimal'` + `stylelint-plugin-tailwindcss`'s recommended preset (`no-invalid-apply`, `no-invalid-theme-function`, `no-atomic-class`, `no-apply`, `no-arbitrary-value`). |
|
|
76
|
+
| `'strict'` | `'recommended'` + `no-theme-function`, `no-screen-directive`, `no-tailwind-directive`, `no-import-directive`, `no-css-layer`. |
|
|
77
|
+
| `false` | Tailwind support disabled entirely. |
|
|
78
|
+
|
|
79
|
+
> [!IMPORTANT]
|
|
80
|
+
> The plugin rules in `'recommended'` and `'strict'` auto-resolve your project's Tailwind runtime from each linted file's path. Projects with a v4 prefix (`maz:`, `tw:`, …), a non-standard entry CSS, or a monorepo layout where Tailwind isn't where the plugin expects produce false positives. **`'minimal'` is the safe default.** Opt into `'recommended'` only if your project sits in the plugin's happy path.
|
|
81
|
+
|
|
82
|
+
Plugin rules come from [`stylelint-plugin-tailwindcss`](https://github.com/sonofmagic/dev-configs/tree/main/packages/stylelint-plugin-tailwindcss) and support both Tailwind v3 and v4.
|
|
83
|
+
|
|
84
|
+
### Property ordering
|
|
85
|
+
|
|
86
|
+
| Value | Behavior |
|
|
87
|
+
| ---------------- | -------------------------------------------------------------------------- |
|
|
88
|
+
| `'recess'` | Extends `stylelint-config-recess-order` (default). |
|
|
89
|
+
| `'alphabetical'` | Loads `stylelint-order` and enables `order/properties-alphabetical-order`. |
|
|
90
|
+
| `false` | No ordering rules. |
|
|
91
|
+
|
|
92
|
+
To swap recess for another shareable order config (e.g. `stylelint-config-clean-order`), disable the built-in strategy and extend yours:
|
|
93
|
+
|
|
94
|
+
```js
|
|
95
|
+
defineConfig({
|
|
96
|
+
order: false,
|
|
97
|
+
extends: ['stylelint-config-clean-order'],
|
|
98
|
+
})
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Layering shareable configs
|
|
102
|
+
|
|
103
|
+
The `extends` option appends entries **after** the built-ins, so user configs win Stylelint's cascade. Common cases:
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
defineConfig({
|
|
107
|
+
extends: [
|
|
108
|
+
'stylelint-config-clean-order', // alternative property order
|
|
109
|
+
'@stylistic/stylelint-config', // restore stylistic rules retired from core
|
|
110
|
+
],
|
|
111
|
+
})
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Auto-detection caveat (monorepos)
|
|
115
|
+
|
|
116
|
+
Auto-detection reads the `package.json` in `process.cwd()` only. In a monorepo where `tailwindcss`, `vue` or `sass` are hoisted to the root and missing from a sub-package's `package.json`, detection fails when Stylelint runs from that sub-package.
|
|
117
|
+
|
|
118
|
+
In monorepos, **set the relevant flags explicitly**:
|
|
119
|
+
|
|
120
|
+
```js
|
|
121
|
+
defineConfig({ vue: true, tailwind: true, scss: false })
|
|
122
|
+
```
|
|
123
|
+
|
|
52
124
|
## Documentation
|
|
53
125
|
|
|
54
126
|
See the full documentation at [maz-ui.com/ecosystem/stylelint-config](https://maz-ui.com/ecosystem/stylelint-config).
|
package/dist/index.d.mts
CHANGED
|
@@ -1,15 +1,25 @@
|
|
|
1
|
-
import { Config } from 'stylelint';
|
|
1
|
+
import { Config as Config$1 } from 'stylelint';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Mirror of `@maz-ui/node`'s LogLevel — kept inline here to avoid making this
|
|
5
|
+
* preset depend on `@maz-ui/node`, which would create a build cycle (the
|
|
6
|
+
* `eslint.config.ts` of `@maz-ui/node` imports `@maz-ui/eslint-config`, which
|
|
7
|
+
* itself depends on `@maz-ui/node` for the same logger). Direct usage of
|
|
8
|
+
* `consola` keeps the dependency graph acyclic.
|
|
9
|
+
*/
|
|
10
|
+
type LogLevel = 'silent' | 'error' | 'warning' | 'normal' | 'default' | 'debug' | 'trace' | 'verbose';
|
|
11
|
+
|
|
12
|
+
type StylelintConfig = Config$1;
|
|
13
|
+
type StylelintRules = Config$1['rules'];
|
|
14
|
+
type StylelintOverride = NonNullable<Config$1['overrides']>[number];
|
|
6
15
|
/**
|
|
7
16
|
* Property order strategy.
|
|
8
17
|
*
|
|
9
18
|
* - `'recess'`: Recess-based ordering (`stylelint-config-recess-order`).
|
|
10
19
|
* Pragmatic, widely adopted, groups related properties together.
|
|
11
|
-
* - `'alphabetical'`: Strict A→Z ordering
|
|
12
|
-
*
|
|
20
|
+
* - `'alphabetical'`: Strict A→Z ordering via `stylelint-order`'s
|
|
21
|
+
* `order/properties-alphabetical-order` rule. Easy mental model, slightly
|
|
22
|
+
* worse diffs than recess.
|
|
13
23
|
* - `false`: Disable ordering rules entirely.
|
|
14
24
|
*/
|
|
15
25
|
type StylelintOrderStrategy = 'recess' | 'alphabetical' | false;
|
|
@@ -32,13 +42,23 @@ interface MazStylelintOptions {
|
|
|
32
42
|
/**
|
|
33
43
|
* Enable Tailwind CSS support — whitelists the v4 at-rules
|
|
34
44
|
* (`@apply`, `@reference`, `@variant`, `@theme`, `@layer`, `@utility`,
|
|
35
|
-
* `@source`, `@custom-variant`, `@tailwind`, `@screen`, `@starting-style`)
|
|
36
|
-
*
|
|
45
|
+
* `@source`, `@custom-variant`, `@tailwind`, `@screen`, `@starting-style`),
|
|
46
|
+
* relaxes patterns that conflict with Tailwind's prefixed classes, and
|
|
47
|
+
* loads `stylelint-plugin-tailwindcss` with the requested policy.
|
|
37
48
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
49
|
+
* Accepts:
|
|
50
|
+
* - `true` or auto-detected (`tailwindcss` in `package.json`): equivalent to
|
|
51
|
+
* `'minimal'`.
|
|
52
|
+
* - `'minimal'`: validation-only — flags typo'd utilities in `@apply`
|
|
53
|
+
* (`no-invalid-apply`) and invalid `theme(...)` paths
|
|
54
|
+
* (`no-invalid-theme-function`). No opinion on authoring style.
|
|
55
|
+
* - `'recommended'`: the plugin's recommended preset — also bans atomic
|
|
56
|
+
* classes in authored CSS, `@apply`, and arbitrary values.
|
|
57
|
+
* - `'strict'`: recommended plus architecture-level checks (no `theme()`,
|
|
58
|
+
* `@screen`, `@tailwind`, `@import`, `@layer`).
|
|
59
|
+
* - `false`: disable Tailwind support entirely.
|
|
40
60
|
*/
|
|
41
|
-
tailwind?: boolean;
|
|
61
|
+
tailwind?: boolean | 'minimal' | 'recommended' | 'strict';
|
|
42
62
|
/**
|
|
43
63
|
* Enable SCSS support — extends `stylelint-config-recommended-scss` and
|
|
44
64
|
* registers `postcss-scss` for `.scss` files.
|
|
@@ -104,7 +124,36 @@ interface MazStylelintOptions {
|
|
|
104
124
|
/**
|
|
105
125
|
* Additional plugins merged on top of the resolved configuration.
|
|
106
126
|
*/
|
|
107
|
-
plugins?: NonNullable<Config['plugins']>;
|
|
127
|
+
plugins?: NonNullable<Config$1['plugins']>;
|
|
128
|
+
/**
|
|
129
|
+
* Additional shareable configs to extend, appended after the built-in
|
|
130
|
+
* extends so user configs win the cascade (e.g. `stylelint-config-clean-order`
|
|
131
|
+
* to replace recess ordering, or `stylelint-config-tailwindcss` for the
|
|
132
|
+
* official Tailwind plugin rules).
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```ts
|
|
136
|
+
* defineConfig({
|
|
137
|
+
* order: false,
|
|
138
|
+
* extends: ['stylelint-config-clean-order'],
|
|
139
|
+
* })
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
extends?: string[];
|
|
143
|
+
/**
|
|
144
|
+
* Verbosity of the logs emitted while resolving the config. Defaults to
|
|
145
|
+
* `'default'` so the resolved configuration box is shown when the preset
|
|
146
|
+
* loads. Set to `'silent'` to hide it, or `'debug'` / `'verbose'` to dig
|
|
147
|
+
* deeper.
|
|
148
|
+
*
|
|
149
|
+
* - `'silent'`: nothing is printed.
|
|
150
|
+
* - `'default'` *(default)*: a titled box summarizing the resolved support
|
|
151
|
+
* (auto-detection results, chosen Tailwind policy, …).
|
|
152
|
+
* - `'debug'`: also logs each plugin / extends / overrides addition.
|
|
153
|
+
* - `'verbose'`: also logs the final shape (extends list, rule count,
|
|
154
|
+
* ignore globs).
|
|
155
|
+
*/
|
|
156
|
+
logLevel?: LogLevel;
|
|
108
157
|
}
|
|
109
158
|
|
|
110
159
|
/**
|
|
@@ -121,7 +170,7 @@ declare const baseRules: StylelintRules;
|
|
|
121
170
|
* Glob patterns Stylelint should ignore by default. Mirrors the eslint-config
|
|
122
171
|
* defaults plus a few CSS-specific build outputs.
|
|
123
172
|
*/
|
|
124
|
-
declare const GLOBAL_IGNORES:
|
|
173
|
+
declare const GLOBAL_IGNORES: Config;
|
|
125
174
|
|
|
126
175
|
/**
|
|
127
176
|
* Flag every physical property/value that has a logical equivalent.
|
|
@@ -139,7 +188,7 @@ declare const logicalRules: StylelintRules;
|
|
|
139
188
|
* so projects that use SCSS *and* Tailwind don't get false positives from
|
|
140
189
|
* `scss/at-rule-no-unknown`.
|
|
141
190
|
*/
|
|
142
|
-
declare function scssRules(includeTailwind: boolean): StylelintRules;
|
|
191
|
+
declare function scssRules(includeTailwind: boolean | string): StylelintRules;
|
|
143
192
|
|
|
144
193
|
/**
|
|
145
194
|
* Tailwind v4 at-rules. New ones can be added without bumping a major
|
|
@@ -148,7 +197,7 @@ declare function scssRules(includeTailwind: boolean): StylelintRules;
|
|
|
148
197
|
*
|
|
149
198
|
* Source: https://tailwindcss.com/docs (v4 directives)
|
|
150
199
|
*/
|
|
151
|
-
declare const TAILWIND_AT_RULES:
|
|
200
|
+
declare const TAILWIND_AT_RULES: readonly ["theme", "utility", "source", "variant", "custom-variant", "reference", "apply", "layer", "screen", "starting-style", "tailwind", "config", "plugin", "responsive"];
|
|
152
201
|
/**
|
|
153
202
|
* Rules to whitelist Tailwind's at-rules and relax patterns that conflict
|
|
154
203
|
* with Tailwind-prefixed classes (`maz:flex`, `dark:bg-…`).
|
|
@@ -167,6 +216,40 @@ declare const tailwindRules: StylelintRules;
|
|
|
167
216
|
* recommended config.
|
|
168
217
|
*/
|
|
169
218
|
declare const tailwindAtRuleNoUnknown: StylelintRules;
|
|
219
|
+
/**
|
|
220
|
+
* No plugin rules. `'minimal'` only ships the at-rule whitelist + a couple
|
|
221
|
+
* of CSS-level rules (`import-notation`, `at-rule-no-deprecated`) — no
|
|
222
|
+
* runtime Tailwind validation.
|
|
223
|
+
*
|
|
224
|
+
* Why empty: the plugin's validation rules (`no-invalid-apply`,
|
|
225
|
+
* `no-invalid-theme-function`) auto-resolve the project's Tailwind runtime
|
|
226
|
+
* from the linted file's path. Projects with a v4 prefix (`maz:`),
|
|
227
|
+
* non-standard entry CSS, or workspace layouts where Tailwind isn't where
|
|
228
|
+
* the plugin expects produce floods of false positives. Loading these
|
|
229
|
+
* rules without a way to scope them is hostile by default.
|
|
230
|
+
*
|
|
231
|
+
* Opt in to `'recommended'` if your project lives in the plugin's happy
|
|
232
|
+
* path.
|
|
233
|
+
*/
|
|
234
|
+
declare const tailwindPluginMinimal: StylelintRules;
|
|
235
|
+
/**
|
|
236
|
+
* Plugin's recommended preset — `no-invalid-apply` and
|
|
237
|
+
* `no-invalid-theme-function` (validation), plus policies that discourage
|
|
238
|
+
* utility-first patterns inside authored CSS (`.flex { … }`, `@apply`,
|
|
239
|
+
* arbitrary values).
|
|
240
|
+
*
|
|
241
|
+
* Opt-in only: the validation rules need to resolve your Tailwind runtime
|
|
242
|
+
* from the linted file's path; if your project has a custom prefix, an
|
|
243
|
+
* unusual entry CSS or sits in a monorepo, expect false positives.
|
|
244
|
+
*/
|
|
245
|
+
declare const tailwindPluginRecommended: StylelintRules;
|
|
246
|
+
/**
|
|
247
|
+
* Plugin's strict preset — adds architecture-level checks on top of
|
|
248
|
+
* recommended (no `theme()`, no `@screen`, no `@tailwind`, no `@import`,
|
|
249
|
+
* no `@layer`). Suited to projects that strictly separate utility tokens
|
|
250
|
+
* from authored CSS.
|
|
251
|
+
*/
|
|
252
|
+
declare const tailwindPluginStrict: StylelintRules;
|
|
170
253
|
|
|
171
254
|
/**
|
|
172
255
|
* Build a Stylelint config tailored for Vue/Nuxt/JS/TS/Tailwind projects.
|
|
@@ -192,5 +275,5 @@ declare const tailwindAtRuleNoUnknown: StylelintRules;
|
|
|
192
275
|
*/
|
|
193
276
|
declare function defineConfig(options?: MazStylelintOptions): StylelintConfig;
|
|
194
277
|
|
|
195
|
-
export { GLOBAL_IGNORES, TAILWIND_AT_RULES, baseRules, defineConfig, logicalRules, scssRules, tailwindAtRuleNoUnknown, tailwindRules };
|
|
278
|
+
export { GLOBAL_IGNORES, TAILWIND_AT_RULES, baseRules, defineConfig, logicalRules, scssRules, tailwindAtRuleNoUnknown, tailwindPluginMinimal, tailwindPluginRecommended, tailwindPluginStrict, tailwindRules };
|
|
196
279
|
export type { MazStylelintOptions, StylelintConfig, StylelintOrderStrategy, StylelintOverride, StylelintRules };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,25 @@
|
|
|
1
|
-
import { Config } from 'stylelint';
|
|
1
|
+
import { Config as Config$1 } from 'stylelint';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Mirror of `@maz-ui/node`'s LogLevel — kept inline here to avoid making this
|
|
5
|
+
* preset depend on `@maz-ui/node`, which would create a build cycle (the
|
|
6
|
+
* `eslint.config.ts` of `@maz-ui/node` imports `@maz-ui/eslint-config`, which
|
|
7
|
+
* itself depends on `@maz-ui/node` for the same logger). Direct usage of
|
|
8
|
+
* `consola` keeps the dependency graph acyclic.
|
|
9
|
+
*/
|
|
10
|
+
type LogLevel = 'silent' | 'error' | 'warning' | 'normal' | 'default' | 'debug' | 'trace' | 'verbose';
|
|
11
|
+
|
|
12
|
+
type StylelintConfig = Config$1;
|
|
13
|
+
type StylelintRules = Config$1['rules'];
|
|
14
|
+
type StylelintOverride = NonNullable<Config$1['overrides']>[number];
|
|
6
15
|
/**
|
|
7
16
|
* Property order strategy.
|
|
8
17
|
*
|
|
9
18
|
* - `'recess'`: Recess-based ordering (`stylelint-config-recess-order`).
|
|
10
19
|
* Pragmatic, widely adopted, groups related properties together.
|
|
11
|
-
* - `'alphabetical'`: Strict A→Z ordering
|
|
12
|
-
*
|
|
20
|
+
* - `'alphabetical'`: Strict A→Z ordering via `stylelint-order`'s
|
|
21
|
+
* `order/properties-alphabetical-order` rule. Easy mental model, slightly
|
|
22
|
+
* worse diffs than recess.
|
|
13
23
|
* - `false`: Disable ordering rules entirely.
|
|
14
24
|
*/
|
|
15
25
|
type StylelintOrderStrategy = 'recess' | 'alphabetical' | false;
|
|
@@ -32,13 +42,23 @@ interface MazStylelintOptions {
|
|
|
32
42
|
/**
|
|
33
43
|
* Enable Tailwind CSS support — whitelists the v4 at-rules
|
|
34
44
|
* (`@apply`, `@reference`, `@variant`, `@theme`, `@layer`, `@utility`,
|
|
35
|
-
* `@source`, `@custom-variant`, `@tailwind`, `@screen`, `@starting-style`)
|
|
36
|
-
*
|
|
45
|
+
* `@source`, `@custom-variant`, `@tailwind`, `@screen`, `@starting-style`),
|
|
46
|
+
* relaxes patterns that conflict with Tailwind's prefixed classes, and
|
|
47
|
+
* loads `stylelint-plugin-tailwindcss` with the requested policy.
|
|
37
48
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
49
|
+
* Accepts:
|
|
50
|
+
* - `true` or auto-detected (`tailwindcss` in `package.json`): equivalent to
|
|
51
|
+
* `'minimal'`.
|
|
52
|
+
* - `'minimal'`: validation-only — flags typo'd utilities in `@apply`
|
|
53
|
+
* (`no-invalid-apply`) and invalid `theme(...)` paths
|
|
54
|
+
* (`no-invalid-theme-function`). No opinion on authoring style.
|
|
55
|
+
* - `'recommended'`: the plugin's recommended preset — also bans atomic
|
|
56
|
+
* classes in authored CSS, `@apply`, and arbitrary values.
|
|
57
|
+
* - `'strict'`: recommended plus architecture-level checks (no `theme()`,
|
|
58
|
+
* `@screen`, `@tailwind`, `@import`, `@layer`).
|
|
59
|
+
* - `false`: disable Tailwind support entirely.
|
|
40
60
|
*/
|
|
41
|
-
tailwind?: boolean;
|
|
61
|
+
tailwind?: boolean | 'minimal' | 'recommended' | 'strict';
|
|
42
62
|
/**
|
|
43
63
|
* Enable SCSS support — extends `stylelint-config-recommended-scss` and
|
|
44
64
|
* registers `postcss-scss` for `.scss` files.
|
|
@@ -104,7 +124,36 @@ interface MazStylelintOptions {
|
|
|
104
124
|
/**
|
|
105
125
|
* Additional plugins merged on top of the resolved configuration.
|
|
106
126
|
*/
|
|
107
|
-
plugins?: NonNullable<Config['plugins']>;
|
|
127
|
+
plugins?: NonNullable<Config$1['plugins']>;
|
|
128
|
+
/**
|
|
129
|
+
* Additional shareable configs to extend, appended after the built-in
|
|
130
|
+
* extends so user configs win the cascade (e.g. `stylelint-config-clean-order`
|
|
131
|
+
* to replace recess ordering, or `stylelint-config-tailwindcss` for the
|
|
132
|
+
* official Tailwind plugin rules).
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```ts
|
|
136
|
+
* defineConfig({
|
|
137
|
+
* order: false,
|
|
138
|
+
* extends: ['stylelint-config-clean-order'],
|
|
139
|
+
* })
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
extends?: string[];
|
|
143
|
+
/**
|
|
144
|
+
* Verbosity of the logs emitted while resolving the config. Defaults to
|
|
145
|
+
* `'default'` so the resolved configuration box is shown when the preset
|
|
146
|
+
* loads. Set to `'silent'` to hide it, or `'debug'` / `'verbose'` to dig
|
|
147
|
+
* deeper.
|
|
148
|
+
*
|
|
149
|
+
* - `'silent'`: nothing is printed.
|
|
150
|
+
* - `'default'` *(default)*: a titled box summarizing the resolved support
|
|
151
|
+
* (auto-detection results, chosen Tailwind policy, …).
|
|
152
|
+
* - `'debug'`: also logs each plugin / extends / overrides addition.
|
|
153
|
+
* - `'verbose'`: also logs the final shape (extends list, rule count,
|
|
154
|
+
* ignore globs).
|
|
155
|
+
*/
|
|
156
|
+
logLevel?: LogLevel;
|
|
108
157
|
}
|
|
109
158
|
|
|
110
159
|
/**
|
|
@@ -121,7 +170,7 @@ declare const baseRules: StylelintRules;
|
|
|
121
170
|
* Glob patterns Stylelint should ignore by default. Mirrors the eslint-config
|
|
122
171
|
* defaults plus a few CSS-specific build outputs.
|
|
123
172
|
*/
|
|
124
|
-
declare const GLOBAL_IGNORES:
|
|
173
|
+
declare const GLOBAL_IGNORES: Config;
|
|
125
174
|
|
|
126
175
|
/**
|
|
127
176
|
* Flag every physical property/value that has a logical equivalent.
|
|
@@ -139,7 +188,7 @@ declare const logicalRules: StylelintRules;
|
|
|
139
188
|
* so projects that use SCSS *and* Tailwind don't get false positives from
|
|
140
189
|
* `scss/at-rule-no-unknown`.
|
|
141
190
|
*/
|
|
142
|
-
declare function scssRules(includeTailwind: boolean): StylelintRules;
|
|
191
|
+
declare function scssRules(includeTailwind: boolean | string): StylelintRules;
|
|
143
192
|
|
|
144
193
|
/**
|
|
145
194
|
* Tailwind v4 at-rules. New ones can be added without bumping a major
|
|
@@ -148,7 +197,7 @@ declare function scssRules(includeTailwind: boolean): StylelintRules;
|
|
|
148
197
|
*
|
|
149
198
|
* Source: https://tailwindcss.com/docs (v4 directives)
|
|
150
199
|
*/
|
|
151
|
-
declare const TAILWIND_AT_RULES:
|
|
200
|
+
declare const TAILWIND_AT_RULES: readonly ["theme", "utility", "source", "variant", "custom-variant", "reference", "apply", "layer", "screen", "starting-style", "tailwind", "config", "plugin", "responsive"];
|
|
152
201
|
/**
|
|
153
202
|
* Rules to whitelist Tailwind's at-rules and relax patterns that conflict
|
|
154
203
|
* with Tailwind-prefixed classes (`maz:flex`, `dark:bg-…`).
|
|
@@ -167,6 +216,40 @@ declare const tailwindRules: StylelintRules;
|
|
|
167
216
|
* recommended config.
|
|
168
217
|
*/
|
|
169
218
|
declare const tailwindAtRuleNoUnknown: StylelintRules;
|
|
219
|
+
/**
|
|
220
|
+
* No plugin rules. `'minimal'` only ships the at-rule whitelist + a couple
|
|
221
|
+
* of CSS-level rules (`import-notation`, `at-rule-no-deprecated`) — no
|
|
222
|
+
* runtime Tailwind validation.
|
|
223
|
+
*
|
|
224
|
+
* Why empty: the plugin's validation rules (`no-invalid-apply`,
|
|
225
|
+
* `no-invalid-theme-function`) auto-resolve the project's Tailwind runtime
|
|
226
|
+
* from the linted file's path. Projects with a v4 prefix (`maz:`),
|
|
227
|
+
* non-standard entry CSS, or workspace layouts where Tailwind isn't where
|
|
228
|
+
* the plugin expects produce floods of false positives. Loading these
|
|
229
|
+
* rules without a way to scope them is hostile by default.
|
|
230
|
+
*
|
|
231
|
+
* Opt in to `'recommended'` if your project lives in the plugin's happy
|
|
232
|
+
* path.
|
|
233
|
+
*/
|
|
234
|
+
declare const tailwindPluginMinimal: StylelintRules;
|
|
235
|
+
/**
|
|
236
|
+
* Plugin's recommended preset — `no-invalid-apply` and
|
|
237
|
+
* `no-invalid-theme-function` (validation), plus policies that discourage
|
|
238
|
+
* utility-first patterns inside authored CSS (`.flex { … }`, `@apply`,
|
|
239
|
+
* arbitrary values).
|
|
240
|
+
*
|
|
241
|
+
* Opt-in only: the validation rules need to resolve your Tailwind runtime
|
|
242
|
+
* from the linted file's path; if your project has a custom prefix, an
|
|
243
|
+
* unusual entry CSS or sits in a monorepo, expect false positives.
|
|
244
|
+
*/
|
|
245
|
+
declare const tailwindPluginRecommended: StylelintRules;
|
|
246
|
+
/**
|
|
247
|
+
* Plugin's strict preset — adds architecture-level checks on top of
|
|
248
|
+
* recommended (no `theme()`, no `@screen`, no `@tailwind`, no `@import`,
|
|
249
|
+
* no `@layer`). Suited to projects that strictly separate utility tokens
|
|
250
|
+
* from authored CSS.
|
|
251
|
+
*/
|
|
252
|
+
declare const tailwindPluginStrict: StylelintRules;
|
|
170
253
|
|
|
171
254
|
/**
|
|
172
255
|
* Build a Stylelint config tailored for Vue/Nuxt/JS/TS/Tailwind projects.
|
|
@@ -192,5 +275,5 @@ declare const tailwindAtRuleNoUnknown: StylelintRules;
|
|
|
192
275
|
*/
|
|
193
276
|
declare function defineConfig(options?: MazStylelintOptions): StylelintConfig;
|
|
194
277
|
|
|
195
|
-
export { GLOBAL_IGNORES, TAILWIND_AT_RULES, baseRules, defineConfig, logicalRules, scssRules, tailwindAtRuleNoUnknown, tailwindRules };
|
|
278
|
+
export { GLOBAL_IGNORES, TAILWIND_AT_RULES, baseRules, defineConfig, logicalRules, scssRules, tailwindAtRuleNoUnknown, tailwindPluginMinimal, tailwindPluginRecommended, tailwindPluginStrict, tailwindRules };
|
|
196
279
|
export type { MazStylelintOptions, StylelintConfig, StylelintOrderStrategy, StylelintOverride, StylelintRules };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
2
3
|
import { join } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { createConsola } from 'consola';
|
|
6
|
+
import { noInvalidApplyPlugin, noInvalidThemeFunctionPlugin, noAtomicClassPlugin, noApplyPlugin, noArbitraryValuePlugin, noThemeFunctionPlugin, noScreenDirectivePlugin, noTailwindDirectivePlugin, noImportDirectivePlugin, noCssLayerPlugin } from 'stylelint-plugin-tailwindcss';
|
|
3
7
|
|
|
4
8
|
const baseRules = {
|
|
5
9
|
/**
|
|
@@ -76,6 +80,29 @@ const GLOBAL_IGNORES = [
|
|
|
76
80
|
"**/*.min.scss"
|
|
77
81
|
];
|
|
78
82
|
|
|
83
|
+
const LEVELS = {
|
|
84
|
+
silent: Number.NEGATIVE_INFINITY,
|
|
85
|
+
error: 0,
|
|
86
|
+
warning: 1,
|
|
87
|
+
normal: 2,
|
|
88
|
+
default: 3,
|
|
89
|
+
debug: 4,
|
|
90
|
+
trace: 5,
|
|
91
|
+
verbose: Number.POSITIVE_INFINITY
|
|
92
|
+
};
|
|
93
|
+
function createLogger() {
|
|
94
|
+
const consola = createConsola();
|
|
95
|
+
return {
|
|
96
|
+
setLevel: (level) => {
|
|
97
|
+
consola.level = LEVELS[level];
|
|
98
|
+
},
|
|
99
|
+
info: (msg) => consola.info(msg),
|
|
100
|
+
debug: (msg) => consola.debug(msg),
|
|
101
|
+
verbose: (msg) => consola.verbose(msg),
|
|
102
|
+
box: (opts) => consola.box(opts)
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
79
106
|
const LOGICAL_PLUGIN = ["stylelint-use-logical-spec"];
|
|
80
107
|
const logicalRules = {
|
|
81
108
|
"liberty/use-logical-spec": ["always"]
|
|
@@ -101,6 +128,14 @@ const TAILWIND_AT_RULES = [
|
|
|
101
128
|
];
|
|
102
129
|
const tailwindRules = {
|
|
103
130
|
"at-rule-no-deprecated": [true, { ignoreAtRules: ["apply"] }],
|
|
131
|
+
/**
|
|
132
|
+
* `stylelint-config-recommended@18` enables the core rule
|
|
133
|
+
* `at-rule-prelude-no-invalid`, which validates the prelude of `@apply`
|
|
134
|
+
* against css-tree. A list of Tailwind utilities (`@apply maz:flex …`) is
|
|
135
|
+
* not a valid prelude grammar, so every `@apply` triggers a false positive.
|
|
136
|
+
* Whitelist Tailwind's at-rules (keeping `media`, ignored by recommended).
|
|
137
|
+
*/
|
|
138
|
+
"at-rule-prelude-no-invalid": [true, { ignoreAtRules: [...TAILWIND_AT_RULES, "media"] }],
|
|
104
139
|
/**
|
|
105
140
|
* Tailwind v4 only parses the `prefix(...)` modifier on the bare-string
|
|
106
141
|
* `@import "..."` form; wrapping the URL in `url(...)` swallows the modifier
|
|
@@ -111,6 +146,43 @@ const tailwindRules = {
|
|
|
111
146
|
const tailwindAtRuleNoUnknown = {
|
|
112
147
|
"at-rule-no-unknown": [true, { ignoreAtRules: TAILWIND_AT_RULES }]
|
|
113
148
|
};
|
|
149
|
+
const tailwindPluginMinimal = {};
|
|
150
|
+
const tailwindPluginMinimalInstances = [];
|
|
151
|
+
const tailwindPluginRecommended = {
|
|
152
|
+
"tailwindcss/no-invalid-apply": true,
|
|
153
|
+
"tailwindcss/no-invalid-theme-function": true,
|
|
154
|
+
"tailwindcss/no-atomic-class": true,
|
|
155
|
+
"tailwindcss/no-apply": true,
|
|
156
|
+
"tailwindcss/no-arbitrary-value": true
|
|
157
|
+
};
|
|
158
|
+
const tailwindPluginRecommendedInstances = [
|
|
159
|
+
noInvalidApplyPlugin,
|
|
160
|
+
noInvalidThemeFunctionPlugin,
|
|
161
|
+
noAtomicClassPlugin,
|
|
162
|
+
noApplyPlugin,
|
|
163
|
+
noArbitraryValuePlugin
|
|
164
|
+
];
|
|
165
|
+
const tailwindPluginStrict = {
|
|
166
|
+
...tailwindPluginRecommended,
|
|
167
|
+
"tailwindcss/no-theme-function": true,
|
|
168
|
+
"tailwindcss/no-screen-directive": true,
|
|
169
|
+
"tailwindcss/no-tailwind-directive": true,
|
|
170
|
+
"tailwindcss/no-import-directive": true,
|
|
171
|
+
"tailwindcss/no-css-layer": true
|
|
172
|
+
};
|
|
173
|
+
const tailwindPluginStrictInstances = [
|
|
174
|
+
...tailwindPluginRecommendedInstances,
|
|
175
|
+
noThemeFunctionPlugin,
|
|
176
|
+
noScreenDirectivePlugin,
|
|
177
|
+
noTailwindDirectivePlugin,
|
|
178
|
+
noImportDirectivePlugin,
|
|
179
|
+
noCssLayerPlugin
|
|
180
|
+
];
|
|
181
|
+
const TAILWIND_POLICY_PLUGINS = {
|
|
182
|
+
minimal: tailwindPluginMinimalInstances,
|
|
183
|
+
recommended: tailwindPluginRecommendedInstances,
|
|
184
|
+
strict: tailwindPluginStrictInstances
|
|
185
|
+
};
|
|
114
186
|
|
|
115
187
|
const SCSS_AT_RULES = [
|
|
116
188
|
"use",
|
|
@@ -148,6 +220,20 @@ function scssRules(includeTailwind) {
|
|
|
148
220
|
};
|
|
149
221
|
}
|
|
150
222
|
|
|
223
|
+
const TAG = "[@maz-ui/stylelint-config]";
|
|
224
|
+
const internalRequire = createRequire(import.meta.url);
|
|
225
|
+
function resolveInternal(name) {
|
|
226
|
+
try {
|
|
227
|
+
const resolved = import.meta.resolve(name);
|
|
228
|
+
return resolved.startsWith("file:") ? fileURLToPath(resolved) : resolved;
|
|
229
|
+
} catch {
|
|
230
|
+
try {
|
|
231
|
+
return internalRequire.resolve(name);
|
|
232
|
+
} catch {
|
|
233
|
+
return name;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
151
237
|
function readConsumerPackageJson() {
|
|
152
238
|
try {
|
|
153
239
|
return JSON.parse(readFileSync(join(process.cwd(), "package.json"), "utf-8"));
|
|
@@ -161,13 +247,57 @@ function hasDependency(pkg, ...names) {
|
|
|
161
247
|
const buckets = [pkg.dependencies, pkg.devDependencies, pkg.peerDependencies];
|
|
162
248
|
return names.some((name) => buckets.some((bucket) => bucket && name in bucket));
|
|
163
249
|
}
|
|
250
|
+
function resolveTailwind(option, pkg) {
|
|
251
|
+
if (option === false)
|
|
252
|
+
return { value: false, source: "explicit" };
|
|
253
|
+
if (option === true)
|
|
254
|
+
return { value: "minimal", source: "explicit" };
|
|
255
|
+
if (typeof option === "string")
|
|
256
|
+
return { value: option, source: "explicit" };
|
|
257
|
+
const detected = hasDependency(pkg, "tailwindcss", "@tailwindcss/vite");
|
|
258
|
+
return { value: detected ? "minimal" : false, source: "auto-detected" };
|
|
259
|
+
}
|
|
260
|
+
function resolveBoolean(explicit, detected) {
|
|
261
|
+
if (explicit !== void 0)
|
|
262
|
+
return { value: explicit, source: "explicit" };
|
|
263
|
+
return { value: detected, source: "auto-detected" };
|
|
264
|
+
}
|
|
265
|
+
function formatSourceTag(source) {
|
|
266
|
+
if (source === "auto-detected")
|
|
267
|
+
return " (auto-detected)";
|
|
268
|
+
if (source === "default")
|
|
269
|
+
return " (default)";
|
|
270
|
+
return "";
|
|
271
|
+
}
|
|
272
|
+
function formatResolutionBox(resolved) {
|
|
273
|
+
const tailwindLabel = resolved.tailwind === false ? "off" : resolved.tailwind;
|
|
274
|
+
const orderLabel = resolved.order === false ? "off" : resolved.order ?? "recess";
|
|
275
|
+
const rows = [
|
|
276
|
+
["vue", `${resolved.vue}${formatSourceTag(resolved.vueSource)}`],
|
|
277
|
+
["html", `${resolved.html}${formatSourceTag(resolved.htmlSource)}`],
|
|
278
|
+
["tailwind", `${tailwindLabel}${formatSourceTag(resolved.tailwindSource)}`],
|
|
279
|
+
["scss", `${resolved.scss}${formatSourceTag(resolved.scssSource)}`],
|
|
280
|
+
["logical", String(resolved.logical)],
|
|
281
|
+
["order", String(orderLabel)]
|
|
282
|
+
];
|
|
283
|
+
const labelWidth = Math.max(...rows.map(([k]) => k.length));
|
|
284
|
+
return rows.map(([k, v]) => `${k.padEnd(labelWidth)} ${v}`).join("\n");
|
|
285
|
+
}
|
|
164
286
|
function resolveOptions(options) {
|
|
165
287
|
const pkg = readConsumerPackageJson();
|
|
288
|
+
const vue = resolveBoolean(options.vue, hasDependency(pkg, "vue", "nuxt"));
|
|
289
|
+
const html = options.html === void 0 ? { value: false, source: "default" } : { value: options.html, source: "explicit" };
|
|
290
|
+
const tailwind = resolveTailwind(options.tailwind, pkg);
|
|
291
|
+
const scss = resolveBoolean(options.scss, hasDependency(pkg, "sass", "sass-embedded", "node-sass"));
|
|
166
292
|
return {
|
|
167
|
-
vue:
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
293
|
+
vue: vue.value,
|
|
294
|
+
vueSource: vue.source,
|
|
295
|
+
html: html.value,
|
|
296
|
+
htmlSource: html.source,
|
|
297
|
+
tailwind: tailwind.value,
|
|
298
|
+
tailwindSource: tailwind.source,
|
|
299
|
+
scss: scss.value,
|
|
300
|
+
scssSource: scss.source,
|
|
171
301
|
logical: options.logical ?? true,
|
|
172
302
|
order: options.order ?? "recess"
|
|
173
303
|
};
|
|
@@ -175,62 +305,110 @@ function resolveOptions(options) {
|
|
|
175
305
|
function applyScss(resolved, ctx) {
|
|
176
306
|
if (!resolved.scss)
|
|
177
307
|
return;
|
|
178
|
-
ctx.extends.push("stylelint-config-
|
|
308
|
+
ctx.extends.push(resolveInternal("stylelint-config-standard-scss"));
|
|
179
309
|
Object.assign(ctx.rules, scssRules(resolved.tailwind));
|
|
180
310
|
ctx.rules["at-rule-no-unknown"] = null;
|
|
181
311
|
ctx.overrides.push({
|
|
182
312
|
files: ["**/*.scss"],
|
|
183
|
-
customSyntax: "postcss-scss"
|
|
313
|
+
customSyntax: resolveInternal("postcss-scss")
|
|
184
314
|
});
|
|
315
|
+
ctx.log.debug(`${TAG} SCSS: extended stylelint-config-standard-scss + postcss-scss override`);
|
|
185
316
|
}
|
|
186
317
|
function applyVueAndHtml(resolved, ctx) {
|
|
187
|
-
if (resolved.vue)
|
|
188
|
-
ctx.extends.push("stylelint-config-recommended-vue");
|
|
189
|
-
|
|
190
|
-
|
|
318
|
+
if (resolved.vue) {
|
|
319
|
+
ctx.extends.push(resolveInternal("stylelint-config-recommended-vue"));
|
|
320
|
+
ctx.log.debug(`${TAG} Vue: extended stylelint-config-recommended-vue`);
|
|
321
|
+
}
|
|
322
|
+
if (resolved.html) {
|
|
323
|
+
ctx.extends.push(resolveInternal("stylelint-config-html"));
|
|
324
|
+
ctx.log.debug(`${TAG} HTML: extended stylelint-config-html`);
|
|
325
|
+
}
|
|
191
326
|
if (!resolved.vue && !resolved.html)
|
|
192
327
|
return;
|
|
193
328
|
const vueGlobs = resolved.vue ? ["**/*.vue"] : [];
|
|
194
329
|
const htmlGlobs = resolved.html ? ["**/*.html"] : [];
|
|
195
330
|
ctx.overrides.push({
|
|
196
331
|
files: [...vueGlobs, ...htmlGlobs],
|
|
197
|
-
customSyntax: "postcss-html"
|
|
332
|
+
customSyntax: resolveInternal("postcss-html")
|
|
198
333
|
});
|
|
199
334
|
}
|
|
335
|
+
const TAILWIND_POLICY_RULES = {
|
|
336
|
+
minimal: tailwindPluginMinimal,
|
|
337
|
+
recommended: tailwindPluginRecommended,
|
|
338
|
+
strict: tailwindPluginStrict
|
|
339
|
+
};
|
|
340
|
+
function applyTailwind(resolved, ctx) {
|
|
341
|
+
if (!resolved.tailwind)
|
|
342
|
+
return;
|
|
343
|
+
Object.assign(ctx.rules, tailwindRules);
|
|
344
|
+
if (!resolved.scss)
|
|
345
|
+
Object.assign(ctx.rules, tailwindAtRuleNoUnknown);
|
|
346
|
+
const plugins = TAILWIND_POLICY_PLUGINS[resolved.tailwind];
|
|
347
|
+
if (plugins.length === 0) {
|
|
348
|
+
ctx.log.debug(`${TAG} Tailwind: at-rule whitelist only ("${resolved.tailwind}" policy \u2014 no plugin loaded)`);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
ctx.plugins.push(...plugins);
|
|
352
|
+
Object.assign(ctx.rules, TAILWIND_POLICY_RULES[resolved.tailwind]);
|
|
353
|
+
ctx.log.debug(`${TAG} Tailwind: loaded ${plugins.length} plugin(s) for "${resolved.tailwind}" policy`);
|
|
354
|
+
}
|
|
200
355
|
function applyLogical(resolved, ctx) {
|
|
201
356
|
if (!resolved.logical)
|
|
202
357
|
return;
|
|
203
|
-
ctx.plugins.push(...LOGICAL_PLUGIN);
|
|
358
|
+
ctx.plugins.push(...LOGICAL_PLUGIN.map((name) => resolveInternal(name)));
|
|
204
359
|
Object.assign(ctx.rules, logicalRules);
|
|
360
|
+
ctx.log.debug(`${TAG} Logical: loaded stylelint-use-logical-spec`);
|
|
205
361
|
}
|
|
206
362
|
function applyUserOverrides(options, ctx) {
|
|
207
|
-
if (Array.isArray(options.plugins) && options.plugins.length > 0)
|
|
363
|
+
if (Array.isArray(options.plugins) && options.plugins.length > 0) {
|
|
208
364
|
ctx.plugins.push(...options.plugins);
|
|
209
|
-
|
|
365
|
+
ctx.log.debug(`${TAG} User: appended ${options.plugins.length} plugin(s)`);
|
|
366
|
+
}
|
|
367
|
+
if (options.rules) {
|
|
210
368
|
Object.assign(ctx.rules, options.rules);
|
|
211
|
-
|
|
369
|
+
ctx.log.debug(`${TAG} User: merged ${Object.keys(options.rules).length} rule override(s)`);
|
|
370
|
+
}
|
|
371
|
+
if (options.overrides?.length) {
|
|
212
372
|
ctx.overrides.push(...options.overrides);
|
|
373
|
+
ctx.log.debug(`${TAG} User: appended ${options.overrides.length} per-file override(s)`);
|
|
374
|
+
}
|
|
375
|
+
if (options.extends?.length) {
|
|
376
|
+
ctx.extends.push(...options.extends);
|
|
377
|
+
ctx.log.debug(`${TAG} User: extended ${options.extends.join(", ")}`);
|
|
378
|
+
}
|
|
213
379
|
}
|
|
214
380
|
function defineConfig(options = {}) {
|
|
381
|
+
const log = createLogger();
|
|
382
|
+
log.setLevel(options.logLevel ?? "default");
|
|
215
383
|
const resolved = resolveOptions(options);
|
|
384
|
+
log.box({
|
|
385
|
+
title: "@maz-ui/stylelint-config",
|
|
386
|
+
message: formatResolutionBox(resolved),
|
|
387
|
+
style: { borderColor: "cyan", padding: 1 }
|
|
388
|
+
});
|
|
216
389
|
const ctx = {
|
|
217
|
-
extends: ["stylelint-config-standard"],
|
|
390
|
+
extends: [resolveInternal("stylelint-config-standard")],
|
|
218
391
|
plugins: [],
|
|
219
392
|
rules: { ...baseRules },
|
|
220
|
-
overrides: []
|
|
393
|
+
overrides: [],
|
|
394
|
+
log
|
|
221
395
|
};
|
|
222
|
-
if (resolved.order === "recess")
|
|
223
|
-
ctx.extends.push("stylelint-config-recess-order");
|
|
396
|
+
if (resolved.order === "recess") {
|
|
397
|
+
ctx.extends.push(resolveInternal("stylelint-config-recess-order"));
|
|
398
|
+
log.debug(`${TAG} Order: extended stylelint-config-recess-order`);
|
|
399
|
+
} else if (resolved.order === "alphabetical") {
|
|
400
|
+
ctx.plugins.push(resolveInternal("stylelint-order"));
|
|
401
|
+
ctx.rules["order/properties-alphabetical-order"] = true;
|
|
402
|
+
log.debug(`${TAG} Order: loaded stylelint-order with properties-alphabetical-order`);
|
|
403
|
+
}
|
|
224
404
|
applyScss(resolved, ctx);
|
|
225
405
|
applyVueAndHtml(resolved, ctx);
|
|
226
|
-
|
|
227
|
-
Object.assign(ctx.rules, tailwindRules);
|
|
228
|
-
if (!resolved.scss)
|
|
229
|
-
Object.assign(ctx.rules, tailwindAtRuleNoUnknown);
|
|
230
|
-
}
|
|
406
|
+
applyTailwind(resolved, ctx);
|
|
231
407
|
applyLogical(resolved, ctx);
|
|
232
408
|
applyUserOverrides(options, ctx);
|
|
233
409
|
const ignoreFiles = options.ignoresOverride ?? [...GLOBAL_IGNORES, ...options.ignores ?? []];
|
|
410
|
+
log.verbose(`${TAG} Final extends (${ctx.extends.length}): ${ctx.extends.join(", ")}`);
|
|
411
|
+
log.verbose(`${TAG} Final plugin count: ${ctx.plugins.length}, rule count: ${Object.keys(ctx.rules).length}, override count: ${ctx.overrides.length}, ignore globs: ${ignoreFiles.length}`);
|
|
234
412
|
return {
|
|
235
413
|
extends: ctx.extends,
|
|
236
414
|
plugins: ctx.plugins.length > 0 ? ctx.plugins : void 0,
|
|
@@ -240,4 +418,4 @@ function defineConfig(options = {}) {
|
|
|
240
418
|
};
|
|
241
419
|
}
|
|
242
420
|
|
|
243
|
-
export { GLOBAL_IGNORES, TAILWIND_AT_RULES, baseRules, defineConfig, logicalRules, scssRules, tailwindAtRuleNoUnknown, tailwindRules };
|
|
421
|
+
export { GLOBAL_IGNORES, TAILWIND_AT_RULES, baseRules, defineConfig, logicalRules, scssRules, tailwindAtRuleNoUnknown, tailwindPluginMinimal, tailwindPluginRecommended, tailwindPluginStrict, tailwindRules };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maz-ui/stylelint-config",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.0.0
|
|
4
|
+
"version": "5.0.0",
|
|
5
5
|
"description": "Stylelint configuration for CSS, SCSS, Vue and Tailwind CSS projects",
|
|
6
6
|
"author": "Louis Mazel <me@loicmazuel.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"exports": {
|
|
28
28
|
".": {
|
|
29
29
|
"types": "./dist/index.d.ts",
|
|
30
|
-
"import": "./dist/index.mjs"
|
|
30
|
+
"import": "./dist/index.mjs",
|
|
31
|
+
"default": "./dist/index.mjs"
|
|
31
32
|
}
|
|
32
33
|
},
|
|
33
34
|
"main": "./dist/index.mjs",
|
|
@@ -38,28 +39,29 @@
|
|
|
38
39
|
"dist"
|
|
39
40
|
],
|
|
40
41
|
"engines": {
|
|
41
|
-
"node": ">=
|
|
42
|
+
"node": ">=22.12.0"
|
|
42
43
|
},
|
|
43
44
|
"peerDependencies": {
|
|
44
45
|
"stylelint": ">=16.0.0 <18.0.0"
|
|
45
46
|
},
|
|
46
47
|
"dependencies": {
|
|
47
|
-
"
|
|
48
|
+
"consola": "^3.4.2",
|
|
49
|
+
"postcss-html": "^2.0.0",
|
|
48
50
|
"postcss-scss": "^4.0.9",
|
|
49
|
-
"stylelint-config-html": "^
|
|
50
|
-
"stylelint-config-recess-order": "^7.
|
|
51
|
-
"stylelint-config-recommended-
|
|
52
|
-
"stylelint-config-recommended-vue": "^1.6.1",
|
|
51
|
+
"stylelint-config-html": "^2.0.0",
|
|
52
|
+
"stylelint-config-recess-order": "^7.8.2",
|
|
53
|
+
"stylelint-config-recommended-vue": "^2.0.0",
|
|
53
54
|
"stylelint-config-standard": "^40.0.0",
|
|
54
|
-
"stylelint-scss": "^
|
|
55
|
+
"stylelint-config-standard-scss": "^17.0.0",
|
|
56
|
+
"stylelint-order": "^8.1.2",
|
|
57
|
+
"stylelint-plugin-tailwindcss": "^3.1.3",
|
|
55
58
|
"stylelint-use-logical-spec": "^5.0.1"
|
|
56
59
|
},
|
|
57
60
|
"devDependencies": {
|
|
58
|
-
"@
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"@maz-ui/eslint-config": "5.0.0-canary.ef64a02.0"
|
|
61
|
+
"@maz-ui/eslint-config": "5.0.0",
|
|
62
|
+
"@vitest/coverage-v8": "^5.0.5",
|
|
63
|
+
"stylelint": "^17.16.0",
|
|
64
|
+
"unbuild": "^3.6.1"
|
|
63
65
|
},
|
|
64
66
|
"lint-staged": {
|
|
65
67
|
"*.{js,jsx,ts,tsx,mjs,mts,cjs,md,yml,json}": [
|
|
@@ -67,10 +69,9 @@
|
|
|
67
69
|
]
|
|
68
70
|
},
|
|
69
71
|
"scripts": {
|
|
70
|
-
"codegen": "nx build",
|
|
71
72
|
"build": "unbuild",
|
|
72
73
|
"dev": "unbuild --stub",
|
|
73
|
-
"typecheck": "tsc --
|
|
74
|
+
"typecheck": "tsc --build",
|
|
74
75
|
"lint": "cross-env NODE_ENV=production eslint .",
|
|
75
76
|
"lint:fix": "pnpm lint --fix",
|
|
76
77
|
"test:unit": "vitest run",
|