eslint-plugin-code-style 1.11.4 → 1.11.7

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/index.js +12 -35
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ---
9
9
 
10
+ ## [1.11.7] - 2026-02-04
11
+
12
+ ### Changed
13
+
14
+ - **`no-hardcoded-strings`**
15
+ - Remove UI component pattern exemption - ALL enum-like attribute values are now flagged (e.g., `variant="primary"`, `size="large"`, `color="danger"`)
16
+ - Enforce consistent use of enums for component props to prevent typos
17
+
18
+ ---
19
+
20
+ ## [1.11.6] - 2026-02-04
21
+
22
+ ### Changed
23
+
24
+ - **`no-hardcoded-strings`**
25
+ - Flag `type` attribute in JSX elements (e.g., `<input type="text" />`) - should use enums to prevent typos
26
+ - Remove `type` from default ignored attributes list
27
+ - Remove "text" from UI component pattern (conflicts with input type)
28
+ - Update error message for JSX attributes: "should be imported from @/enums (preferred) or @/data to prevent typos"
29
+
30
+ ---
31
+
32
+ ## [1.11.5] - 2026-02-04
33
+
34
+ ### Fixed
35
+
36
+ - **`no-hardcoded-strings`**
37
+ - Flag hardcoded strings in component default params (e.g., `type = "text"`, `variant = "ghost"`)
38
+ - Flag hardcoded strings in ternary expressions (e.g., `showPassword ? "text" : "password"`)
39
+ - Remove overly broad HTML input type exemption from general string checks
40
+ - Remove "text" from CSS cursor pattern (conflicts with common input type usage)
41
+
42
+ ---
43
+
10
44
  ## [1.11.4] - 2026-02-04
11
45
 
12
46
  ### Fixed
@@ -1504,6 +1538,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1504
1538
 
1505
1539
  ---
1506
1540
 
1541
+ [1.11.7]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.6...v1.11.7
1542
+ [1.11.6]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.5...v1.11.6
1543
+ [1.11.5]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.4...v1.11.5
1507
1544
  [1.11.4]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.3...v1.11.4
1508
1545
  [1.11.3]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.2...v1.11.3
1509
1546
  [1.11.2]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.1...v1.11.2
package/index.js CHANGED
@@ -14561,7 +14561,7 @@ const noHardcodedStrings = {
14561
14561
  "textDecoration", // SVG
14562
14562
  "transform", // SVG
14563
14563
  "translate",
14564
- "type",
14564
+ // "type" removed - should use enums for input/button types to prevent typos
14565
14565
  "vectorEffect", // SVG
14566
14566
  "useMap",
14567
14567
  "value",
@@ -14646,8 +14646,8 @@ const noHardcodedStrings = {
14646
14646
  /^[a-zA-Z]+\d*[_a-zA-Z0-9]*(_[a-zA-Z0-9]+)+$/,
14647
14647
  // Color names (CSS named colors used in SVG)
14648
14648
  /^(white|black|red|green|blue|yellow|orange|purple|pink|brown|gray|grey|cyan|magenta|transparent)$/i,
14649
- // CSS cursor values
14650
- /^(auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|text|vertical-text|alias|copy|move|no-drop|not-allowed|grab|grabbing|all-scroll|col-resize|row-resize|n-resize|e-resize|s-resize|w-resize|ne-resize|nw-resize|se-resize|sw-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|zoom-in|zoom-out)$/,
14649
+ // CSS cursor values (excluding "text" as it conflicts with input type)
14650
+ /^(auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|vertical-text|alias|copy|move|no-drop|not-allowed|grab|grabbing|all-scroll|col-resize|row-resize|n-resize|e-resize|s-resize|w-resize|ne-resize|nw-resize|se-resize|sw-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|zoom-in|zoom-out)$/,
14651
14651
  // CSS display/visibility values
14652
14652
  /^(block|inline|inline-block|flex|inline-flex|grid|inline-grid|flow-root|contents|table|table-row|table-cell|list-item|none|visible|hidden|collapse)$/,
14653
14653
  // CSS position values
@@ -14801,9 +14801,6 @@ const noHardcodedStrings = {
14801
14801
  });
14802
14802
  };
14803
14803
 
14804
- // UI component patterns - only ignored in JSX attributes, not in logic
14805
- 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)$/;
14806
-
14807
14804
  // HTML input types - standard browser input types, not hardcoded strings
14808
14805
  const htmlInputTypes = new Set([
14809
14806
  "button",
@@ -14923,21 +14920,6 @@ const noHardcodedStrings = {
14923
14920
  return false;
14924
14921
  };
14925
14922
 
14926
- // Check if string is in a default parameter for input type
14927
- const isInputTypeDefaultParamHandler = (node) => {
14928
- // Check if we're in an AssignmentPattern (default param)
14929
- if (node.parent && node.parent.type === "AssignmentPattern") {
14930
- const assignPattern = node.parent;
14931
-
14932
- // Check if the parameter name is "type"
14933
- if (assignPattern.left && assignPattern.left.type === "Identifier" && assignPattern.left.name === "type") {
14934
- return true;
14935
- }
14936
- }
14937
-
14938
- return false;
14939
- };
14940
-
14941
14923
  // Check if this is a module-level exported string that should be flagged
14942
14924
  const isExportedHardcodedStringHandler = (node) => {
14943
14925
  let current = node.parent;
@@ -14995,19 +14977,23 @@ const noHardcodedStrings = {
14995
14977
  const isSingleWord = !/\s/.test(str) && str.length <= 30;
14996
14978
  const isAllLowercase = /^[a-z_]+$/.test(str);
14997
14979
 
14980
+ // For JSX attributes (type, variant, etc.), prefer enums to prevent typos
14981
+ const isJsxAttribute = context.includes("attribute");
14982
+
14998
14983
  if (isSingleWord && isAllLowercase) {
14999
- return `Hardcoded data keyword or enum "${truncatedStr}"${contextPart} should be imported from @/data or @/enums (e.g., import { StatusEnum } from "@/enums")`;
14984
+ if (isJsxAttribute) {
14985
+ return `Hardcoded "${truncatedStr}"${contextPart} should be imported from @/enums (preferred) or @/data to prevent typos (e.g., import { InputTypeEnum } from "@/enums")`;
14986
+ }
14987
+
14988
+ return `Hardcoded "${truncatedStr}"${contextPart} should be imported from @/enums (preferred) or @/data (e.g., import { StatusEnum } from "@/enums")`;
15000
14989
  }
15001
14990
 
15002
14991
  // UI string: starts with capital, has spaces, or multiple words
15003
- return `Hardcoded UI string "${truncatedStr}"${contextPart} should be imported from @/strings or @/constants or @/@strings or @/@constants (e.g., import { strings } from "@/strings")`;
14992
+ return `Hardcoded UI string "${truncatedStr}"${contextPart} should be imported from @/strings or @/constants (e.g., import { strings } from "@/strings")`;
15004
14993
  };
15005
14994
 
15006
14995
  // Check if a string matches any ignore pattern
15007
14996
  const shouldIgnoreStringHandler = (str) => {
15008
- // Skip HTML input types (text, password, email, etc.)
15009
- if (isHtmlInputTypeHandler(str)) return true;
15010
-
15011
14997
  // Skip Tailwind/CSS class strings
15012
14998
  if (isTailwindClassStringHandler(str)) return true;
15013
14999
 
@@ -15279,9 +15265,6 @@ const noHardcodedStrings = {
15279
15265
  if (node.value.type === "Literal" && typeof node.value.value === "string") {
15280
15266
  const str = node.value.value;
15281
15267
 
15282
- // Skip UI component patterns in JSX attributes (variant, size, position props)
15283
- if (uiComponentPattern.test(str)) return;
15284
-
15285
15268
  if (shouldIgnoreStringHandler(str)) return;
15286
15269
 
15287
15270
  // Check if it looks like user-facing text
@@ -15303,9 +15286,6 @@ const noHardcodedStrings = {
15303
15286
  if (expression.type === "Literal" && typeof expression.value === "string") {
15304
15287
  const str = expression.value;
15305
15288
 
15306
- // Skip UI component patterns in JSX attributes (variant, size, position props)
15307
- if (uiComponentPattern.test(str)) return;
15308
-
15309
15289
  if (shouldIgnoreStringHandler(str)) return;
15310
15290
 
15311
15291
  if (!/[a-zA-Z]/.test(str)) return;
@@ -15328,9 +15308,6 @@ const noHardcodedStrings = {
15328
15308
  // Skip if inside a style object (style={{ transform: "..." }})
15329
15309
  if (isInsideStyleObjectHandler(node)) return;
15330
15310
 
15331
- // Skip input type default params (e.g., type = "text")
15332
- if (isInputTypeDefaultParamHandler(node)) return;
15333
-
15334
15311
  // Check for exported hardcoded strings (e.g., export const tokenKey = "auth_token")
15335
15312
  // These should be flagged even at module level, regardless of whether the value
15336
15313
  // looks "technical" - the point is exposing hardcoded strings in exports
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-code-style",
3
- "version": "1.11.4",
3
+ "version": "1.11.7",
4
4
  "description": "A custom ESLint plugin for enforcing consistent code formatting and style rules in React/JSX projects",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",