stylelint-plugin-rhythmguard 1.7.0 → 1.9.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/CHANGELOG.md CHANGED
@@ -6,6 +6,24 @@ The format follows Keep a Changelog principles and semantic versioning.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.9.0] - 2026-05-23
10
+
11
+ ### Added
12
+
13
+ - Added opt-in `rhythmguard/use-motion-scale` for duration/delay scale enforcement and raw easing reporting.
14
+ - Added `stylelint-plugin-rhythmguard/configs/motion`.
15
+ - Added ESLint companion rule `rhythmguard-tailwind/tailwind-class-use-motion-scale` for Tailwind `duration-[...]`, `delay-[...]`, and `ease-[...]` arbitrary values.
16
+ - Added `rhythmguard audit --include-motion` and `.rhythmguardrc.json` `includeMotion` support.
17
+
18
+ ## [1.8.0] - 2026-05-23
19
+
20
+ ### Added
21
+
22
+ - Added `.rhythmguardrc.json` audit config loading with `--config` and `--no-config`.
23
+ - Added external audit token sources with `--token-source`, `--token-source-format`, and `--token-kind`.
24
+ - Added token source parsing for CSS custom properties, Tailwind v4 `@theme`, flat JSON, Style Dictionary JSON, and DTCG JSON.
25
+ - Expanded audit token-contract reporting with loaded source metadata, raw values that match known tokens, and conflicting token values.
26
+
9
27
  ## [1.7.0] - 2026-05-23
10
28
 
11
29
  ### Added
package/README.md CHANGED
@@ -66,6 +66,7 @@ This gives you spacing governance in both CSS files and JSX/TSX templates.
66
66
  | `rhythmguard/use-scale` | Enforces spacing values must be on your configured scale | Yes, nearest safe value |
67
67
  | `rhythmguard/prefer-token` | Enforces token usage over raw spacing literals | Yes, with `tokenMap` |
68
68
  | `rhythmguard/no-offscale-transform` | Enforces scale-aligned `translate*` motion offsets | Yes, nearest safe value |
69
+ | `rhythmguard/use-motion-scale` | Enforces opt-in duration/delay rhythm and flags raw easing curves | Yes, for duration/delay values |
69
70
 
70
71
  ## Demo
71
72
 
@@ -93,9 +94,12 @@ npx rhythmguard audit . --ignore "apps/legacy/**" --ignore "vendor/**"
93
94
  npx rhythmguard audit ./src --write-baseline
94
95
  npx rhythmguard audit ./src --since-baseline --fail-on-new-drift
95
96
  npx rhythmguard audit ./src --staged --max-findings 0
97
+ npx rhythmguard audit ./src --token-source ./tokens.json
98
+ npx rhythmguard audit ./src --token-source ./theme.css --token-source-format css
99
+ npx rhythmguard audit ./src --include-motion
96
100
  ```
97
101
 
98
- The report covers authored CSS declarations, Tailwind arbitrary spacing values in common template/source files, and token-contract drift such as missing spacing tokens, unused spacing tokens, and repeated raw values that deserve token review. Scan paths are scoped to the directory argument. Use `--ignore`, `.rhythmguardignore`, or `--ignore-path` for generated or legacy subtrees, then add baselines and CI thresholds when you are ready to gate new drift. Markdown output is PR-ready for UX developers, UX designers, and design-system owners:
102
+ The report covers authored CSS declarations, Tailwind arbitrary spacing values in common template/source files, and token-contract drift such as missing spacing tokens, unused spacing tokens, repeated raw values that deserve token review, raw values that match known tokens, and conflicting token values. Scan paths are scoped to the directory argument. Use `--ignore`, `.rhythmguardignore`, or `--ignore-path` for generated or legacy subtrees, then add baselines and CI thresholds when you are ready to gate new drift. Markdown output is PR-ready for UX developers, UX designers, and design-system owners:
99
103
 
100
104
  ```md
101
105
  # Rhythmguard Design-System Audit
@@ -110,6 +114,28 @@ The report covers authored CSS declarations, Tailwind arbitrary spacing values i
110
114
  | New findings | 3 |
111
115
  ```
112
116
 
117
+ ### Audit config and external token sources
118
+
119
+ For large codebases, put shared audit settings in `.rhythmguardrc.json`:
120
+
121
+ ```json
122
+ {
123
+ "audit": {
124
+ "ignore": ["legacy/**", "generated/**"],
125
+ "tokenSources": [
126
+ "./tokens.json",
127
+ { "path": "./src/theme.css", "format": "css" }
128
+ ],
129
+ "tokenKind": "spacing",
130
+ "includeMotion": false,
131
+ "tokenCandidateMinCount": 2,
132
+ "minCleanliness": 90
133
+ }
134
+ }
135
+ ```
136
+
137
+ `rhythmguard audit` loads `.rhythmguardrc.json` automatically when present. Use `--config <file>` for another config, `--no-config` to skip config discovery, and `--token-source <file>` for extra canonical token files. Token source paths in config files resolve from the config file directory; CLI token source paths resolve from the current working directory. Supported source formats are CSS custom properties and Tailwind v4 `@theme`, flat JSON maps, Style Dictionary JSON, and DTCG JSON.
138
+
113
139
  ## Installation
114
140
 
115
141
  ```bash
@@ -198,6 +224,16 @@ npm install --save-dev stylelint-plugin-rhythmguard
198
224
 
199
225
  `react-tailwind` extends the tailwind config with CSS Modules overrides (spacing + radius enforcement) and ignores Next.js build directories.
200
226
 
227
+ ### Motion config
228
+
229
+ ```json
230
+ {
231
+ "extends": ["stylelint-plugin-rhythmguard/configs/motion"]
232
+ }
233
+ ```
234
+
235
+ `motion` enables opt-in duration/delay rhythm checks with `rhythmguard/use-motion-scale`.
236
+
201
237
  Stable shared config entry points:
202
238
 
203
239
  - `stylelint-plugin-rhythmguard/configs/recommended`
@@ -207,6 +243,7 @@ Stable shared config entry points:
207
243
  - `stylelint-plugin-rhythmguard/configs/expanded`
208
244
  - `stylelint-plugin-rhythmguard/configs/logical`
209
245
  - `stylelint-plugin-rhythmguard/configs/migration`
246
+ - `stylelint-plugin-rhythmguard/configs/motion`
210
247
 
211
248
  Framework-specific setup for Vue, Lit, Astro, and SvelteKit: [`docs/FRAMEWORKS.md`](https://github.com/PetriLahdelma/stylelint-plugin-rhythmguard/blob/main/docs/FRAMEWORKS.md)
212
249
 
@@ -448,7 +485,7 @@ Options:
448
485
  | `enforceInsideMathFunctions` | `boolean` | `false` | Lints `calc()/clamp()/min()/max()` internals |
449
486
  | `mathFunctionArguments` | `Record<mathFn, number[]>` | `{}` | Restricts linting to specific 1-based argument indexes per math function |
450
487
  | `ignoreMathFunctionArguments` | `Record<mathFn, number[]>` | `{}` | Excludes specific 1-based argument indexes per math function |
451
- | `propertyGroups` | `Array<'spacing' \| 'radius' \| 'typography' \| 'size'>` | `['spacing']` | Selects built-in property groups when `properties` is not provided |
488
+ | `propertyGroups` | `Array<'spacing' \| 'radius' \| 'typography' \| 'size' \| 'motion'>` | `['spacing']` | Selects built-in property groups when `properties` is not provided |
452
489
  | `properties` | `Array<string|RegExp>` | built-in spacing patterns | Override targeted property set; string values may be supported property names or regex-like strings (`/pattern/flags`) |
453
490
  | `propertyScales` | `Record<propertyOrRegex, scaleOrPreset>` | `{}` | Per-property scale overrides (supports exact names or `/regex/flags` keys; stateful `g`/`y` flags are normalized for deterministic matching) |
454
491
 
@@ -520,6 +557,35 @@ Options:
520
557
 
521
558
  `rhythmguard/no-offscale-transform` accepts the same scale options as `rhythmguard/use-scale` (including `unitStrategy`, math argument targeting, and deterministic autofix), but only for transform translation properties. Its secondary options are also validated for unknown keys and invalid value shapes.
522
559
 
560
+ ### `rhythmguard/use-motion-scale`
561
+
562
+ Opt-in guardrail for duration, delay, and easing rhythm.
563
+
564
+ Example:
565
+
566
+ ```css
567
+ /* ❌ Off-scale timing + raw easing */
568
+ .button {
569
+ transition: opacity 175ms cubic-bezier(.2, 0, 0, 1);
570
+ }
571
+
572
+ /* ✅ Timing on motion scale */
573
+ .button {
574
+ transition: opacity 150ms var(--ease-snappy);
575
+ }
576
+ ```
577
+
578
+ Options:
579
+
580
+ | Option | Type | Default | Description |
581
+ | --- | --- | --- | --- |
582
+ | `durationScale` | `number[]` | `[0,75,100,150,200,300,500,700,1000]` | Allowed duration and delay values in milliseconds |
583
+ | `durationUnits` | `Array<'ms' \| 's'>` | `['ms','s']` | Time units considered by the rule |
584
+ | `fixToScale` | `boolean` | `true` | Autofixes simple duration/delay values to the nearest scale value |
585
+ | `easingTokenMap` | `Record<string,string>` | `{}` | Optional exact replacements for raw easing functions |
586
+
587
+ Tailwind class strings can use the ESLint companion rule `rhythmguard-tailwind/tailwind-class-use-motion-scale` for `duration-[...]`, `delay-[...]`, and `ease-[...]` arbitrary values.
588
+
523
589
  ## Tailwind CSS Integration
524
590
 
525
591
  Rhythmguard works well in Tailwind projects, but it enforces what Stylelint can parse: CSS declarations.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stylelint-plugin-rhythmguard",
3
- "version": "1.7.0",
3
+ "version": "1.9.0",
4
4
  "description": "Token governance for CSS and Tailwind — enforce spacing scales, require design tokens, catch arbitrary values",
5
5
  "bin": {
6
6
  "rhythmguard": "src/cli/index.js"
@@ -49,6 +49,10 @@
49
49
  "require": "./src/configs/migration.js",
50
50
  "import": "./src/configs/migration.mjs"
51
51
  },
52
+ "./configs/motion": {
53
+ "require": "./src/configs/motion.js",
54
+ "import": "./src/configs/motion.mjs"
55
+ },
52
56
  "./configs/react-tailwind": {
53
57
  "require": "./src/configs/react-tailwind.js",
54
58
  "import": "./src/configs/react-tailwind.mjs"
@@ -69,6 +73,10 @@
69
73
  "require": "./src/rules/no-offscale-transform/index.js",
70
74
  "import": "./src/rules/no-offscale-transform/index.mjs"
71
75
  },
76
+ "./rules/use-motion-scale": {
77
+ "require": "./src/rules/use-motion-scale/index.js",
78
+ "import": "./src/rules/use-motion-scale/index.mjs"
79
+ },
72
80
  "./eslint": {
73
81
  "require": "./src/eslint/index.js",
74
82
  "import": "./src/eslint/index.mjs"