@salesforce-ux/eslint-plugin-slds 1.0.8-internal → 1.0.9-internal

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 (107) hide show
  1. package/build/config/rule-messages.d.ts +2 -0
  2. package/build/config/rule-messages.js +197 -0
  3. package/build/config/rule-messages.js.map +7 -0
  4. package/build/index.js +40 -2471
  5. package/build/index.js.map +4 -4
  6. package/build/rules/enforce-bem-usage.js +16 -232
  7. package/build/rules/enforce-bem-usage.js.map +4 -4
  8. package/build/rules/modal-close-button-issue.js +11 -183
  9. package/build/rules/modal-close-button-issue.js.map +4 -4
  10. package/build/rules/no-deprecated-classes-slds2.js +4 -176
  11. package/build/rules/no-deprecated-classes-slds2.js.map +4 -4
  12. package/build/rules/v9/enforce-bem-usage.js +1 -161
  13. package/build/rules/v9/enforce-bem-usage.js.map +4 -4
  14. package/build/rules/v9/enforce-component-hook-naming-convention.js +1 -161
  15. package/build/rules/v9/enforce-component-hook-naming-convention.js.map +4 -4
  16. package/build/rules/v9/enforce-sds-to-slds-hooks.js +1 -161
  17. package/build/rules/v9/enforce-sds-to-slds-hooks.js.map +4 -4
  18. package/build/rules/v9/lwc-token-to-slds-hook.js +4 -262
  19. package/build/rules/v9/lwc-token-to-slds-hook.js.map +4 -4
  20. package/build/rules/v9/no-deprecated-slds-classes.js +1 -161
  21. package/build/rules/v9/no-deprecated-slds-classes.js.map +4 -4
  22. package/build/rules/v9/no-deprecated-tokens-slds1.js +29 -168
  23. package/build/rules/v9/no-deprecated-tokens-slds1.js.map +4 -4
  24. package/build/rules/v9/no-hardcoded-values/handlers/boxShadowHandler.js +9 -289
  25. package/build/rules/v9/no-hardcoded-values/handlers/boxShadowHandler.js.map +4 -4
  26. package/build/rules/v9/no-hardcoded-values/handlers/colorHandler.js +13 -283
  27. package/build/rules/v9/no-hardcoded-values/handlers/colorHandler.js.map +4 -4
  28. package/build/rules/v9/no-hardcoded-values/handlers/densityHandler.js +12 -328
  29. package/build/rules/v9/no-hardcoded-values/handlers/densityHandler.js.map +4 -4
  30. package/build/rules/v9/no-hardcoded-values/handlers/fontHandler.js +13 -309
  31. package/build/rules/v9/no-hardcoded-values/handlers/fontHandler.js.map +4 -4
  32. package/build/rules/v9/no-hardcoded-values/handlers/index.js +8 -875
  33. package/build/rules/v9/no-hardcoded-values/handlers/index.js.map +4 -4
  34. package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds1.js +3 -1208
  35. package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds1.js.map +4 -4
  36. package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds2.js +3 -1208
  37. package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds2.js.map +4 -4
  38. package/build/rules/v9/no-hardcoded-values/noHardcodedValueRule.js +22 -993
  39. package/build/rules/v9/no-hardcoded-values/noHardcodedValueRule.js.map +4 -4
  40. package/build/rules/v9/no-slds-class-overrides.js +1 -161
  41. package/build/rules/v9/no-slds-class-overrides.js.map +4 -4
  42. package/build/rules/v9/no-slds-namespace-for-custom-hooks.js +3 -252
  43. package/build/rules/v9/no-slds-namespace-for-custom-hooks.js.map +4 -4
  44. package/build/rules/v9/no-slds-private-var.js +1 -161
  45. package/build/rules/v9/no-slds-private-var.js.map +4 -4
  46. package/build/rules/v9/no-slds-var-without-fallback.js +3 -255
  47. package/build/rules/v9/no-slds-var-without-fallback.js.map +4 -4
  48. package/build/rules/v9/no-sldshook-fallback-for-lwctoken.js +1 -161
  49. package/build/rules/v9/no-sldshook-fallback-for-lwctoken.js.map +4 -4
  50. package/build/rules/v9/no-unsupported-hooks-slds2.js +1 -161
  51. package/build/rules/v9/no-unsupported-hooks-slds2.js.map +4 -4
  52. package/build/rules/v9/reduce-annotations.js +1 -161
  53. package/build/rules/v9/reduce-annotations.js.map +4 -4
  54. package/build/{src/utils → utils}/boxShadowValueParser.d.ts +1 -1
  55. package/build/utils/boxShadowValueParser.js +63 -93
  56. package/build/utils/boxShadowValueParser.js.map +4 -4
  57. package/build/utils/color-lib-utils.js +2 -29
  58. package/build/utils/color-lib-utils.js.map +3 -3
  59. package/build/{src/utils → utils}/css-utils.d.ts +7 -0
  60. package/build/utils/css-utils.js +10 -71
  61. package/build/utils/css-utils.js.map +4 -4
  62. package/build/utils/hardcoded-shared-utils.js +17 -82
  63. package/build/utils/hardcoded-shared-utils.js.map +4 -4
  64. package/build/utils/property-matcher.js +2 -2
  65. package/build/utils/property-matcher.js.map +2 -2
  66. package/build/utils/styling-hook-utils.js +16 -39
  67. package/build/utils/styling-hook-utils.js.map +3 -3
  68. package/build/{src/utils → utils}/value-utils.d.ts +2 -2
  69. package/build/utils/value-utils.js +8 -8
  70. package/build/utils/value-utils.js.map +2 -2
  71. package/package.json +5 -10
  72. package/src/config/rule-messages.yml +0 -143
  73. /package/build/{src/index.d.ts → index.d.ts} +0 -0
  74. /package/build/{src/rules → rules}/enforce-bem-usage.d.ts +0 -0
  75. /package/build/{src/rules → rules}/modal-close-button-issue.d.ts +0 -0
  76. /package/build/{src/rules → rules}/no-deprecated-classes-slds2.d.ts +0 -0
  77. /package/build/{src/rules → rules}/v9/enforce-bem-usage.d.ts +0 -0
  78. /package/build/{src/rules → rules}/v9/enforce-component-hook-naming-convention.d.ts +0 -0
  79. /package/build/{src/rules → rules}/v9/enforce-sds-to-slds-hooks.d.ts +0 -0
  80. /package/build/{src/rules → rules}/v9/lwc-token-to-slds-hook.d.ts +0 -0
  81. /package/build/{src/rules → rules}/v9/no-deprecated-slds-classes.d.ts +0 -0
  82. /package/build/{src/rules → rules}/v9/no-deprecated-tokens-slds1.d.ts +0 -0
  83. /package/build/{src/rules → rules}/v9/no-hardcoded-values/handlers/boxShadowHandler.d.ts +0 -0
  84. /package/build/{src/rules → rules}/v9/no-hardcoded-values/handlers/colorHandler.d.ts +0 -0
  85. /package/build/{src/rules → rules}/v9/no-hardcoded-values/handlers/densityHandler.d.ts +0 -0
  86. /package/build/{src/rules → rules}/v9/no-hardcoded-values/handlers/fontHandler.d.ts +0 -0
  87. /package/build/{src/rules → rules}/v9/no-hardcoded-values/handlers/index.d.ts +0 -0
  88. /package/build/{src/rules → rules}/v9/no-hardcoded-values/no-hardcoded-values-slds1.d.ts +0 -0
  89. /package/build/{src/rules → rules}/v9/no-hardcoded-values/no-hardcoded-values-slds2.d.ts +0 -0
  90. /package/build/{src/rules → rules}/v9/no-hardcoded-values/noHardcodedValueRule.d.ts +0 -0
  91. /package/build/{src/rules → rules}/v9/no-hardcoded-values/ruleOptionsSchema.d.ts +0 -0
  92. /package/build/{src/rules → rules}/v9/no-slds-class-overrides.d.ts +0 -0
  93. /package/build/{src/rules → rules}/v9/no-slds-namespace-for-custom-hooks.d.ts +0 -0
  94. /package/build/{src/rules → rules}/v9/no-slds-private-var.d.ts +0 -0
  95. /package/build/{src/rules → rules}/v9/no-slds-var-without-fallback.d.ts +0 -0
  96. /package/build/{src/rules → rules}/v9/no-sldshook-fallback-for-lwctoken.d.ts +0 -0
  97. /package/build/{src/rules → rules}/v9/no-unsupported-hooks-slds2.d.ts +0 -0
  98. /package/build/{src/rules → rules}/v9/reduce-annotations.d.ts +0 -0
  99. /package/build/{src/types → types}/index.d.ts +0 -0
  100. /package/build/{src/utils → utils}/color-lib-utils.d.ts +0 -0
  101. /package/build/{src/utils → utils}/css-functions.d.ts +0 -0
  102. /package/build/{src/utils → utils}/custom-mapping-utils.d.ts +0 -0
  103. /package/build/{src/utils → utils}/hardcoded-shared-utils.d.ts +0 -0
  104. /package/build/{src/utils → utils}/node.d.ts +0 -0
  105. /package/build/{src/utils → utils}/property-matcher.d.ts +0 -0
  106. /package/build/{src/utils → utils}/rule-utils.d.ts +0 -0
  107. /package/build/{src/utils → utils}/styling-hook-utils.d.ts +0 -0
@@ -4,9 +4,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __getProtoOf = Object.getPrototypeOf;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __commonJS = (cb, mod) => function __require() {
8
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
- };
10
7
  var __export = (target, all) => {
11
8
  for (var name in all)
12
9
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -29,163 +26,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
26
  ));
30
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
28
 
32
- // yaml-file:rule-messages.yml
33
- var require_rule_messages = __commonJS({
34
- "yaml-file:rule-messages.yml"(exports2, module2) {
35
- module2.exports = {
36
- "no-slds-class-overrides": {
37
- "description": "Create new custom CSS classes instead of overriding SLDS selectors",
38
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-slds-class-overrides",
39
- "type": "problem",
40
- "messages": {
41
- "sldsClassOverride": "Overriding .{{className}} isn't supported. To differentiate SLDS and custom classes, create a CSS class in your namespace. Examples: myapp-input, myapp-button."
42
- }
43
- },
44
- "no-deprecated-slds-classes": {
45
- "description": "Please replace the deprecated classes with a modern equivalent",
46
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-deprecated-slds-classes",
47
- "type": "problem",
48
- "messages": {
49
- "deprecatedClass": "The class {{className}} is deprecated and not available in SLDS2. Please update to a supported class."
50
- }
51
- },
52
- "no-deprecated-tokens-slds1": {
53
- "description": "Update outdated design tokens to SLDS 2 styling hooks with similar values. For more information, see Styling Hooks on lightningdesignsystem.com.",
54
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-deprecated-tokens-slds1",
55
- "type": "problem",
56
- "messages": {
57
- "deprecatedToken": "Consider removing {{oldValue}} or replacing it with {{newValue}}. Set the fallback to {{oldValue}}. For more info, see Styling Hooks on lightningdesignsystem.com.",
58
- "noReplacement": "Update outdated design tokens to SLDS 2 styling hooks with similar values. For more information, see Styling Hooks on lightningdesignsystem.com."
59
- }
60
- },
61
- "enforce-sds-to-slds-hooks": {
62
- "description": "Convert your existing --sds styling hooks to --slds styling hooks. See lightningdesignsystem.com for more info.",
63
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#enforce-sds-to-slds-hooks",
64
- "type": "problem",
65
- "messages": {
66
- "replaceSdsWithSlds": "Replace {{oldValue}} with {{suggestedMatch}} styling hook."
67
- }
68
- },
69
- "enforce-bem-usage": {
70
- "description": "Replace BEM double-dash syntax in class names with single underscore syntax",
71
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#enforce-bem-usage",
72
- "type": "problem",
73
- "messages": {
74
- "bemDoubleDash": "{{actual}} has been retired. Update it to the new name {{newValue}}.",
75
- "fixBemNaming": "Update to correct BEM naming convention"
76
- }
77
- },
78
- "modal-close-button-issue": {
79
- "description": "Update component attributes or CSS classes for the modal close button to comply with the modal component blueprint",
80
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#modal-close-button-issue",
81
- "type": "problem",
82
- "messages": {
83
- "modalCloseButtonIssue": "Update component attributes or CSS classes for the modal close button to comply with the modal component blueprint.",
84
- "removeClass": "Remove the slds-button_icon-inverse class from the modal close button in components that use the SLDS modal blueprint.",
85
- "changeVariant": "Change the variant attribute value from bare-inverse to bare in <lightning-button-icon> or <lightning-icon>.",
86
- "removeVariant": "Remove the variant attribute from the <lightning-icon> component inside the <button> element.",
87
- "ensureButtonClasses": "Add or move slds-button and slds-button_icon to the class attribute of the <button> element or <lightning-button-icon> component.",
88
- "ensureSizeAttribute": "To size icons properly, set the size attribute \u200Cto large in the <lightning-icon> and <lightning-button-icon> components."
89
- }
90
- },
91
- "no-deprecated-classes-slds2": {
92
- "description": "Replace classes that aren't available with SLDS 2 classes",
93
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-deprecated-classes-slds2",
94
- "type": "problem",
95
- "messages": {
96
- "deprecatedClass": "The class {{className}} isn't available in SLDS 2. Update it to a class supported in SLDS 2. See lightningdesignsystem.com for more information.",
97
- "updateToModernClass": "Replace deprecated class with modern equivalent",
98
- "checkDocumentation": "See lightningdesignsystem.com for SLDS 2 class alternatives"
99
- }
100
- },
101
- "lwc-token-to-slds-hook": {
102
- "description": "Replace the deprecated --lwc tokens with the latest --slds tokens. See lightningdesignsystem.com for more info.",
103
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#lwc-token-to-slds-hook",
104
- "type": "problem",
105
- "messages": {
106
- "errorWithReplacement": "The '{{oldValue}}' design token is deprecated. Replace it with '{{newValue}}'. For more info, see Global Styling Hooks on lightningdesignsystem.com.",
107
- "errorWithStyleHooks": "The '{{oldValue}}' design token is deprecated. Replace it with the SLDS 2 '{{newValue}}' styling hook and set the fallback to '{{oldValue}}'. For more info, see Global Styling Hooks on lightningdesignsystem.com.",
108
- "errorWithNoRecommendation": "The '{{oldValue}}' design token is deprecated. For more info, see the New Global Styling Hook Guidance on lightningdesignsystem.com."
109
- }
110
- },
111
- "no-sldshook-fallback-for-lwctoken": {
112
- "description": "Avoid using --slds styling hooks as fallback values for --lwc tokens.",
113
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-sldshook-fallback-for-lwctoken",
114
- "type": "problem",
115
- "messages": {
116
- "unsupportedFallback": "Remove the {{sldsToken}} styling hook that is used as a fallback value for {{lwcToken}}."
117
- }
118
- },
119
- "no-unsupported-hooks-slds2": {
120
- "description": "Identifies styling hooks that aren't present in SLDS 2. They must be replaced with styling hooks that have a similar effect, or they must be removed.",
121
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-unsupported-hooks-slds2",
122
- "type": "problem",
123
- "messages": {
124
- "deprecated": "The {{token}} styling hook isn't present in SLDS 2 and there's no equivalent replacement. Remove it or replace it with a styling hook with a similar effect."
125
- }
126
- },
127
- "no-slds-var-without-fallback": {
128
- "description": "Add fallback values to SLDS styling hooks. The fallback values are used in Salesforce environments where styling hooks are unavailable.",
129
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-slds-var-without-fallback",
130
- "type": "problem",
131
- "messages": {
132
- "varWithoutFallback": "Your code uses the {{cssVar}} styling hook without a fallback value. Styling hooks are unavailable in some Salesforce environments. To render your component correctly in all environments, add this fallback value: var({{cssVar}}, {{recommendation}}). To make this fallback value brand-aware, use a branded design token instead of a static value. See Design Tokens on v1.lightningdesignsystem.com."
133
- }
134
- },
135
- "no-slds-namespace-for-custom-hooks": {
136
- "description": "To differentiate custom styling hooks from SLDS styling hooks, create custom styling hooks in your namespace.",
137
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-slds-namespace-for-custom-hooks",
138
- "type": "problem",
139
- "messages": {
140
- "customHookNamespace": "Using the --slds namespace for {{token}} isn't supported. Create the custom styling hook in your namespace. Example: --myapp-{{tokenWithoutNamespace}}"
141
- }
142
- },
143
- "no-slds-private-var": {
144
- "description": "Some SLDS styling hooks are private and reserved only for internal Salesforce use. Private SLDS styling hooks have prefixes --_slds- and --slds-s-. For more information, look up private CSS in lightningdesignsystem.com.",
145
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-slds-private-var",
146
- "type": "problem",
147
- "messages": {
148
- "privateVar": "This styling hook is reserved for internal Salesforce use. Remove the --_slds- or \u2013slds-s private variable within selector {{prop}}. For more information, look up private CSS in lightningdesignsystem.com."
149
- }
150
- },
151
- "enforce-component-hook-naming-convention": {
152
- "description": "Replace component styling hooks that use a deprecated naming convention.",
153
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#enforce-component-hook-naming-convention",
154
- "type": "problem",
155
- "messages": {
156
- "replace": "Replace the deprecated {{oldValue}} component styling hook with {{suggestedMatch}}."
157
- }
158
- },
159
- "no-hardcoded-values-slds1": {
160
- "description": "Replace static values with SLDS 1 design tokens. For more information, look up design tokens on lightningdesignsystem.com.",
161
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-hardcoded-value",
162
- "type": "suggestion",
163
- "messages": {
164
- "hardcodedValue": "Replace the {{oldValue}} static value with an SLDS 1 styling hook: {{newValue}}.",
165
- "noReplacement": "There's no replacement styling hook for the {{oldValue}} static value. Remove the static value."
166
- }
167
- },
168
- "no-hardcoded-values-slds2": {
169
- "description": "Replace static values with SLDS 2 styling hooks. For more information, look up design tokens on lightningdesignsystem.com.",
170
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-hardcoded-values-slds2",
171
- "type": "suggestion",
172
- "messages": {
173
- "hardcodedValue": "Consider replacing the {{oldValue}} static value with an SLDS 2 styling hook that has a similar value: {{newValue}}.",
174
- "noReplacement": "There's no replacement styling hook for the {{oldValue}} static value. Remove the static value."
175
- }
176
- },
177
- "reduce-annotations": {
178
- "description": "Remove your annotations and update your code.",
179
- "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#reduce-annotations",
180
- "type": "problem",
181
- "messages": {
182
- "removeAnnotation": "Remove this annotation and update the code to SLDS best practices. For help, file an issue at https://github.com/salesforce-ux/slds-linter/"
183
- }
184
- }
185
- };
186
- }
187
- });
188
-
189
29
  // src/rules/v9/no-hardcoded-values/no-hardcoded-values-slds2.ts
190
30
  var no_hardcoded_values_slds2_exports = {};
191
31
  __export(no_hardcoded_values_slds2_exports, {
@@ -193,1058 +33,13 @@ __export(no_hardcoded_values_slds2_exports, {
193
33
  });
194
34
  module.exports = __toCommonJS(no_hardcoded_values_slds2_exports);
195
35
  var import_next = __toESM(require("@salesforce-ux/sds-metadata/next"));
196
- var import_rule_messages = __toESM(require_rule_messages());
197
-
198
- // src/utils/color-lib-utils.ts
199
- var import_chroma_js = __toESM(require("chroma-js"));
200
- var import_css_tree = require("@eslint/css-tree");
201
-
202
- // src/utils/css-functions.ts
203
- var CSS_FUNCTIONS = [
204
- "attr",
205
- "calc",
206
- "color-mix",
207
- "conic-gradient",
208
- "counter",
209
- "cubic-bezier",
210
- "linear-gradient",
211
- "max",
212
- "min",
213
- "radial-gradient",
214
- "repeating-conic-gradient",
215
- "repeating-linear-gradient",
216
- "repeating-radial-gradient",
217
- "var"
218
- ];
219
- var CSS_MATH_FUNCTIONS = ["calc", "min", "max"];
220
- var RGB_COLOR_FUNCTIONS = ["rgb", "rgba", "hsl", "hsla"];
221
- var cssFunctionsRegex = new RegExp(`(?:${CSS_FUNCTIONS.join("|")})`);
222
- var cssFunctionsExactRegex = new RegExp(`^(?:${CSS_FUNCTIONS.join("|")})$`);
223
- var cssMathFunctionsRegex = new RegExp(`^(?:${CSS_MATH_FUNCTIONS.join("|")})$`);
224
- function isCssFunction(value) {
225
- return cssFunctionsExactRegex.test(value);
226
- }
227
- function isCssColorFunction(value) {
228
- return RGB_COLOR_FUNCTIONS.includes(value);
229
- }
230
-
231
- // src/utils/color-lib-utils.ts
232
- var DELTAE_THRESHOLD = 10;
233
- var convertToHex = (color) => {
234
- try {
235
- return (0, import_chroma_js.default)(color).hex();
236
- } catch (e) {
237
- return null;
238
- }
239
- };
240
- var isHookPropertyMatch = (hook, cssProperty) => {
241
- return hook.properties.includes(cssProperty) || hook.properties.includes("*");
242
- };
243
- function getOrderByCssProp(cssProperty) {
244
- if (cssProperty === "color" || cssProperty === "fill") {
245
- return ["surface", "theme", "feedback", "reference"];
246
- } else if (cssProperty.match(/background/)) {
247
- return ["surface", "surface-inverse", "theme", "feedback", "reference"];
248
- } else if (cssProperty.match(/border/) || cssProperty.match(/outline/) || cssProperty.match(/stroke/)) {
249
- return ["borders", "borders-inverse", "feedback", "theme", "reference"];
250
- }
251
- return ["surface", "surface-inverse", "borders", "borders-inverse", "theme", "feedback", "reference"];
252
- }
253
- var findClosestColorHook = (color, supportedColors, cssProperty) => {
254
- const closestHooks = [];
255
- Object.entries(supportedColors).forEach(([sldsValue, data]) => {
256
- if (sldsValue && isValidColor(sldsValue)) {
257
- const hooks = data;
258
- hooks.forEach((hook) => {
259
- const distance = sldsValue.toLowerCase() === color.toLowerCase() ? 0 : import_chroma_js.default.deltaE(sldsValue, color);
260
- if (isHookPropertyMatch(hook, cssProperty) && distance <= DELTAE_THRESHOLD) {
261
- closestHooks.push({ distance, group: hook.group, name: hook.name });
262
- }
263
- });
264
- }
265
- });
266
- const hooksByGroupMap = closestHooks.sort((a, b) => a.distance - b.distance).reduce((acc, hook) => {
267
- if (!acc[hook.group]) {
268
- acc[hook.group] = [];
269
- }
270
- acc[hook.group].push(hook.name);
271
- return acc;
272
- }, {});
273
- return getOrderByCssProp(cssProperty).map((group) => hooksByGroupMap[group] || []).flat().slice(0, 5);
274
- };
275
- var isValidColor = (val) => import_chroma_js.default.valid(val);
276
- var extractColorValue = (node) => {
277
- let colorValue = null;
278
- switch (node.type) {
279
- case "Hash":
280
- colorValue = `#${node.value}`;
281
- break;
282
- case "Identifier":
283
- colorValue = node.name;
284
- break;
285
- case "Function":
286
- if (isCssColorFunction(node.name)) {
287
- colorValue = (0, import_css_tree.generate)(node);
288
- }
289
- break;
290
- }
291
- return colorValue && isValidColor(colorValue) ? colorValue : null;
292
- };
293
-
294
- // src/utils/property-matcher.ts
295
- var DIRECTION_VALUES = "(?:top|right|bottom|left|inline|block|inline-start|inline-end|start|end|block-start|block-end)";
296
- var CORNER_VALUES = "(?:top-left|top-right|bottom-right|bottom-left|start-start|start-end|end-start|end-end)";
297
- var INSET_VALUES = "(?:inline|block|inline-start|inline-end|block-start|block-end)";
298
- var BORDER_COLOR_REGEX = new RegExp(`^border(?:-${DIRECTION_VALUES})?-color$`);
299
- var BORDER_WIDTH_REGEX = new RegExp(`^border(?:-${DIRECTION_VALUES})?-width$`);
300
- var MARGIN_REGEX = new RegExp(`^margin(?:-${DIRECTION_VALUES})?$`);
301
- var PADDING_REGEX = new RegExp(`^padding(?:-${DIRECTION_VALUES})?$`);
302
- var BORDER_RADIUS_REGEX = new RegExp(`^border(?:-${CORNER_VALUES})?-radius$`);
303
- var INSET_REGEX = new RegExp(`^inset(?:-${INSET_VALUES})?$`);
304
- function isBorderColorProperty(cssProperty) {
305
- return BORDER_COLOR_REGEX.test(cssProperty);
306
- }
307
- function isBorderWidthProperty(cssProperty) {
308
- return BORDER_WIDTH_REGEX.test(cssProperty);
309
- }
310
- function isMarginProperty(cssProperty) {
311
- return MARGIN_REGEX.test(cssProperty);
312
- }
313
- function isPaddingProperty(cssProperty) {
314
- return PADDING_REGEX.test(cssProperty);
315
- }
316
- function isBorderRadius(cssProperty) {
317
- return BORDER_RADIUS_REGEX.test(cssProperty);
318
- }
319
- function isDimensionProperty(cssProperty) {
320
- return ["width", "height", "min-width", "max-width", "min-height", "max-height"].includes(cssProperty);
321
- }
322
- function isInsetProperty(cssProperty) {
323
- return INSET_REGEX.test(cssProperty);
324
- }
325
- var fontProperties = [
326
- "font",
327
- "font-size",
328
- "font-weight"
329
- ];
330
- var colorProperties = [
331
- "color",
332
- "fill",
333
- "background",
334
- "background-color",
335
- "stroke",
336
- "border",
337
- "border*",
338
- "border*-color",
339
- "outline",
340
- "outline-color"
341
- ];
342
- var densificationProperties = [
343
- "border*",
344
- "margin*",
345
- "padding*",
346
- "width",
347
- "height",
348
- "min-width",
349
- "max-width",
350
- "min-height",
351
- "max-height",
352
- "inset",
353
- "top",
354
- "right",
355
- "left",
356
- "bottom",
357
- "outline",
358
- "outline-width",
359
- "line-height"
360
- ];
361
- function toSelector(properties) {
362
- const selectorParts = properties.map((prop) => {
363
- if (prop.includes("*")) {
364
- const regexPattern = prop.replace(/\*/g, ".*");
365
- return `Declaration[property=/^${regexPattern}$/]`;
366
- } else {
367
- return `Declaration[property='${prop}']`;
368
- }
369
- });
370
- return selectorParts.join(", ");
371
- }
372
- function resolveDensityPropertyToMatch(cssProperty) {
373
- const propertyToMatch = cssProperty.toLowerCase();
374
- if (isOutlineWidthProperty(propertyToMatch) || isBorderWidthProperty(propertyToMatch)) {
375
- return "border-width";
376
- } else if (isMarginProperty(propertyToMatch)) {
377
- return "margin";
378
- } else if (isPaddingProperty(propertyToMatch)) {
379
- return "padding";
380
- } else if (isBorderRadius(propertyToMatch)) {
381
- return "border-radius";
382
- } else if (isDimensionProperty(propertyToMatch)) {
383
- return "width";
384
- } else if (isInsetProperty(propertyToMatch)) {
385
- return "top";
386
- }
387
- return propertyToMatch;
388
- }
389
- function resolveColorPropertyToMatch(cssProperty) {
390
- const propertyToMatch = cssProperty.toLowerCase();
391
- if (propertyToMatch === "outline" || propertyToMatch === "outline-color") {
392
- return "border-color";
393
- } else if (propertyToMatch === "background" || propertyToMatch === "background-color") {
394
- return "background-color";
395
- } else if (isBorderColorProperty(propertyToMatch)) {
396
- return "border-color";
397
- }
398
- return propertyToMatch;
399
- }
400
- function isOutlineWidthProperty(propertyToMatch) {
401
- return propertyToMatch === "outline" || propertyToMatch === "outline-width";
402
- }
403
-
404
- // src/utils/hardcoded-shared-utils.ts
405
- var import_css_tree2 = require("@eslint/css-tree");
406
-
407
- // src/utils/value-utils.ts
408
- var ALLOWED_UNITS = ["px", "em", "rem", "%", "ch"];
409
- function parseUnitValue(value) {
410
- if (!value) return null;
411
- const unitsPattern = ALLOWED_UNITS.join("|");
412
- const regex = new RegExp(`^(-?\\d*\\.?\\d+)(${unitsPattern})?$`);
413
- const match = value.match(regex);
414
- if (!match) return null;
415
- const number = parseFloat(match[1]);
416
- const unit = match[2] ? match[2] : null;
417
- if (isNaN(number)) return null;
418
- return { number, unit };
419
- }
420
- function toAlternateUnitValue(numberVal, unitType) {
421
- if (unitType === "px") {
422
- let floatValue = parseFloat(`${numberVal / 16}`);
423
- if (!isNaN(floatValue)) {
424
- return {
425
- unit: "rem",
426
- number: parseFloat(floatValue.toFixed(4))
427
- };
428
- }
429
- } else if (unitType === "rem") {
430
- const intValue = parseInt(`${numberVal * 16}`);
431
- if (!isNaN(intValue)) {
432
- return {
433
- unit: "px",
434
- number: intValue
435
- };
436
- }
437
- }
438
- return null;
439
- }
440
-
441
- // src/utils/hardcoded-shared-utils.ts
442
- var FONT_WEIGHTS = [
443
- "normal",
444
- "bold",
445
- "bolder",
446
- "lighter",
447
- "100",
448
- "200",
449
- "300",
450
- "400",
451
- "500",
452
- "600",
453
- "700",
454
- "800",
455
- "900"
456
- ];
457
- function isKnownFontWeight(value) {
458
- const stringValue = value.toString();
459
- return FONT_WEIGHTS.includes(stringValue.toLowerCase());
460
- }
461
- function handleShorthandAutoFix(declarationNode, context, valueText, replacements) {
462
- if (!replacements || replacements.length === 0) {
463
- return;
464
- }
465
- const sortedReplacements = replacements.sort((a, b) => b.start - a.start);
466
- const reportNumericValue = context.options?.reportNumericValue || "always";
467
- const fixCallback = (start, originalValue, replacement) => {
468
- let newValue = valueText;
469
- newValue = newValue.substring(0, start) + replacement + newValue.substring(start + originalValue.length);
470
- if (newValue !== valueText) {
471
- return (fixer) => {
472
- return fixer.replaceText(declarationNode.value, newValue);
473
- };
474
- }
475
- };
476
- sortedReplacements.forEach(({ start, end, replacement, displayValue, hasHook, isNumeric }) => {
477
- const originalValue = valueText.substring(start, end);
478
- if (isNumeric) {
479
- if (reportNumericValue === "never") {
480
- return;
481
- }
482
- if (reportNumericValue === "hasReplacement" && !hasHook) {
483
- return;
484
- }
485
- }
486
- const valueColumnStart = declarationNode.value.loc.start.column + start;
487
- const valueColumnEnd = valueColumnStart + originalValue.length;
488
- const canAutoFix = originalValue !== replacement;
489
- const { loc: { start: locStart, end: locEnd } } = declarationNode.value;
490
- const reportNode = {
491
- ...declarationNode.value,
492
- loc: {
493
- ...declarationNode.value.loc,
494
- start: {
495
- ...locStart,
496
- column: valueColumnStart
497
- },
498
- end: {
499
- ...locEnd,
500
- column: valueColumnEnd
501
- }
502
- }
503
- };
504
- if (hasHook) {
505
- const fix = canAutoFix ? fixCallback(start, originalValue, replacement) : void 0;
506
- context.context.report({
507
- node: reportNode,
508
- messageId: "hardcodedValue",
509
- data: {
510
- oldValue: originalValue,
511
- newValue: displayValue
512
- },
513
- fix
514
- });
515
- } else {
516
- context.context.report({
517
- node: reportNode,
518
- messageId: "noReplacement",
519
- data: {
520
- oldValue: originalValue
521
- }
522
- });
523
- }
524
- });
525
- }
526
- function forEachValue(valueText, extractValue, shouldSkipNode, callback) {
527
- if (!valueText || typeof valueText !== "string") {
528
- return;
529
- }
530
- try {
531
- const ast = (0, import_css_tree2.parse)(valueText, { context: "value", positions: true });
532
- (0, import_css_tree2.walk)(ast, {
533
- enter(node) {
534
- if (shouldSkipNode(node)) {
535
- return this.skip;
536
- }
537
- const value = extractValue(node);
538
- if (value !== null) {
539
- const positionInfo = {
540
- start: node.loc?.start,
541
- end: node.loc?.end
542
- };
543
- callback(value, positionInfo);
544
- }
545
- }
546
- });
547
- } catch (error) {
548
- return;
549
- }
550
- }
551
- function shouldSkipColorNode(node) {
552
- return node.type === "Function" && isCssFunction(node.name);
553
- }
554
- function shouldSkipDimensionNode(node) {
555
- return node.type === "Function";
556
- }
557
- function extractDimensionValue(valueNode, cssProperty) {
558
- if (!valueNode) return null;
559
- switch (valueNode.type) {
560
- case "Dimension":
561
- const numValue = Number(valueNode.value);
562
- if (numValue === 0) return null;
563
- const unit = valueNode.unit.toLowerCase();
564
- if (!ALLOWED_UNITS.includes(unit)) return null;
565
- return {
566
- number: numValue,
567
- unit
568
- };
569
- case "Number":
570
- const numberValue = Number(valueNode.value);
571
- if (numberValue === 0) return null;
572
- return {
573
- number: numberValue,
574
- unit: null
575
- };
576
- case "Percentage":
577
- const percentValue = Number(valueNode.value);
578
- if (percentValue === 0) return null;
579
- return {
580
- number: percentValue,
581
- unit: "%"
582
- };
583
- case "Value":
584
- return valueNode.children?.[0] ? extractDimensionValue(valueNode.children[0], cssProperty) : null;
585
- }
586
- return null;
587
- }
588
- function forEachColorValue(valueText, callback) {
589
- forEachValue(valueText, extractColorValue, shouldSkipColorNode, callback);
590
- }
591
- function forEachDensityValue(valueText, cssProperty, callback) {
592
- forEachValue(
593
- valueText,
594
- (node) => extractDimensionValue(node, cssProperty),
595
- shouldSkipDimensionNode,
596
- callback
597
- );
598
- }
599
- function extractFontValue(node) {
600
- if (!node) return null;
601
- switch (node.type) {
602
- case "Dimension":
603
- const numValue = Number(node.value);
604
- if (numValue <= 0) return null;
605
- const unit = node.unit.toLowerCase();
606
- if (!ALLOWED_UNITS.includes(unit)) return null;
607
- return {
608
- number: numValue,
609
- unit
610
- };
611
- case "Number":
612
- const numberValue = Number(node.value);
613
- if (numberValue <= 0) {
614
- return null;
615
- }
616
- if (!isKnownFontWeight(numberValue)) {
617
- return null;
618
- }
619
- return {
620
- number: numberValue,
621
- unit: null
622
- };
623
- case "Identifier":
624
- const namedValue = node.name.toLowerCase();
625
- if (!isKnownFontWeight(namedValue)) {
626
- return null;
627
- }
628
- if (namedValue === "normal") {
629
- return { number: 400, unit: null };
630
- }
631
- return { number: namedValue, unit: null };
632
- case "Percentage":
633
- const percentValue = Number(node.value);
634
- if (percentValue === 0) return null;
635
- return {
636
- number: percentValue,
637
- unit: "%"
638
- };
639
- case "Value":
640
- return node.children?.[0] ? extractFontValue(node.children[0]) : null;
641
- }
642
- return null;
643
- }
644
- function shouldSkipFontNode(node) {
645
- return node.type === "Function";
646
- }
647
- function forEachFontValue(valueText, callback) {
648
- forEachValue(valueText, extractFontValue, shouldSkipFontNode, callback);
649
- }
650
-
651
- // src/utils/css-utils.ts
652
- function formatSuggestionHooks(hooks) {
653
- if (hooks.length === 1) {
654
- return `${hooks[0]}`;
655
- }
656
- return "\n" + hooks.map((hook, index) => `${index + 1}. ${hook}`).join("\n");
657
- }
658
-
659
- // src/utils/custom-mapping-utils.ts
660
- function matchesPropertyPattern(cssProperty, pattern) {
661
- const normalizedProperty = cssProperty.toLowerCase();
662
- const normalizedPattern = pattern.toLowerCase();
663
- if (normalizedProperty === normalizedPattern) {
664
- return true;
665
- }
666
- if (normalizedPattern.endsWith("*")) {
667
- const prefix = normalizedPattern.slice(0, -1);
668
- return normalizedProperty.startsWith(prefix);
669
- }
670
- return false;
671
- }
672
- function getCustomMapping(cssProperty, value, customMapping) {
673
- if (!customMapping) {
674
- return null;
675
- }
676
- const normalizedValue = value.toLowerCase().trim();
677
- for (const [hookName, config] of Object.entries(customMapping)) {
678
- const propertyMatches = config.properties.some(
679
- (pattern) => matchesPropertyPattern(cssProperty, pattern)
680
- );
681
- if (!propertyMatches) {
682
- continue;
683
- }
684
- const valueMatches = config.values.some(
685
- (configValue) => configValue.toLowerCase().trim() === normalizedValue
686
- );
687
- if (valueMatches) {
688
- return hookName;
689
- }
690
- }
691
- return null;
692
- }
693
-
694
- // src/rules/v9/no-hardcoded-values/handlers/colorHandler.ts
695
- var handleColorDeclaration = (node, context) => {
696
- const cssProperty = node.property.toLowerCase();
697
- const valueText = context.sourceCode.getText(node.value);
698
- const replacements = [];
699
- forEachColorValue(valueText, (colorValue, positionInfo) => {
700
- if (colorValue !== "transparent" && isValidColor(colorValue)) {
701
- const replacement = createColorReplacement(colorValue, cssProperty, context, positionInfo, valueText);
702
- if (replacement) {
703
- replacements.push(replacement);
704
- }
705
- }
706
- });
707
- handleShorthandAutoFix(node, context, valueText, replacements);
708
- };
709
- function createColorReplacement(colorValue, cssProperty, context, positionInfo, originalValueText) {
710
- if (!positionInfo?.start) {
711
- return null;
712
- }
713
- const hexValue = convertToHex(colorValue);
714
- if (!hexValue) {
715
- return null;
716
- }
717
- const start = positionInfo.start.offset;
718
- const end = positionInfo.end.offset;
719
- const originalValue = originalValueText ? originalValueText.substring(start, end) : colorValue;
720
- const customHook = getCustomMapping(cssProperty, colorValue, context.options?.customMapping);
721
- let closestHooks = [];
722
- if (customHook) {
723
- closestHooks = [customHook];
724
- } else {
725
- const propToMatch = resolveColorPropertyToMatch(cssProperty);
726
- closestHooks = findClosestColorHook(hexValue, context.valueToStylinghook, propToMatch);
727
- }
728
- let replacement = originalValue;
729
- let paletteHook = null;
730
- if (context.options?.preferPaletteHook && closestHooks.length > 1) {
731
- paletteHook = closestHooks.filter((hook) => hook.includes("-palette-"))[0];
732
- }
733
- if (paletteHook) {
734
- replacement = `var(${paletteHook}, ${colorValue})`;
735
- } else if (closestHooks.length === 1) {
736
- replacement = `var(${closestHooks[0]}, ${colorValue})`;
737
- }
738
- if (closestHooks.length > 0) {
739
- return {
740
- start,
741
- end,
742
- replacement,
743
- // Use original value to preserve spacing
744
- displayValue: formatSuggestionHooks(closestHooks),
745
- hasHook: true
746
- };
747
- } else {
748
- return {
749
- start,
750
- end,
751
- replacement,
752
- // Use original value to preserve spacing
753
- displayValue: originalValue,
754
- hasHook: false
755
- };
756
- }
757
- }
758
-
759
- // src/utils/styling-hook-utils.ts
760
- function isValueMatch(valueToMatch, sldsValue) {
761
- if (!valueToMatch || !sldsValue) {
762
- return false;
763
- }
764
- return valueToMatch.unit == sldsValue.unit && valueToMatch.number === sldsValue.number;
765
- }
766
- function getStylingHooksForDensityValue(parsedValue, supportedStylinghooks, cssProperty) {
767
- if (!parsedValue) return [];
768
- const alternateValue = toAlternateUnitValue(parsedValue.number, parsedValue.unit);
769
- const matchedHooks = [];
770
- for (const [sldsValue, hooks] of Object.entries(supportedStylinghooks)) {
771
- const parsedSldsValue = parseUnitValue(sldsValue);
772
- if (isValueMatch(parsedValue, parsedSldsValue) || alternateValue && isValueMatch(alternateValue, parsedSldsValue)) {
773
- hooks.filter((hook) => hook.properties.includes(cssProperty)).forEach((hook) => matchedHooks.push(hook.name));
774
- }
775
- }
776
- return matchedHooks;
777
- }
778
-
779
- // src/rules/v9/no-hardcoded-values/handlers/densityHandler.ts
780
- var handleDensityDeclaration = (node, context) => {
781
- const cssProperty = node.property.toLowerCase();
782
- const valueText = context.sourceCode.getText(node.value);
783
- const replacements = [];
784
- forEachDensityValue(valueText, cssProperty, (parsedDimension, positionInfo) => {
785
- if (parsedDimension) {
786
- const replacement = createDimensionReplacement(parsedDimension, cssProperty, context, positionInfo);
787
- if (replacement) {
788
- replacements.push(replacement);
789
- }
790
- }
791
- });
792
- handleShorthandAutoFix(node, context, valueText, replacements);
793
- };
794
- function createDimensionReplacement(parsedDimension, cssProperty, context, positionInfo) {
795
- if (!parsedDimension || !positionInfo?.start) {
796
- return null;
797
- }
798
- const rawValue = parsedDimension.unit ? `${parsedDimension.number}${parsedDimension.unit}` : parsedDimension.number.toString();
799
- const customHook = getCustomMapping(cssProperty, rawValue, context.options?.customMapping);
800
- let closestHooks = [];
801
- if (customHook) {
802
- closestHooks = [customHook];
803
- } else {
804
- const propToMatch = resolveDensityPropertyToMatch(cssProperty);
805
- closestHooks = getStylingHooksForDensityValue(parsedDimension, context.valueToStylinghook, propToMatch);
806
- }
807
- const start = positionInfo.start.offset;
808
- const end = positionInfo.end.offset;
809
- if (closestHooks.length === 1) {
810
- return {
811
- start,
812
- end,
813
- replacement: `var(${closestHooks[0]}, ${rawValue})`,
814
- displayValue: closestHooks[0],
815
- hasHook: true,
816
- isNumeric: true
817
- };
818
- } else if (closestHooks.length > 1) {
819
- return {
820
- start,
821
- end,
822
- replacement: rawValue,
823
- displayValue: formatSuggestionHooks(closestHooks),
824
- hasHook: true,
825
- isNumeric: true
826
- };
827
- } else {
828
- return {
829
- start,
830
- end,
831
- replacement: rawValue,
832
- displayValue: rawValue,
833
- hasHook: false,
834
- isNumeric: true
835
- };
836
- }
837
- }
838
-
839
- // src/rules/v9/no-hardcoded-values/handlers/fontHandler.ts
840
- var handleFontDeclaration = (node, context) => {
841
- const cssProperty = node.property.toLowerCase();
842
- const valueText = context.sourceCode.getText(node.value);
843
- const replacements = [];
844
- forEachFontValue(valueText, (fontValue, positionInfo) => {
845
- if (fontValue && isValidFontValue(fontValue, cssProperty)) {
846
- const replacement = createFontReplacement(fontValue, cssProperty, context, positionInfo);
847
- if (replacement) {
848
- replacements.push(replacement);
849
- }
850
- }
851
- });
852
- handleShorthandAutoFix(node, context, valueText, replacements);
853
- };
854
- function isValidFontValue(fontValue, cssProperty) {
855
- if (cssProperty === "font-size") {
856
- return !!fontValue.unit;
857
- } else if (cssProperty === "font-weight") {
858
- return !fontValue.unit && isKnownFontWeight(fontValue.number);
859
- } else if (cssProperty === "font") {
860
- if (!fontValue.unit && isKnownFontWeight(fontValue.number)) {
861
- return true;
862
- } else if (fontValue.unit) {
863
- return true;
864
- } else {
865
- return false;
866
- }
867
- }
868
- return false;
869
- }
870
- function createFontReplacement(fontValue, cssProperty, context, positionInfo) {
871
- if (!positionInfo?.start) {
872
- return null;
873
- }
874
- const rawValue = fontValue.unit ? `${fontValue.number}${fontValue.unit}` : fontValue.number.toString();
875
- const propToMatch = !fontValue.unit && isKnownFontWeight(fontValue.number) ? "font-weight" : "font-size";
876
- const customHook = getCustomMapping(propToMatch, rawValue, context.options?.customMapping);
877
- let closestHooks = [];
878
- if (customHook) {
879
- closestHooks = [customHook];
880
- } else {
881
- closestHooks = getStylingHooksForDensityValue(fontValue, context.valueToStylinghook, propToMatch);
882
- }
883
- const start = positionInfo.start.offset;
884
- const end = positionInfo.end.offset;
885
- if (closestHooks.length === 1) {
886
- return {
887
- start,
888
- end,
889
- replacement: `var(${closestHooks[0]}, ${rawValue})`,
890
- displayValue: closestHooks[0],
891
- hasHook: true,
892
- isNumeric: true
893
- };
894
- } else if (closestHooks.length > 1) {
895
- return {
896
- start,
897
- end,
898
- replacement: rawValue,
899
- displayValue: formatSuggestionHooks(closestHooks),
900
- hasHook: true,
901
- isNumeric: true
902
- };
903
- } else {
904
- return {
905
- start,
906
- end,
907
- replacement: rawValue,
908
- displayValue: rawValue,
909
- hasHook: false,
910
- isNumeric: true
911
- };
912
- }
913
- }
914
-
915
- // src/utils/boxShadowValueParser.ts
916
- var import_css_tree3 = require("@eslint/css-tree");
917
- function isColorValue(node) {
918
- if (!node) return false;
919
- switch (node.type) {
920
- case "Hash":
921
- return true;
922
- // #hex colors
923
- case "Identifier":
924
- return isValidColor(node.name);
925
- case "Function":
926
- return isCssColorFunction(node.name.toLowerCase());
927
- default:
928
- return false;
929
- }
930
- }
931
- function isLengthValue(node) {
932
- if (!node) return false;
933
- switch (node.type) {
934
- case "Dimension":
935
- const dimensionStr = `${node.value}${node.unit}`;
936
- return parseUnitValue(dimensionStr) !== null;
937
- case "Number":
938
- return Number(node.value) === 0;
939
- default:
940
- return false;
941
- }
942
- }
943
- function isInsetKeyword(node) {
944
- return node?.type === "Identifier" && node.name.toLowerCase() === "inset";
945
- }
946
- function extractShadowParts(valueText) {
947
- const shadows = [];
948
- let currentShadow = {
949
- lengthParts: [],
950
- colorParts: [],
951
- inset: false
952
- };
953
- try {
954
- const ast = (0, import_css_tree3.parse)(valueText, { context: "value" });
955
- (0, import_css_tree3.walk)(ast, {
956
- enter(node) {
957
- if (node.type === "Function") {
958
- return this.skip;
959
- }
960
- if (isInsetKeyword(node)) {
961
- currentShadow.inset = true;
962
- } else if (isLengthValue(node)) {
963
- currentShadow.lengthParts.push((0, import_css_tree3.generate)(node));
964
- } else if (isColorValue(node)) {
965
- currentShadow.colorParts.push((0, import_css_tree3.generate)(node));
966
- }
967
- }
968
- });
969
- if (currentShadow.lengthParts.length > 0 || currentShadow.colorParts.length > 0 || currentShadow.inset) {
970
- shadows.push(currentShadow);
971
- }
972
- } catch (error) {
973
- return [];
974
- }
975
- return shadows;
976
- }
977
- function parseBoxShadowValue(value) {
978
- const shadowStrings = value.split(",").map((s) => s.trim());
979
- const allShadows = [];
980
- for (const shadowString of shadowStrings) {
981
- const shadows = extractShadowParts(shadowString);
982
- const parsedShadows = shadows.map((shadow) => {
983
- const shadowValue = {};
984
- const lengthProps = ["offsetX", "offsetY", "blurRadius", "spreadRadius"];
985
- lengthProps.forEach((prop, index) => {
986
- if (shadow.lengthParts.length > index) {
987
- shadowValue[prop] = shadow.lengthParts[index];
988
- }
989
- });
990
- if (shadow.colorParts.length > 0) {
991
- shadowValue.color = shadow.colorParts[0];
992
- }
993
- if (shadow.inset) {
994
- shadowValue.inset = true;
995
- }
996
- return shadowValue;
997
- });
998
- allShadows.push(...parsedShadows);
999
- }
1000
- return allShadows;
1001
- }
1002
- function normalizeLengthValue(value) {
1003
- if (!value) return "0px";
1004
- if (value === "0") return "0px";
1005
- return value;
1006
- }
1007
- function isBoxShadowMatch(parsedCssValue, parsedValueHook) {
1008
- if (parsedCssValue.length !== parsedValueHook.length) {
1009
- return false;
1010
- }
1011
- for (let i = 0; i < parsedCssValue.length; i++) {
1012
- const cssShadow = parsedCssValue[i];
1013
- const hookShadow = parsedValueHook[i];
1014
- if (cssShadow.color !== hookShadow.color || cssShadow.inset !== hookShadow.inset) {
1015
- return false;
1016
- }
1017
- const lengthProps = ["offsetX", "offsetY", "blurRadius", "spreadRadius"];
1018
- for (const prop of lengthProps) {
1019
- if (normalizeLengthValue(cssShadow[prop]) !== normalizeLengthValue(hookShadow[prop])) {
1020
- return false;
1021
- }
1022
- }
1023
- }
1024
- return true;
1025
- }
1026
-
1027
- // src/rules/v9/no-hardcoded-values/handlers/boxShadowHandler.ts
1028
- function toBoxShadowValue(cssValue) {
1029
- const parsedCssValue = parseBoxShadowValue(cssValue).filter((shadow) => Object.keys(shadow).length > 0);
1030
- if (parsedCssValue.length === 0) {
1031
- return null;
1032
- }
1033
- return parsedCssValue;
1034
- }
1035
- function shadowValueToHookEntries(supportedStylinghooks) {
1036
- return Object.entries(supportedStylinghooks).filter(([key, value]) => {
1037
- return value.some((hook) => hook.properties.includes("box-shadow"));
1038
- }).map(([key, value]) => {
1039
- return [key, value.map((hook) => hook.name)];
1040
- });
1041
- }
1042
- function reportBoxShadowViolation(node, context, valueText, hooks) {
1043
- const positionInfo = {
1044
- start: { offset: 0, line: 1, column: 1 },
1045
- end: { offset: valueText.length, line: 1, column: valueText.length + 1 }
1046
- };
1047
- const replacement = createBoxShadowReplacement(
1048
- valueText,
1049
- hooks,
1050
- context,
1051
- positionInfo
1052
- );
1053
- if (replacement) {
1054
- const replacements = [replacement];
1055
- handleShorthandAutoFix(node, context, valueText, replacements);
1056
- }
1057
- }
1058
- var handleBoxShadowDeclaration = (node, context) => {
1059
- const cssProperty = node.property.toLowerCase();
1060
- const valueText = context.sourceCode.getText(node.value);
1061
- const customHook = getCustomMapping(cssProperty, valueText, context.options?.customMapping);
1062
- if (customHook) {
1063
- reportBoxShadowViolation(node, context, valueText, [customHook]);
1064
- return;
1065
- }
1066
- const shadowHooks = shadowValueToHookEntries(context.valueToStylinghook);
1067
- const parsedCssValue = toBoxShadowValue(valueText);
1068
- if (!parsedCssValue) {
1069
- return;
1070
- }
1071
- for (const [shadow, closestHooks] of shadowHooks) {
1072
- const parsedValueHook = toBoxShadowValue(shadow);
1073
- if (parsedValueHook && isBoxShadowMatch(parsedCssValue, parsedValueHook)) {
1074
- if (closestHooks.length > 0) {
1075
- reportBoxShadowViolation(node, context, valueText, closestHooks);
1076
- }
1077
- return;
1078
- }
1079
- }
1080
- };
1081
- function createBoxShadowReplacement(originalValue, hooks, context, positionInfo) {
1082
- if (!positionInfo?.start) {
1083
- return null;
1084
- }
1085
- const start = positionInfo.start.offset;
1086
- const end = positionInfo.end.offset;
1087
- if (hooks.length === 1) {
1088
- return {
1089
- start,
1090
- end,
1091
- replacement: `var(${hooks[0]}, ${originalValue})`,
1092
- displayValue: hooks[0],
1093
- hasHook: true
1094
- };
1095
- } else {
1096
- return {
1097
- start,
1098
- end,
1099
- replacement: originalValue,
1100
- displayValue: formatSuggestionHooks(hooks),
1101
- hasHook: true
1102
- };
1103
- }
1104
- }
1105
-
1106
- // src/utils/rule-utils.ts
1107
- function isRuleEnabled(context, ruleName2) {
1108
- try {
1109
- const rules = context.settings?.sldsRules || {};
1110
- if (ruleName2 in rules) {
1111
- const ruleConfig2 = rules[ruleName2];
1112
- if (Array.isArray(ruleConfig2)) {
1113
- return ruleConfig2[0] === true;
1114
- } else if (ruleConfig2 !== void 0 && ruleConfig2 !== null) {
1115
- return true;
1116
- } else if (ruleConfig2 === false) {
1117
- return false;
1118
- }
1119
- }
1120
- } catch (error) {
1121
- return false;
1122
- }
1123
- }
1124
-
1125
- // src/rules/v9/no-hardcoded-values/ruleOptionsSchema.ts
1126
- var ruleOptionsSchema = [
1127
- {
1128
- type: "object",
1129
- properties: {
1130
- reportNumericValue: {
1131
- type: "string",
1132
- enum: ["never", "always", "hasReplacement"],
1133
- default: "always"
1134
- },
1135
- customMapping: {
1136
- type: "object",
1137
- additionalProperties: {
1138
- type: "object",
1139
- properties: {
1140
- properties: {
1141
- type: "array",
1142
- items: { type: "string" }
1143
- },
1144
- values: {
1145
- type: "array",
1146
- items: { type: "string" }
1147
- }
1148
- },
1149
- required: ["properties", "values"]
1150
- }
1151
- },
1152
- preferPaletteHook: {
1153
- type: "boolean",
1154
- default: false
1155
- }
1156
- },
1157
- additionalProperties: false
1158
- }
1159
- ];
1160
-
1161
- // src/rules/v9/no-hardcoded-values/noHardcodedValueRule.ts
1162
- function defineNoHardcodedValueRule(config) {
1163
- const { ruleConfig: ruleConfig2, ruleName: ruleName2 } = config;
1164
- const { type: type2, description: description2, url: url2, messages: messages2 } = ruleConfig2;
1165
- return {
1166
- meta: {
1167
- type: type2,
1168
- docs: {
1169
- description: description2,
1170
- recommended: true,
1171
- url: url2
1172
- },
1173
- fixable: "code",
1174
- messages: messages2,
1175
- schema: ruleOptionsSchema
1176
- },
1177
- create(context) {
1178
- if (ruleName2 === "no-hardcoded-values-slds1" && isRuleEnabled(context, "@salesforce-ux/slds/no-hardcoded-values-slds2")) {
1179
- return {};
1180
- }
1181
- const options = context.options[0] || {};
1182
- const ruleOptions = {
1183
- reportNumericValue: options.reportNumericValue || "always",
1184
- customMapping: options.customMapping || {},
1185
- preferPaletteHook: options.preferPaletteHook || false
1186
- };
1187
- const handlerContext = {
1188
- valueToStylinghook: config.valueToStylinghook,
1189
- context,
1190
- sourceCode: context.sourceCode,
1191
- options: ruleOptions
1192
- };
1193
- const colorOnlySelector = toSelector(colorProperties);
1194
- const densityOnlySelector = toSelector(densificationProperties);
1195
- const fontDensitySelector = toSelector(fontProperties);
1196
- const overlappingProperties = colorProperties.filter((colorProp) => {
1197
- return densificationProperties.some((densityProp) => {
1198
- if (densityProp === colorProp) {
1199
- return true;
1200
- }
1201
- if (densityProp.includes("*")) {
1202
- const regexPattern = new RegExp("^" + densityProp.replace(/\*/g, ".*") + "$");
1203
- return regexPattern.test(colorProp);
1204
- }
1205
- return false;
1206
- });
1207
- });
1208
- const overlappingSet = new Set(overlappingProperties);
1209
- const colorOnlyProps = colorProperties.filter((prop) => !overlappingSet.has(prop));
1210
- const densityOnlyProps = densificationProperties.filter((prop) => !overlappingSet.has(prop));
1211
- const visitors = {};
1212
- if (colorOnlyProps.length > 0) {
1213
- const colorOnlySelector2 = toSelector(colorOnlyProps);
1214
- visitors[colorOnlySelector2] = (node) => {
1215
- handleColorDeclaration(node, handlerContext);
1216
- };
1217
- }
1218
- if (densityOnlyProps.length > 0) {
1219
- const densityOnlySelector2 = toSelector(densityOnlyProps);
1220
- visitors[densityOnlySelector2] = (node) => {
1221
- handleDensityDeclaration(node, handlerContext);
1222
- };
1223
- }
1224
- visitors[fontDensitySelector] = (node) => {
1225
- handleFontDeclaration(node, handlerContext);
1226
- };
1227
- visitors['Declaration[property="box-shadow"]'] = (node) => {
1228
- handleBoxShadowDeclaration(node, handlerContext);
1229
- };
1230
- if (overlappingProperties.length > 0) {
1231
- const overlappingSelector = toSelector(overlappingProperties);
1232
- visitors[overlappingSelector] = (node) => {
1233
- handleColorDeclaration(node, handlerContext);
1234
- handleDensityDeclaration(node, handlerContext);
1235
- };
1236
- }
1237
- return visitors;
1238
- }
1239
- };
1240
- }
1241
-
1242
- // src/rules/v9/no-hardcoded-values/no-hardcoded-values-slds2.ts
36
+ var import_rule_messages = __toESM(require("../../../config/rule-messages"));
37
+ var import_noHardcodedValueRule = require("./noHardcodedValueRule");
1243
38
  var ruleName = "no-hardcoded-values-slds2";
1244
39
  var ruleConfig = import_rule_messages.default[ruleName];
1245
40
  var { type, description, url, messages } = ruleConfig;
1246
41
  var valueToStylinghook = import_next.default.valueToStylingHooksCosmos;
1247
- var no_hardcoded_values_slds2_default = defineNoHardcodedValueRule({
42
+ var no_hardcoded_values_slds2_default = (0, import_noHardcodedValueRule.defineNoHardcodedValueRule)({
1248
43
  ruleConfig,
1249
44
  valueToStylinghook,
1250
45
  ruleName