stylelint-plugin-rhythmguard 1.4.0 → 1.4.1
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 +10 -0
- package/README.md +4 -4
- package/package.json +1 -1
- package/src/rules/prefer-token/index.js +1 -1
- package/src/rules/use-scale/index.js +1 -1
- package/src/utils/options.js +22 -3
- package/src/utils/value-utils.js +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,16 @@ The format follows Keep a Changelog principles and semantic versioning.
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.4.1] - 2026-02-21
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- `properties` now correctly supports regex-like string entries (for example `"/^(margin|padding)$/"`) in rule options.
|
|
14
|
+
- Property matcher behavior is now deterministic for regex matchers with stateful `g`/`y` flags by normalizing stateful behavior during matching.
|
|
15
|
+
- Generic rule messaging for expanded property groups:
|
|
16
|
+
- `rhythmguard/use-scale` now reports off-scale values without spacing-only wording.
|
|
17
|
+
- `rhythmguard/prefer-token` now reports raw scale values without spacing-only wording.
|
|
18
|
+
|
|
9
19
|
## [1.4.0] - 2026-02-21
|
|
10
20
|
|
|
11
21
|
### Added
|
package/README.md
CHANGED
|
@@ -349,8 +349,8 @@ Options:
|
|
|
349
349
|
| `mathFunctionArguments` | `Record<mathFn, number[]>` | `{}` | Restricts linting to specific 1-based argument indexes per math function |
|
|
350
350
|
| `ignoreMathFunctionArguments` | `Record<mathFn, number[]>` | `{}` | Excludes specific 1-based argument indexes per math function |
|
|
351
351
|
| `propertyGroups` | `Array<'spacing' \| 'radius' \| 'typography' \| 'size'>` | `['spacing']` | Selects built-in property groups when `properties` is not provided |
|
|
352
|
-
| `properties` | `Array<string|RegExp>` | built-in spacing patterns | Override targeted property set; string values
|
|
353
|
-
| `propertyScales` | `Record<propertyOrRegex, scaleOrPreset>` | `{}` | Per-property scale overrides (supports exact names or `/regex/flags` keys) |
|
|
352
|
+
| `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`) |
|
|
353
|
+
| `propertyScales` | `Record<propertyOrRegex, scaleOrPreset>` | `{}` | Per-property scale overrides (supports exact names or `/regex/flags` keys; stateful `g`/`y` flags are normalized for deterministic matching) |
|
|
354
354
|
|
|
355
355
|
### `rhythmguard/prefer-token`
|
|
356
356
|
|
|
@@ -395,8 +395,8 @@ Options:
|
|
|
395
395
|
| `tailwindConfigPath` | `string` | `null` | Path to Tailwind config used by `tokenMapFromTailwindSpacing` (`.js`, `.cjs`, `.mjs`) |
|
|
396
396
|
| `ignoreValues` | `string[]` | CSS global keywords + `auto` | Skips keyword literals |
|
|
397
397
|
| `propertyGroups` | `Array<'spacing' \| 'radius' \| 'typography' \| 'size'>` | `['spacing']` | Selects built-in property groups when `properties` is not provided |
|
|
398
|
-
| `properties` | `Array<string|RegExp>` | built-in spacing patterns | Override targeted property set; string values
|
|
399
|
-
| `propertyScales` | `Record<propertyOrRegex, scaleOrPreset>` | `{}` | Per-property scale overrides for numeric migration mode |
|
|
398
|
+
| `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`) |
|
|
399
|
+
| `propertyScales` | `Record<propertyOrRegex, scaleOrPreset>` | `{}` | Per-property scale overrides for numeric migration mode (stateful `g`/`y` flags are normalized for deterministic matching) |
|
|
400
400
|
|
|
401
401
|
### `rhythmguard/no-offscale-transform`
|
|
402
402
|
|
package/package.json
CHANGED
|
@@ -34,7 +34,7 @@ const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
|
34
34
|
invalidPreset: (presetName, presetNames) =>
|
|
35
35
|
`Unknown scale preset "${presetName}". Available presets: ${presetNames.join(', ')}.`,
|
|
36
36
|
rejected: (value) =>
|
|
37
|
-
`Unexpected raw
|
|
37
|
+
`Unexpected raw scale value "${value}". Use design tokens for scale decisions.`,
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
function applyNegativeToken(replacement, parsedLength) {
|
|
@@ -35,7 +35,7 @@ const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
|
35
35
|
invalidPreset: (presetName, presetNames) =>
|
|
36
36
|
`Unknown scale preset "${presetName}". Available presets: ${presetNames.join(', ')}.`,
|
|
37
37
|
rejected: (value, lower, upper) =>
|
|
38
|
-
`Unexpected off-scale
|
|
38
|
+
`Unexpected off-scale value "${value}". Use scale values (nearest: ${lower} or ${upper}).`,
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
function getFixedNodeValue(parsedLength, nearestPx, options) {
|
package/src/utils/options.js
CHANGED
|
@@ -102,6 +102,19 @@ function parseRegexLikeString(value) {
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
function toStableRegex(regex) {
|
|
106
|
+
if (!(regex instanceof RegExp)) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!regex.global && !regex.sticky) {
|
|
111
|
+
return regex;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const stableFlags = regex.flags.replace(/[gy]/g, '');
|
|
115
|
+
return new RegExp(regex.source, stableFlags);
|
|
116
|
+
}
|
|
117
|
+
|
|
105
118
|
function isPropertyPatternEntry(value) {
|
|
106
119
|
if (value instanceof RegExp) {
|
|
107
120
|
return true;
|
|
@@ -300,7 +313,9 @@ function normalizePropertyGroups(rawGroups) {
|
|
|
300
313
|
|
|
301
314
|
function resolvePropertyPatterns(options) {
|
|
302
315
|
if (Array.isArray(options.properties)) {
|
|
303
|
-
return options.properties
|
|
316
|
+
return options.properties
|
|
317
|
+
.map((entry) => compilePropertyMatcher(entry))
|
|
318
|
+
.filter((entry) => entry !== null);
|
|
304
319
|
}
|
|
305
320
|
|
|
306
321
|
const groups = normalizePropertyGroups(options.propertyGroups);
|
|
@@ -315,7 +330,7 @@ function resolvePropertyPatterns(options) {
|
|
|
315
330
|
|
|
316
331
|
function compilePropertyMatcher(entry) {
|
|
317
332
|
if (entry instanceof RegExp) {
|
|
318
|
-
return entry;
|
|
333
|
+
return toStableRegex(entry);
|
|
319
334
|
}
|
|
320
335
|
|
|
321
336
|
if (!isNonEmptyString(entry)) {
|
|
@@ -325,7 +340,7 @@ function compilePropertyMatcher(entry) {
|
|
|
325
340
|
const trimmed = entry.trim();
|
|
326
341
|
const parsedRegex = parseRegexLikeString(trimmed);
|
|
327
342
|
if (parsedRegex) {
|
|
328
|
-
return parsedRegex;
|
|
343
|
+
return toStableRegex(parsedRegex);
|
|
329
344
|
}
|
|
330
345
|
|
|
331
346
|
return trimmed.toLowerCase();
|
|
@@ -655,6 +670,10 @@ function resolvePropertyScale(prop, options) {
|
|
|
655
670
|
|
|
656
671
|
for (const override of options.propertyScaleOverrides) {
|
|
657
672
|
if (override.matcher instanceof RegExp) {
|
|
673
|
+
if (override.matcher.global || override.matcher.sticky) {
|
|
674
|
+
override.matcher.lastIndex = 0;
|
|
675
|
+
}
|
|
676
|
+
|
|
658
677
|
if (override.matcher.test(prop)) {
|
|
659
678
|
return override.scale;
|
|
660
679
|
}
|
package/src/utils/value-utils.js
CHANGED
|
@@ -11,6 +11,10 @@ function propertyMatches(prop, patterns) {
|
|
|
11
11
|
const normalized = prop.toLowerCase();
|
|
12
12
|
return patterns.some((pattern) => {
|
|
13
13
|
if (pattern instanceof RegExp) {
|
|
14
|
+
if (pattern.global || pattern.sticky) {
|
|
15
|
+
pattern.lastIndex = 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
return pattern.test(normalized);
|
|
15
19
|
}
|
|
16
20
|
|