eslint-plugin-code-style 1.9.5 → 1.9.6
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 +16 -0
- package/index.js +51 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [1.9.6] - 2026-02-03
|
|
11
|
+
|
|
12
|
+
### Enhanced
|
|
13
|
+
|
|
14
|
+
- **`no-hardcoded-strings`** - Skip Tailwind CSS class strings:
|
|
15
|
+
- Multi-class strings like `"px-5 py-3 w-full bg-white"` are now ignored
|
|
16
|
+
- Individual classes: `w-5`, `p-4`, `pr-12`, `text-2xl`, `gap-4`, etc.
|
|
17
|
+
- State modifiers: `hover:bg-primary`, `focus:ring-2`, `disabled:opacity-50`
|
|
18
|
+
- Responsive prefixes: `sm:flex`, `md:hidden`, `lg:grid`
|
|
19
|
+
- Opacity values: `bg-white/50`, `text-black/80`, `placeholder-error/50`
|
|
20
|
+
- Arbitrary values: `w-[100px]`, `bg-[#ff0000]`
|
|
21
|
+
- Negative values: `-translate-y-1/2`, `-rotate-45`
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
10
25
|
## [1.9.5] - 2026-02-03
|
|
11
26
|
|
|
12
27
|
### Fixed
|
|
@@ -1310,6 +1325,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
1310
1325
|
|
|
1311
1326
|
---
|
|
1312
1327
|
|
|
1328
|
+
[1.9.6]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.9.5...v1.9.6
|
|
1313
1329
|
[1.9.5]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.9.4...v1.9.5
|
|
1314
1330
|
[1.9.4]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.9.3...v1.9.4
|
|
1315
1331
|
[1.9.3]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.9.2...v1.9.3
|
package/index.js
CHANGED
|
@@ -14070,6 +14070,22 @@ const noHardcodedStrings = {
|
|
|
14070
14070
|
/^[a-z][a-zA-Z0-9_]*=/,
|
|
14071
14071
|
// CSS property-like (kebab-case): must have hyphen (e.g., font-size, background-color)
|
|
14072
14072
|
/^[a-z]+-[a-z]+(-[a-z]+)*$/,
|
|
14073
|
+
// Tailwind CSS utility classes
|
|
14074
|
+
// With numbers: w-5, p-4, pr-12, mt-1, text-2xl, gap-4, h-5, rounded-lg, etc.
|
|
14075
|
+
/^-?[a-z]+-\d+(\.\d+)?(\/\d+)?$/,
|
|
14076
|
+
/^-?[a-z]+-[a-z]+-\d+(\.\d+)?(\/\d+)?$/,
|
|
14077
|
+
// With modifiers: hover:bg-primary, focus:ring-2, sm:flex, disabled:opacity-50, etc.
|
|
14078
|
+
/^[a-z]+:[a-z][-a-z0-9/]*$/,
|
|
14079
|
+
// With opacity: bg-white/50, text-black/80, placeholder-error/50, etc.
|
|
14080
|
+
/^[a-z]+-[a-z]+(-[a-z]+)*\/\d+$/,
|
|
14081
|
+
// Arbitrary values: w-[100px], bg-[#ff0000], translate-x-[50%], etc.
|
|
14082
|
+
/^-?[a-z]+(-[a-z]+)*-\[.+\]$/,
|
|
14083
|
+
// Negative transforms: -translate-y-1/2, -rotate-45, -skew-x-12, etc.
|
|
14084
|
+
/^-[a-z]+-[a-z]+-\d+\/\d+$/,
|
|
14085
|
+
// Common Tailwind patterns with full/auto/screen/none/inherit etc.
|
|
14086
|
+
/^[a-z]+-(full|auto|screen|none|inherit|initial|px|fit|min|max)$/,
|
|
14087
|
+
// Responsive/state prefixes with values: sm:w-full, md:flex, lg:hidden, etc.
|
|
14088
|
+
/^(sm|md|lg|xl|2xl|hover|focus|active|disabled|first|last|odd|even|group-hover|dark|motion-safe|motion-reduce):[a-z][-a-z0-9/[\]]*$/,
|
|
14073
14089
|
// Numbers with separators
|
|
14074
14090
|
/^[\d,._]+$/,
|
|
14075
14091
|
// Semantic version
|
|
@@ -14090,6 +14106,38 @@ const noHardcodedStrings = {
|
|
|
14090
14106
|
|
|
14091
14107
|
const allIgnorePatterns = [...technicalPatterns, ...extraIgnorePatterns];
|
|
14092
14108
|
|
|
14109
|
+
// Tailwind/CSS class pattern - matches individual class names
|
|
14110
|
+
const tailwindClassPattern = /^-?[a-z]+(-[a-z0-9]+)*(\/\d+)?$|^-?[a-z]+(-[a-z0-9]+)*-\[.+\]$|^[a-z]+:[a-z][-a-z0-9/[\]]*$/;
|
|
14111
|
+
|
|
14112
|
+
// Check if a string contains only CSS/Tailwind class names
|
|
14113
|
+
const isTailwindClassStringHandler = (str) => {
|
|
14114
|
+
// Split by whitespace and filter empty strings
|
|
14115
|
+
const tokens = str.trim().split(/\s+/).filter(Boolean);
|
|
14116
|
+
|
|
14117
|
+
// Must have at least one token
|
|
14118
|
+
if (tokens.length === 0) return false;
|
|
14119
|
+
|
|
14120
|
+
// Check if all tokens look like CSS classes
|
|
14121
|
+
return tokens.every((token) => {
|
|
14122
|
+
// Skip template literal expressions placeholders if any
|
|
14123
|
+
if (token.includes("${")) return true;
|
|
14124
|
+
|
|
14125
|
+
// Common Tailwind patterns
|
|
14126
|
+
return (
|
|
14127
|
+
// Basic kebab-case with numbers: w-5, p-4, pr-12, text-2xl, gap-4
|
|
14128
|
+
/^-?[a-z]+(-[a-z0-9]+)*$/.test(token)
|
|
14129
|
+
// With fractions: w-1/2, -translate-y-1/2
|
|
14130
|
+
|| /^-?[a-z]+(-[a-z0-9]+)*\/\d+$/.test(token)
|
|
14131
|
+
// With modifiers: hover:bg-primary, focus:ring-2, sm:flex
|
|
14132
|
+
|| /^[a-z0-9]+:[a-z][-a-z0-9/[\]]*$/.test(token)
|
|
14133
|
+
// Arbitrary values: w-[100px], bg-[#ff0000]
|
|
14134
|
+
|| /^-?[a-z]+(-[a-z]+)*-?\[.+\]$/.test(token)
|
|
14135
|
+
// Single word utilities: flex, hidden, block
|
|
14136
|
+
|| /^[a-z]+$/.test(token)
|
|
14137
|
+
);
|
|
14138
|
+
});
|
|
14139
|
+
};
|
|
14140
|
+
|
|
14093
14141
|
// UI component patterns - only ignored in JSX attributes, not in logic
|
|
14094
14142
|
const uiComponentPattern = /^(primary|secondary|tertiary|ghost|outline|link|muted|danger|warning|info|success|error|default|subtle|solid|soft|plain|flat|elevated|filled|tonal|text|contained|standard|xs|sm|md|lg|xl|2xl|3xl|4xl|5xl|xxs|xxl|small|medium|large|tiny|huge|compact|comfortable|spacious|left|right|center|top|bottom|start|end|middle|baseline|stretch|between|around|evenly|horizontal|vertical|row|column|inline|block|flex|grid|auto|none|hidden|visible|static|relative|absolute|fixed|sticky|on|off|hover|focus|click|blur|always|never)$/;
|
|
14095
14143
|
|
|
@@ -14311,6 +14359,9 @@ const noHardcodedStrings = {
|
|
|
14311
14359
|
// Always flag HTTP status codes and role names
|
|
14312
14360
|
if (isFlaggedSpecialStringHandler(str)) return false;
|
|
14313
14361
|
|
|
14362
|
+
// Skip Tailwind/CSS class strings
|
|
14363
|
+
if (isTailwindClassStringHandler(str)) return true;
|
|
14364
|
+
|
|
14314
14365
|
return allIgnorePatterns.some((pattern) => pattern.test(str));
|
|
14315
14366
|
};
|
|
14316
14367
|
|
package/package.json
CHANGED