@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/lwc-token-to-slds-hook.ts
190
30
  var lwc_token_to_slds_hook_exports = {};
191
31
  __export(lwc_token_to_slds_hook_exports, {
@@ -193,106 +33,8 @@ __export(lwc_token_to_slds_hook_exports, {
193
33
  });
194
34
  module.exports = __toCommonJS(lwc_token_to_slds_hook_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/hardcoded-shared-utils.ts
199
- var import_css_tree2 = require("@eslint/css-tree");
200
-
201
- // src/utils/color-lib-utils.ts
202
- var import_chroma_js = __toESM(require("chroma-js"));
203
- var import_css_tree = require("@eslint/css-tree");
204
-
205
- // src/utils/css-functions.ts
206
- var CSS_FUNCTIONS = [
207
- "attr",
208
- "calc",
209
- "color-mix",
210
- "conic-gradient",
211
- "counter",
212
- "cubic-bezier",
213
- "linear-gradient",
214
- "max",
215
- "min",
216
- "radial-gradient",
217
- "repeating-conic-gradient",
218
- "repeating-linear-gradient",
219
- "repeating-radial-gradient",
220
- "var"
221
- ];
222
- var CSS_MATH_FUNCTIONS = ["calc", "min", "max"];
223
- var cssFunctionsRegex = new RegExp(`(?:${CSS_FUNCTIONS.join("|")})`);
224
- var cssFunctionsExactRegex = new RegExp(`^(?:${CSS_FUNCTIONS.join("|")})$`);
225
- var cssMathFunctionsRegex = new RegExp(`^(?:${CSS_MATH_FUNCTIONS.join("|")})$`);
226
-
227
- // src/utils/hardcoded-shared-utils.ts
228
- function forEachValue(valueText, extractValue, shouldSkipNode, callback) {
229
- if (!valueText || typeof valueText !== "string") {
230
- return;
231
- }
232
- try {
233
- const ast = (0, import_css_tree2.parse)(valueText, { context: "value", positions: true });
234
- (0, import_css_tree2.walk)(ast, {
235
- enter(node) {
236
- if (shouldSkipNode(node)) {
237
- return this.skip;
238
- }
239
- const value = extractValue(node);
240
- if (value !== null) {
241
- const positionInfo = {
242
- start: node.loc?.start,
243
- end: node.loc?.end
244
- };
245
- callback(value, positionInfo);
246
- }
247
- }
248
- });
249
- } catch (error) {
250
- return;
251
- }
252
- }
253
-
254
- // src/utils/css-utils.ts
255
- function extractCssVariable(node, filter) {
256
- if (!node || node.type !== "Function" || node.name !== "var") {
257
- return null;
258
- }
259
- if (!node.children) {
260
- return null;
261
- }
262
- const childrenArray = Array.from(node.children);
263
- if (childrenArray.length === 0) {
264
- return null;
265
- }
266
- const firstChild = childrenArray[0];
267
- if (!firstChild || firstChild.type !== "Identifier") {
268
- return null;
269
- }
270
- const variableName = firstChild.name;
271
- if (!variableName) {
272
- return null;
273
- }
274
- return filter(variableName, childrenArray);
275
- }
276
- function forEachLwcVariable(valueText, callback) {
277
- const extractor = (node) => extractCssVariable(node, (variableName, childrenArray) => {
278
- if (!variableName.startsWith("--lwc-")) {
279
- return null;
280
- }
281
- const hasFallback = childrenArray.some(
282
- (child) => child.type === "Operator" && child.value === ","
283
- );
284
- return { name: variableName, hasFallback };
285
- });
286
- forEachValue(valueText, extractor, () => false, callback);
287
- }
288
- function formatSuggestionHooks(hooks) {
289
- if (hooks.length === 1) {
290
- return `${hooks[0]}`;
291
- }
292
- return "\n" + hooks.map((hook, index) => `${index + 1}. ${hook}`).join("\n");
293
- }
294
-
295
- // src/rules/v9/lwc-token-to-slds-hook.ts
36
+ var import_rule_messages = __toESM(require("../../config/rule-messages"));
37
+ var import_css_utils = require("../../utils/css-utils");
296
38
  var ruleConfig = import_rule_messages.default["lwc-token-to-slds-hook"];
297
39
  var { type, description, url, messages } = ruleConfig;
298
40
  var lwcToSlds = import_next.default.lwcToSlds;
@@ -327,7 +69,7 @@ function getReportMessage(cssVar, replacementCategory, recommendation) {
327
69
  } else if (replacementCategory === "array" /* ARRAY */) {
328
70
  return {
329
71
  messageId: "errorWithStyleHooks",
330
- data: { oldValue: cssVar, newValue: formatSuggestionHooks(recommendation) }
72
+ data: { oldValue: cssVar, newValue: (0, import_css_utils.formatSuggestionHooks)(recommendation) }
331
73
  };
332
74
  } else if (replacementCategory === "slds_token" /* SLDS_TOKEN */) {
333
75
  return {
@@ -380,7 +122,7 @@ var lwc_token_to_slds_hook_default = {
380
122
  }
381
123
  const valueText = context.sourceCode.getText(node.value);
382
124
  if (valueText) {
383
- forEachLwcVariable(valueText, (variableInfo, positionInfo) => {
125
+ (0, import_css_utils.forEachLwcVariable)(valueText, (variableInfo, positionInfo) => {
384
126
  const { name: lwcToken, hasFallback } = variableInfo;
385
127
  if (shouldIgnoreDetection(lwcToken)) {
386
128
  return;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["yaml-file:rule-messages.yml", "../../../src/rules/v9/lwc-token-to-slds-hook.ts", "../../../src/utils/hardcoded-shared-utils.ts", "../../../src/utils/color-lib-utils.ts", "../../../src/utils/css-functions.ts", "../../../src/utils/css-utils.ts"],
4
- "sourcesContent": ["module.exports = {\n \"no-slds-class-overrides\": {\n \"description\": \"Create new custom CSS classes instead of overriding SLDS selectors\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-slds-class-overrides\",\n \"type\": \"problem\",\n \"messages\": {\n \"sldsClassOverride\": \"Overriding .{{className}} isn't supported. To differentiate SLDS and custom classes, create a CSS class in your namespace. Examples: myapp-input, myapp-button.\"\n }\n },\n \"no-deprecated-slds-classes\": {\n \"description\": \"Please replace the deprecated classes with a modern equivalent\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-deprecated-slds-classes\",\n \"type\": \"problem\",\n \"messages\": {\n \"deprecatedClass\": \"The class {{className}} is deprecated and not available in SLDS2. Please update to a supported class.\"\n }\n },\n \"no-deprecated-tokens-slds1\": {\n \"description\": \"Update outdated design tokens to SLDS 2 styling hooks with similar values. For more information, see Styling Hooks on lightningdesignsystem.com.\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-deprecated-tokens-slds1\",\n \"type\": \"problem\",\n \"messages\": {\n \"deprecatedToken\": \"Consider removing {{oldValue}} or replacing it with {{newValue}}. Set the fallback to {{oldValue}}. For more info, see Styling Hooks on lightningdesignsystem.com.\",\n \"noReplacement\": \"Update outdated design tokens to SLDS 2 styling hooks with similar values. For more information, see Styling Hooks on lightningdesignsystem.com.\"\n }\n },\n \"enforce-sds-to-slds-hooks\": {\n \"description\": \"Convert your existing --sds styling hooks to --slds styling hooks. See lightningdesignsystem.com for more info.\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#enforce-sds-to-slds-hooks\",\n \"type\": \"problem\",\n \"messages\": {\n \"replaceSdsWithSlds\": \"Replace {{oldValue}} with {{suggestedMatch}} styling hook.\"\n }\n },\n \"enforce-bem-usage\": {\n \"description\": \"Replace BEM double-dash syntax in class names with single underscore syntax\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#enforce-bem-usage\",\n \"type\": \"problem\",\n \"messages\": {\n \"bemDoubleDash\": \"{{actual}} has been retired. Update it to the new name {{newValue}}.\",\n \"fixBemNaming\": \"Update to correct BEM naming convention\"\n }\n },\n \"modal-close-button-issue\": {\n \"description\": \"Update component attributes or CSS classes for the modal close button to comply with the modal component blueprint\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#modal-close-button-issue\",\n \"type\": \"problem\",\n \"messages\": {\n \"modalCloseButtonIssue\": \"Update component attributes or CSS classes for the modal close button to comply with the modal component blueprint.\",\n \"removeClass\": \"Remove the slds-button_icon-inverse class from the modal close button in components that use the SLDS modal blueprint.\",\n \"changeVariant\": \"Change the variant attribute value from bare-inverse to bare in <lightning-button-icon> or <lightning-icon>.\",\n \"removeVariant\": \"Remove the variant attribute from the <lightning-icon> component inside the <button> element.\",\n \"ensureButtonClasses\": \"Add or move slds-button and slds-button_icon to the class attribute of the <button> element or <lightning-button-icon> component.\",\n \"ensureSizeAttribute\": \"To size icons properly, set the size attribute \u200Cto large in the <lightning-icon> and <lightning-button-icon> components.\"\n }\n },\n \"no-deprecated-classes-slds2\": {\n \"description\": \"Replace classes that aren't available with SLDS 2 classes\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-deprecated-classes-slds2\",\n \"type\": \"problem\",\n \"messages\": {\n \"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.\",\n \"updateToModernClass\": \"Replace deprecated class with modern equivalent\",\n \"checkDocumentation\": \"See lightningdesignsystem.com for SLDS 2 class alternatives\"\n }\n },\n \"lwc-token-to-slds-hook\": {\n \"description\": \"Replace the deprecated --lwc tokens with the latest --slds tokens. See lightningdesignsystem.com for more info.\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#lwc-token-to-slds-hook\",\n \"type\": \"problem\",\n \"messages\": {\n \"errorWithReplacement\": \"The '{{oldValue}}' design token is deprecated. Replace it with '{{newValue}}'. For more info, see Global Styling Hooks on lightningdesignsystem.com.\",\n \"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.\",\n \"errorWithNoRecommendation\": \"The '{{oldValue}}' design token is deprecated. For more info, see the New Global Styling Hook Guidance on lightningdesignsystem.com.\"\n }\n },\n \"no-sldshook-fallback-for-lwctoken\": {\n \"description\": \"Avoid using --slds styling hooks as fallback values for --lwc tokens.\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-sldshook-fallback-for-lwctoken\",\n \"type\": \"problem\",\n \"messages\": {\n \"unsupportedFallback\": \"Remove the {{sldsToken}} styling hook that is used as a fallback value for {{lwcToken}}.\"\n }\n },\n \"no-unsupported-hooks-slds2\": {\n \"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.\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-unsupported-hooks-slds2\",\n \"type\": \"problem\",\n \"messages\": {\n \"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.\"\n }\n },\n \"no-slds-var-without-fallback\": {\n \"description\": \"Add fallback values to SLDS styling hooks. The fallback values are used in Salesforce environments where styling hooks are unavailable.\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-slds-var-without-fallback\",\n \"type\": \"problem\",\n \"messages\": {\n \"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.\"\n }\n },\n \"no-slds-namespace-for-custom-hooks\": {\n \"description\": \"To differentiate custom styling hooks from SLDS styling hooks, create custom styling hooks in your namespace.\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-slds-namespace-for-custom-hooks\",\n \"type\": \"problem\",\n \"messages\": {\n \"customHookNamespace\": \"Using the --slds namespace for {{token}} isn't supported. Create the custom styling hook in your namespace. Example: --myapp-{{tokenWithoutNamespace}}\"\n }\n },\n \"no-slds-private-var\": {\n \"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.\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-slds-private-var\",\n \"type\": \"problem\",\n \"messages\": {\n \"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.\"\n }\n },\n \"enforce-component-hook-naming-convention\": {\n \"description\": \"Replace component styling hooks that use a deprecated naming convention.\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#enforce-component-hook-naming-convention\",\n \"type\": \"problem\",\n \"messages\": {\n \"replace\": \"Replace the deprecated {{oldValue}} component styling hook with {{suggestedMatch}}.\"\n }\n },\n \"no-hardcoded-values-slds1\": {\n \"description\": \"Replace static values with SLDS 1 design tokens. For more information, look up design tokens on lightningdesignsystem.com.\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-hardcoded-value\",\n \"type\": \"suggestion\",\n \"messages\": {\n \"hardcodedValue\": \"Replace the {{oldValue}} static value with an SLDS 1 styling hook: {{newValue}}.\",\n \"noReplacement\": \"There's no replacement styling hook for the {{oldValue}} static value. Remove the static value.\"\n }\n },\n \"no-hardcoded-values-slds2\": {\n \"description\": \"Replace static values with SLDS 2 styling hooks. For more information, look up design tokens on lightningdesignsystem.com.\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-hardcoded-values-slds2\",\n \"type\": \"suggestion\",\n \"messages\": {\n \"hardcodedValue\": \"Consider replacing the {{oldValue}} static value with an SLDS 2 styling hook that has a similar value: {{newValue}}.\",\n \"noReplacement\": \"There's no replacement styling hook for the {{oldValue}} static value. Remove the static value.\"\n }\n },\n \"reduce-annotations\": {\n \"description\": \"Remove your annotations and update your code.\",\n \"url\": \"https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#reduce-annotations\",\n \"type\": \"problem\",\n \"messages\": {\n \"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/\"\n }\n }\n};", "import { Rule } from 'eslint';\nimport metadata from '@salesforce-ux/sds-metadata/next';\nimport ruleMessages from '../../config/rule-messages.yml';\nimport { formatSuggestionHooks, forEachLwcVariable, type CssVariableInfo } from '../../utils/css-utils';\nimport type { PositionInfo } from '../../utils/hardcoded-shared-utils';\n\nconst ruleConfig = ruleMessages['lwc-token-to-slds-hook'];\nconst { type, description, url, messages } = ruleConfig;\n\nconst lwcToSlds = metadata.lwcToSlds;\n\n// Replacement category enum to match Stylelint version\nenum ReplacementCategory {\n EMPTY = 'empty',\n SLDS_TOKEN = 'slds_token',\n ARRAY = 'array',\n RAW_VALUE = 'raw_value'\n}\n\nfunction shouldIgnoreDetection(lwcToken: string): boolean {\n // Ignore if entry not found in the list or the token is marked to use further\n return (\n !lwcToken.startsWith('--lwc-') ||\n !(lwcToken in lwcToSlds) ||\n lwcToSlds[lwcToken].continueToUse\n );\n}\n\nfunction categorizeReplacement(recommendation: string | string[]): ReplacementCategory {\n if (!recommendation || recommendation === '--') {\n return ReplacementCategory.EMPTY;\n }\n if (Array.isArray(recommendation)) {\n return ReplacementCategory.ARRAY;\n }\n if (typeof recommendation === 'string' && recommendation.startsWith('--slds-')) {\n return ReplacementCategory.SLDS_TOKEN;\n }\n return ReplacementCategory.RAW_VALUE;\n}\n\nfunction getRecommendation(lwcToken: string) {\n const oldValue = lwcToken;\n const recommendation = lwcToSlds[oldValue]?.replacement || '';\n const replacementCategory = categorizeReplacement(recommendation);\n const hasRecommendation = oldValue in lwcToSlds && replacementCategory !== ReplacementCategory.EMPTY;\n return { hasRecommendation, recommendation, replacementCategory };\n}\n\nfunction getReportMessage(cssVar: string, replacementCategory: ReplacementCategory, recommendation: string | string[]): { messageId: string, data: any } {\n if (!recommendation) {\n // Found a deprecated token but don't have any alternate recommendation then just report user to follow docs\n return {\n messageId: 'errorWithNoRecommendation',\n data: { oldValue: cssVar }\n };\n } else if (replacementCategory === ReplacementCategory.ARRAY) {\n return {\n messageId: 'errorWithStyleHooks',\n data: { oldValue: cssVar, newValue: formatSuggestionHooks(recommendation as string[]) }\n };\n } else if (replacementCategory === ReplacementCategory.SLDS_TOKEN) {\n return {\n messageId: 'errorWithStyleHooks',\n data: { oldValue: cssVar, newValue: recommendation as string }\n };\n } else {\n return {\n messageId: 'errorWithReplacement',\n data: { oldValue: cssVar, newValue: recommendation as string }\n };\n }\n}\n\nexport default {\n meta: {\n type,\n docs: {\n description,\n recommended: true,\n url,\n },\n fixable: 'code',\n messages,\n },\n \n create(context) {\n function reportAndFix(\n node: any,\n suggestedMatch: string | null,\n messageId: string,\n data: any,\n fixRange?: [number, number],\n loc?: any\n ) {\n context.report({\n node,\n loc: loc || node.loc,\n messageId,\n data,\n fix: suggestedMatch && fixRange ? (fixer) => {\n return fixer.replaceTextRange(fixRange, suggestedMatch);\n } : undefined\n });\n }\n\n return {\n // CSS custom property declarations: Check both property name and value\n \"Declaration\"(node) {\n // Check 1: Property name (left-side) for custom properties using --lwc- prefix\n const property = node.property;\n if (property && property.startsWith('--lwc-')) {\n if (!shouldIgnoreDetection(property)) {\n const { hasRecommendation, recommendation, replacementCategory } = getRecommendation(property);\n const { messageId, data } = getReportMessage(property, replacementCategory, recommendation);\n \n // Only provide auto-fix for SLDS token replacements\n const suggestedMatch = (hasRecommendation && replacementCategory === ReplacementCategory.SLDS_TOKEN) \n ? recommendation as string \n : null;\n \n // Calculate fix range for property name\n const propertyStart = node.loc.start.offset;\n const propertyEnd = propertyStart + property.length;\n \n reportAndFix(node, suggestedMatch, messageId, data, [propertyStart, propertyEnd]);\n }\n }\n\n // Check 2: Property value (right-side) - Use AST parsing to detect var(--lwc-*) functions\n // Note: We use forEachLwcVariable instead of Function[name='var'] handler because\n // ESLint treats custom property values (e.g., --custom-prop: var(--lwc-token)) as raw strings\n // rather than parsing them into Function nodes. This AST-based approach handles both cases.\n const valueText = context.sourceCode.getText(node.value);\n if (valueText) {\n forEachLwcVariable(valueText, (variableInfo: CssVariableInfo, positionInfo: PositionInfo) => {\n const { name: lwcToken, hasFallback } = variableInfo;\n \n if (shouldIgnoreDetection(lwcToken)) {\n return;\n }\n\n const { hasRecommendation, recommendation, replacementCategory } = getRecommendation(lwcToken);\n const { messageId, data } = getReportMessage(lwcToken, replacementCategory, recommendation);\n \n let suggestedMatch: string | null = null;\n \n if (hasRecommendation) {\n if (replacementCategory === ReplacementCategory.SLDS_TOKEN) {\n // Extract fallback value from the original var() call if present\n // Use position info to get the full var() call text\n let fallbackValue: string | null = null;\n if (hasFallback && positionInfo.start && positionInfo.end && positionInfo.start.offset !== undefined && positionInfo.end.offset !== undefined) {\n const varCallText = valueText.substring(positionInfo.start.offset, positionInfo.end.offset);\n // Find the comma after the token name and extract everything after it (before the closing paren)\n const commaIndex = varCallText.indexOf(',');\n if (commaIndex !== -1) {\n // Extract from after comma to before closing paren\n fallbackValue = varCallText.substring(commaIndex + 1, varCallText.length - 1).trim();\n }\n }\n \n // Create the replacement in the format: var(--slds-token, var(--lwc-token, fallback))\n // This preserves any existing fallback value\n const originalVarCall = fallbackValue \n ? `var(${lwcToken}, ${fallbackValue})`\n : `var(${lwcToken})`;\n suggestedMatch = `var(${recommendation}, ${originalVarCall})`;\n } else if (replacementCategory === ReplacementCategory.RAW_VALUE) {\n suggestedMatch = recommendation as string;\n }\n }\n\n // Calculate fix range and location using position info from AST parsing\n const valueStartOffset = node.value.loc.start.offset;\n const varStartOffset = valueStartOffset + (positionInfo.start?.offset || 0);\n const varEndOffset = valueStartOffset + (positionInfo.end?.offset || valueText.length);\n \n // Calculate precise location if position info is available\n const preciseLoc = positionInfo.start && positionInfo.end && node.value.loc ? {\n start: {\n line: node.value.loc.start.line + positionInfo.start.line - 1,\n column: node.value.loc.start.column + positionInfo.start.column - 1\n },\n end: {\n line: node.value.loc.start.line + positionInfo.end.line - 1,\n column: node.value.loc.start.column + positionInfo.end.column - 1\n }\n } : node.value.loc;\n \n reportAndFix(node, suggestedMatch, messageId, data, [varStartOffset, varEndOffset], preciseLoc);\n });\n }\n },\n };\n },\n} as Rule.RuleModule;\n", "import { parse, walk } from '@eslint/css-tree';\nimport type { HandlerContext } from '../types';\nimport type { ParsedUnitValue } from './value-utils';\nimport { ALLOWED_UNITS } from './value-utils';\nimport { extractColorValue } from './color-lib-utils';\nimport { isCssFunction } from './css-functions';\n\n/**\n * Common replacement data structure used by both color and density handlers\n */\nexport interface ReplacementInfo {\n start: number;\n end: number;\n replacement: string; // Full CSS var: var(--hook, fallback)\n displayValue: string; // Just the hook: --hook\n hasHook: boolean;\n isNumeric?: boolean; // Whether this is a numeric (dimension) value\n}\n\n/**\n * Position information from CSS tree parsing\n */\nexport interface PositionInfo {\n start?: { offset: number; line: number; column: number };\n end?: { offset: number; line: number; column: number };\n}\n\n/**\n * Generic callback for processing values with position information\n */\nexport type ValueCallback<T> = (value: T, positionInfo?: PositionInfo) => void;\n\n/**\n * Known valid font-weight values\n */\nconst FONT_WEIGHTS = [\n 'normal',\n 'bold', \n 'bolder',\n 'lighter',\n '100',\n '200', \n '300',\n '400',\n '500',\n '600',\n '700',\n '800',\n '900'\n];\n\n/**\n * Check if a value is a known font-weight\n */\nexport function isKnownFontWeight(value: string | number): boolean {\n const stringValue = value.toString();\n return FONT_WEIGHTS.includes(stringValue.toLowerCase());\n}\n\n/**\n * Generic shorthand auto-fix handler\n * Handles the common logic for reconstructing shorthand values with replacements\n */\nexport function handleShorthandAutoFix(\n declarationNode: any,\n context: HandlerContext,\n valueText: string,\n replacements: ReplacementInfo[]\n) {\n if(!replacements || replacements.length === 0){\n return;\n }\n // Sort replacements by position for proper reconstruction\n const sortedReplacements = replacements.sort((a,b)=> b.start-a.start);\n\n // Get rule options\n const reportNumericValue = context.options?.reportNumericValue || 'always';\n\n const fixCallback = (start:number, originalValue:string, replacement:string) => {\n // Reconstruct the entire value with all replacements\n let newValue = valueText;\n\n newValue = newValue.substring(0, start) + replacement + newValue.substring(start+originalValue.length);\n\n if(newValue !== valueText){\n return (fixer:any)=>{\n return fixer.replaceText(declarationNode.value, newValue);\n }\n }\n }\n\n // Report each individual value\n sortedReplacements.forEach(({ start, end, replacement, displayValue, hasHook, isNumeric }) => {\n const originalValue = valueText.substring(start, end);\n \n // Check if we should skip reporting based on reportNumericValue option\n if (isNumeric) {\n if (reportNumericValue === 'never') {\n return; // Skip reporting numeric values\n }\n if (reportNumericValue === 'hasReplacement' && !hasHook) {\n return; // Skip reporting numeric values without replacements\n }\n }\n \n \n const valueColumnStart = declarationNode.value.loc.start.column + start;\n const valueColumnEnd = valueColumnStart + originalValue.length;\n const canAutoFix = originalValue !== replacement;\n \n // Create precise error location for this value\n const { loc: { start: locStart, end: locEnd } } = declarationNode.value;\n const reportNode = {\n ...declarationNode.value,\n loc: {\n ...declarationNode.value.loc,\n start: {\n ...locStart,\n column: valueColumnStart\n },\n end: {\n ...locEnd,\n column: valueColumnEnd\n }\n }\n };\n\n if (hasHook) {\n // Create auto-fix for the entire shorthand value\n const fix = canAutoFix ? fixCallback(start, originalValue, replacement) : undefined;\n\n context.context.report({\n node: reportNode,\n messageId: 'hardcodedValue',\n data: {\n oldValue: originalValue,\n newValue: displayValue\n },\n fix\n });\n } else {\n // No hook available\n context.context.report({\n node: reportNode,\n messageId: 'noReplacement',\n data: {\n oldValue: originalValue\n }\n });\n }\n });\n}\n\n/**\n * Generic CSS tree traversal with position tracking\n * Always provides position information since both handlers need it\n */\nexport function forEachValue<T>(\n valueText: string,\n extractValue: (node: any) => T | null,\n shouldSkipNode: (node: any) => boolean,\n callback: (value: T, positionInfo: PositionInfo) => void\n): void {\n if (!valueText || typeof valueText !== 'string') {\n return;\n }\n\n try {\n const ast = parse(valueText, { context: 'value' as const, positions: true });\n \n walk(ast, {\n enter(node: any) {\n // Skip nodes efficiently using this.skip\n if (shouldSkipNode(node)) {\n return this.skip;\n }\n \n const value = extractValue(node);\n if (value !== null) {\n const positionInfo: PositionInfo = {\n start: node.loc?.start,\n end: node.loc?.end\n };\n callback(value, positionInfo);\n }\n }\n });\n } catch (error) {\n // Silently handle parse errors\n return;\n }\n}\n\n/**\n * Check if color node should be skipped during traversal\n */\nfunction shouldSkipColorNode(node: any): boolean {\n return node.type === 'Function' && isCssFunction(node.name);\n}\n\n/**\n * Check if dimension node should be skipped during traversal\n * Skip all function nodes by default\n */\nfunction shouldSkipDimensionNode(node: any): boolean {\n return node.type === 'Function';\n}\n\n/**\n * Extract dimension value from CSS AST node\n * Returns structured data with number and unit to eliminate regex parsing\n */\nfunction extractDimensionValue(valueNode: any, cssProperty?: string): ParsedUnitValue | null {\n if (!valueNode) return null;\n \n switch (valueNode.type) {\n case 'Dimension':\n // Dimensions: 16px, 1rem -> extract value and unit directly from AST\n const numValue = Number(valueNode.value);\n if (numValue === 0) return null; // Skip zero values\n \n const unit = valueNode.unit.toLowerCase();\n if (!ALLOWED_UNITS.includes(unit)) return null; // Support only allowed units\n \n return {\n number: numValue,\n unit: unit as 'px' | 'rem' | '%' | 'em' | 'ch'\n };\n \n case 'Number':\n // Numbers: 400, 1.5 -> treat as unitless (font-weight, line-height, etc.)\n const numberValue = Number(valueNode.value);\n if (numberValue === 0) return null; // Skip zero values\n \n return {\n number: numberValue,\n unit: null\n };\n \n case 'Percentage':\n // Percentage values: 100%, 50% -> extract value and add % unit\n const percentValue = Number(valueNode.value);\n if (percentValue === 0) return null; // Skip zero values\n \n return {\n number: percentValue,\n unit: '%'\n };\n \n case 'Value':\n // Value wrapper - extract from first child\n return valueNode.children?.[0] ? extractDimensionValue(valueNode.children[0], cssProperty) : null;\n }\n \n return null;\n}\n\n/**\n * Specialized color value traversal\n * Handles color-specific extraction and skipping logic\n */\nexport function forEachColorValue(\n valueText: string,\n callback: (colorValue: string, positionInfo: PositionInfo) => void\n): void {\n forEachValue(valueText, extractColorValue, shouldSkipColorNode, callback);\n}\n\n/**\n * Specialized density value traversal\n * Handles dimension-specific extraction and skipping logic\n */\nexport function forEachDensityValue(\n valueText: string,\n cssProperty: string,\n callback: (parsedDimension: ParsedUnitValue, positionInfo: PositionInfo) => void\n): void {\n forEachValue(\n valueText, \n (node) => extractDimensionValue(node, cssProperty), \n shouldSkipDimensionNode, \n callback\n );\n}\n\n/**\n * Extract font-related values from CSS AST node\n * Handles font-size and font-weight values\n */\nfunction extractFontValue(node: any): ParsedUnitValue | null {\n if (!node) return null;\n \n switch (node.type) {\n case 'Dimension':\n // Font-size: 16px, 1rem, etc.\n const numValue = Number(node.value);\n if (numValue <= 0) return null; // Skip zero/negative values\n \n const unit = node.unit.toLowerCase();\n if (!ALLOWED_UNITS.includes(unit)) return null;\n \n return {\n number: numValue,\n unit: unit as 'px' | 'rem' | '%' | 'em' | 'ch'\n };\n \n case 'Number':\n // Font-weight: 400, 700, etc.\n const numberValue = Number(node.value);\n if (numberValue <= 0) {\n return null; // Skip zero/negative values\n }\n \n // Only accept known font-weight values for unitless numbers\n if (!isKnownFontWeight(numberValue)) {\n return null; // Skip values that aren't valid font-weights\n }\n \n return {\n number: numberValue,\n unit: null\n };\n \n case 'Identifier':\n // Font-weight keywords: normal, bold, etc.\n const namedValue = node.name.toLowerCase();\n \n // Only accept known font-weight keywords\n if (!isKnownFontWeight(namedValue)) {\n return null;\n }\n \n // Convert known keywords to numeric values\n if (namedValue === 'normal') {\n return { number: 400, unit: null };\n }\n \n // For other keywords (bolder, lighter), we can't determine exact numeric value\n // but we know they're valid font-weight values\n return { number: namedValue, unit: null };\n \n case 'Percentage':\n // Percentage values for font-size\n const percentValue = Number(node.value);\n if (percentValue === 0) return null; // Skip zero values\n \n return {\n number: percentValue,\n unit: '%'\n };\n \n case 'Value':\n // Value wrapper - extract from first child\n return node.children?.[0] ? extractFontValue(node.children[0]) : null;\n }\n \n return null;\n}\n\n/**\n * Check if font node should be skipped during traversal\n * Skip all function nodes by default\n */\nfunction shouldSkipFontNode(node: any): boolean {\n return node.type === 'Function';\n}\n\n/**\n * Specialized font value traversal\n * Handles font-specific extraction and skipping logic\n */\nexport function forEachFontValue(\n valueText: string,\n callback: (fontValue: ParsedUnitValue, positionInfo: PositionInfo) => void\n): void {\n forEachValue(valueText, extractFontValue, shouldSkipFontNode, callback);\n}\n", "import { ValueToStylingHooksMapping, ValueToStylingHookEntry } from '@salesforce-ux/sds-metadata/next';\nimport chroma from 'chroma-js';\nimport { generate } from '@eslint/css-tree';\nimport { isCssColorFunction } from './css-functions';\n\n/**\n * Perceptual color difference threshold (Delta E, CIEDE2000 via chroma.deltaE).\n * Lower values are stricter matches. Used to decide which hooks are \"close enough\".\n */\nconst DELTAE_THRESHOLD = 10;\n\n/**\n * Convert any valid CSS color (named, hex, rgb(a), hsl(a), etc.) to hex.\n * Returns null if the value is not a valid color.\n */\nconst convertToHex = (color: string): string | null => {\n try {\n // Try converting the color using chroma-js, which handles both named and hex colors\n return chroma(color).hex();\n } catch (e) {\n // If chroma can't process the color, it's likely invalid\n return null;\n }\n};\n\nconst isHookPropertyMatch = (hook: ValueToStylingHookEntry, cssProperty: string): boolean => {\n return hook.properties.includes(cssProperty) || hook.properties.includes(\"*\");\n}\n\nfunction getOrderByCssProp(cssProperty: string): string[] {\n if(cssProperty === 'color' || cssProperty === 'fill') {\n return [\"surface\", \"theme\", \"feedback\", \"reference\"];\n } else if(cssProperty.match(/background/)){\n return [\"surface\", \"surface-inverse\", \"theme\", \"feedback\", \"reference\"];\n } else if(cssProperty.match(/border/) || cssProperty.match(/outline/) || cssProperty.match(/stroke/)) {\n return [\"borders\", \"borders-inverse\", \"feedback\", \"theme\", \"reference\"];\n }\n return [\"surface\", \"surface-inverse\", \"borders\", \"borders-inverse\", \"theme\", \"feedback\", \"reference\"];\n}\n\n\n/**\n * Given an input color and the metadata mapping of supported colors to hooks,\n * suggest up to 5 styling hook names ordered by:\n * 1) Category priority: semantic -> system -> palette\n * 2) Perceptual distance (Delta E)\n * Also prioritizes exact color matches (distance 0).\n */\nconst findClosestColorHook = (\n color: string,\n supportedColors:ValueToStylingHooksMapping,\n cssProperty: string\n): string[] => {\n const closestHooks: Array<{distance: number, group: string, name: string}> = [];\n Object.entries(supportedColors).forEach(([sldsValue, data]) => {\n if (sldsValue && isValidColor(sldsValue)) {\n const hooks = data as ValueToStylingHookEntry[]; // Get the hooks for the sldsValue\n\n hooks.forEach((hook) => {\n // Exact match shortcut to avoid floating rounding noise\n const distance = (sldsValue.toLowerCase() === color.toLowerCase())\n ? 0\n : chroma.deltaE(sldsValue, color);\n \n // Check if the hook has the same property or universal selector\n if (isHookPropertyMatch(hook, cssProperty) && distance <= DELTAE_THRESHOLD) {\n // Add to same property hooks if within threshold\n closestHooks.push({ distance, group: hook.group, name: hook.name });\n }\n });\n }\n });\n\n const hooksByGroupMap:Record<string, string[]> = closestHooks.sort((a, b) => a.distance - b.distance).reduce((acc, hook) => {\n if (!acc[hook.group]) {\n acc[hook.group] = [];\n }\n acc[hook.group].push(hook.name);\n return acc;\n }, {});\n\n return getOrderByCssProp(cssProperty)\n .map(group => hooksByGroupMap[group]||[])\n .flat().slice(0, 5);\n};\n\n/**\n * Check if a value is any valid CSS color string (delegates to chroma-js).\n */\nconst isValidColor = (val:string):boolean => chroma.valid(val);\n\n/**\n * Extract a color string from a CSS AST node produced by @eslint/css-tree.\n * Supports Hash (#rrggbb), Identifier (named colors), and color Function nodes.\n * Returns null if the extracted value is not a valid color.\n */\nconst extractColorValue = (node: any): string | null => {\n let colorValue: string | null = null;\n \n switch (node.type) {\n case 'Hash':\n colorValue = `#${node.value}`;\n break;\n case 'Identifier':\n colorValue = node.name;\n break;\n case 'Function':\n // Only extract color functions\n if (isCssColorFunction(node.name)) {\n colorValue = generate(node);\n }\n break;\n }\n \n return colorValue && isValidColor(colorValue) ? colorValue : null;\n};\n\nexport { findClosestColorHook, convertToHex, isValidColor, extractColorValue };\n", "//stylelint-sds/packages/stylelint-plugin-slds/src/utils/css-functions.ts\n/**\n * Complete list of CSS functions that should be preserved/recognized\n */\nconst CSS_FUNCTIONS = [\n 'attr',\n 'calc',\n 'color-mix',\n 'conic-gradient',\n 'counter',\n 'cubic-bezier',\n 'linear-gradient',\n 'max',\n 'min',\n 'radial-gradient',\n 'repeating-conic-gradient',\n 'repeating-linear-gradient',\n 'repeating-radial-gradient',\n 'var'\n ];\n \n \n const CSS_MATH_FUNCTIONS = ['calc', 'min', 'max'];\n \n \n const RGB_COLOR_FUNCTIONS = ['rgb', 'rgba', 'hsl', 'hsla'];\n \n /**\n * Regex for matching any CSS function (for general detection)\n * Matches function names within other text\n */\n const cssFunctionsRegex = new RegExp(`(?:${CSS_FUNCTIONS.join('|')})`);\n \n \n const cssFunctionsExactRegex = new RegExp(`^(?:${CSS_FUNCTIONS.join('|')})$`);\n \n \n const cssMathFunctionsRegex = new RegExp(`^(?:${CSS_MATH_FUNCTIONS.join('|')})$`);\n \n export function containsCssFunction(value: string): boolean {\n return cssFunctionsRegex.test(value);\n }\n \n /**\n * Check if a value is exactly a CSS function name\n */\n export function isCssFunction(value: string): boolean {\n return cssFunctionsExactRegex.test(value);\n }\n \n export function isCssMathFunction(value: string): boolean {\n return cssMathFunctionsRegex.test(value);\n }\n \n export function isCssColorFunction(value: string): boolean {\n return RGB_COLOR_FUNCTIONS.includes(value);\n }", "import { \n forEachValue, \n type PositionInfo \n} from './hardcoded-shared-utils';\n\n/**\n * Check if a CSS property should be targeted for linting based on prefixes or explicit targets\n * @param property - The CSS property name to check\n * @param propertyTargets - Array of specific properties to target (empty means target all)\n * @returns true if the property should be targeted\n */\nexport function isTargetProperty(property: string, propertyTargets: string[] = []): boolean {\n if (typeof property !== 'string') return false;\n return property.startsWith('--sds-')\n || property.startsWith('--slds-')\n || property.startsWith('--lwc-')\n || propertyTargets.length === 0\n || propertyTargets.includes(property);\n}\n\n/**\n * CSS Variable information for SLDS variable detection\n */\nexport interface CssVariableInfo {\n name: string; // Variable name: --slds-g-color-surface-1\n hasFallback: boolean; // Whether var() already has a fallback\n}\n\n/**\n * Generic CSS variable extractor that can be customized for different use cases\n * @param node - AST node to extract from\n * @param filter - Function to validate and extract variable information\n * @returns Extracted variable info or null\n */\nfunction extractCssVariable<T>(\n node: any,\n filter: (variableName: string, childrenArray: any[]) => T | null\n): T | null {\n if (!node || node.type !== 'Function' || node.name !== 'var') {\n return null;\n }\n\n if (!node.children) {\n return null;\n }\n\n // Convert children to array and get the first child (variable name)\n const childrenArray = Array.from(node.children);\n if (childrenArray.length === 0) {\n return null;\n }\n \n const firstChild = childrenArray[0] as any;\n if (!firstChild || firstChild.type !== 'Identifier') {\n return null;\n }\n\n const variableName = firstChild.name;\n if (!variableName) {\n return null;\n }\n\n return filter(variableName, childrenArray);\n}\n\n/**\n * Specialized CSS variable traversal for SLDS variables\n * Finds var(--slds-*) functions and reports their fallback status\n */\nexport function forEachSldsVariable(\n valueText: string,\n callback: (variableInfo: CssVariableInfo, positionInfo: PositionInfo) => void\n): void {\n const extractor = (node: any) => extractCssVariable(node, (variableName, childrenArray) => {\n if (!variableName.startsWith('--slds-')) {\n return null;\n }\n\n // Check if there's a fallback (comma separator)\n const hasFallback = childrenArray.some((child: any) => \n child.type === 'Operator' && child.value === ','\n );\n\n return { name: variableName, hasFallback };\n });\n\n forEachValue(valueText, extractor, () => false, callback);\n}\n\n/**\n * Specialized CSS variable traversal for SLDS/SDS namespace detection\n * Finds var(--slds-*) or var(--sds-*) functions in CSS values\n * Note: hasFallback is set to false as it's unused for namespace validation\n */\nexport function forEachNamespacedVariable(\n valueText: string,\n callback: (variableInfo: CssVariableInfo, positionInfo: PositionInfo) => void\n): void {\n const extractor = (node: any) => extractCssVariable(node, (variableName) => {\n // Check for SLDS or SDS namespace\n if (variableName.startsWith('--slds-') || variableName.startsWith('--sds-')) {\n return { name: variableName, hasFallback: false }; // hasFallback unused, but required by interface\n }\n return null;\n });\n\n forEachValue(valueText, extractor, () => false, callback);\n}\n\n/**\n * Specialized CSS variable traversal for LWC variables\n * Finds var(--lwc-*) functions in CSS values and reports their fallback status\n */\nexport function forEachLwcVariable(\n valueText: string,\n callback: (variableInfo: CssVariableInfo, positionInfo: PositionInfo) => void\n): void {\n const extractor = (node: any) => extractCssVariable(node, (variableName, childrenArray) => {\n if (!variableName.startsWith('--lwc-')) {\n return null;\n }\n\n // Check if there's a fallback (comma separator)\n const hasFallback = childrenArray.some((child: any) => \n child.type === 'Operator' && child.value === ','\n );\n\n return { name: variableName, hasFallback };\n });\n\n forEachValue(valueText, extractor, () => false, callback);\n}\n\n/**\n * Format multiple hook suggestions for better readability\n * @param hooks - Array of hook names to format\n * @returns Formatted string with hooks\n */\nexport function formatSuggestionHooks(hooks: string[]): string {\n if (hooks.length === 1) {\n return `${hooks[0]}`;\n }\n\n // Loop through hooks and append each as a numbered list item with line breaks\n return '\\n' + hooks.map((hook, index) => `${index + 1}. ${hook}`).join('\\n');\n}"],
5
- "mappings": "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",
6
- "names": ["exports", "module", "import_css_tree", "ruleMessages", "metadata"]
3
+ "sources": ["../../../src/rules/v9/lwc-token-to-slds-hook.ts"],
4
+ "sourcesContent": ["import { Rule } from 'eslint';\nimport metadata from '@salesforce-ux/sds-metadata/next';\nimport ruleMessages from '../../config/rule-messages';\nimport { formatSuggestionHooks, forEachLwcVariable, type CssVariableInfo } from '../../utils/css-utils';\nimport type { PositionInfo } from '../../utils/hardcoded-shared-utils';\n\nconst ruleConfig = ruleMessages['lwc-token-to-slds-hook'];\nconst { type, description, url, messages } = ruleConfig;\n\nconst lwcToSlds = metadata.lwcToSlds;\n\n// Replacement category enum to match Stylelint version\nenum ReplacementCategory {\n EMPTY = 'empty',\n SLDS_TOKEN = 'slds_token',\n ARRAY = 'array',\n RAW_VALUE = 'raw_value'\n}\n\nfunction shouldIgnoreDetection(lwcToken: string): boolean {\n // Ignore if entry not found in the list or the token is marked to use further\n return (\n !lwcToken.startsWith('--lwc-') ||\n !(lwcToken in lwcToSlds) ||\n lwcToSlds[lwcToken].continueToUse\n );\n}\n\nfunction categorizeReplacement(recommendation: string | string[]): ReplacementCategory {\n if (!recommendation || recommendation === '--') {\n return ReplacementCategory.EMPTY;\n }\n if (Array.isArray(recommendation)) {\n return ReplacementCategory.ARRAY;\n }\n if (typeof recommendation === 'string' && recommendation.startsWith('--slds-')) {\n return ReplacementCategory.SLDS_TOKEN;\n }\n return ReplacementCategory.RAW_VALUE;\n}\n\nfunction getRecommendation(lwcToken: string) {\n const oldValue = lwcToken;\n const recommendation = lwcToSlds[oldValue]?.replacement || '';\n const replacementCategory = categorizeReplacement(recommendation);\n const hasRecommendation = oldValue in lwcToSlds && replacementCategory !== ReplacementCategory.EMPTY;\n return { hasRecommendation, recommendation, replacementCategory };\n}\n\nfunction getReportMessage(cssVar: string, replacementCategory: ReplacementCategory, recommendation: string | string[]): { messageId: string, data: any } {\n if (!recommendation) {\n // Found a deprecated token but don't have any alternate recommendation then just report user to follow docs\n return {\n messageId: 'errorWithNoRecommendation',\n data: { oldValue: cssVar }\n };\n } else if (replacementCategory === ReplacementCategory.ARRAY) {\n return {\n messageId: 'errorWithStyleHooks',\n data: { oldValue: cssVar, newValue: formatSuggestionHooks(recommendation as string[]) }\n };\n } else if (replacementCategory === ReplacementCategory.SLDS_TOKEN) {\n return {\n messageId: 'errorWithStyleHooks',\n data: { oldValue: cssVar, newValue: recommendation as string }\n };\n } else {\n return {\n messageId: 'errorWithReplacement',\n data: { oldValue: cssVar, newValue: recommendation as string }\n };\n }\n}\n\nexport default {\n meta: {\n type,\n docs: {\n description,\n recommended: true,\n url,\n },\n fixable: 'code',\n messages,\n },\n \n create(context) {\n function reportAndFix(\n node: any,\n suggestedMatch: string | null,\n messageId: string,\n data: any,\n fixRange?: [number, number],\n loc?: any\n ) {\n context.report({\n node,\n loc: loc || node.loc,\n messageId,\n data,\n fix: suggestedMatch && fixRange ? (fixer) => {\n return fixer.replaceTextRange(fixRange, suggestedMatch);\n } : undefined\n });\n }\n\n return {\n // CSS custom property declarations: Check both property name and value\n \"Declaration\"(node) {\n // Check 1: Property name (left-side) for custom properties using --lwc- prefix\n const property = node.property;\n if (property && property.startsWith('--lwc-')) {\n if (!shouldIgnoreDetection(property)) {\n const { hasRecommendation, recommendation, replacementCategory } = getRecommendation(property);\n const { messageId, data } = getReportMessage(property, replacementCategory, recommendation);\n \n // Only provide auto-fix for SLDS token replacements\n const suggestedMatch = (hasRecommendation && replacementCategory === ReplacementCategory.SLDS_TOKEN) \n ? recommendation as string \n : null;\n \n // Calculate fix range for property name\n const propertyStart = node.loc.start.offset;\n const propertyEnd = propertyStart + property.length;\n \n reportAndFix(node, suggestedMatch, messageId, data, [propertyStart, propertyEnd]);\n }\n }\n\n // Check 2: Property value (right-side) - Use AST parsing to detect var(--lwc-*) functions\n // Note: We use forEachLwcVariable instead of Function[name='var'] handler because\n // ESLint treats custom property values (e.g., --custom-prop: var(--lwc-token)) as raw strings\n // rather than parsing them into Function nodes. This AST-based approach handles both cases.\n const valueText = context.sourceCode.getText(node.value);\n if (valueText) {\n forEachLwcVariable(valueText, (variableInfo: CssVariableInfo, positionInfo: PositionInfo) => {\n const { name: lwcToken, hasFallback } = variableInfo;\n \n if (shouldIgnoreDetection(lwcToken)) {\n return;\n }\n\n const { hasRecommendation, recommendation, replacementCategory } = getRecommendation(lwcToken);\n const { messageId, data } = getReportMessage(lwcToken, replacementCategory, recommendation);\n \n let suggestedMatch: string | null = null;\n \n if (hasRecommendation) {\n if (replacementCategory === ReplacementCategory.SLDS_TOKEN) {\n // Extract fallback value from the original var() call if present\n // Use position info to get the full var() call text\n let fallbackValue: string | null = null;\n if (hasFallback && positionInfo.start && positionInfo.end && positionInfo.start.offset !== undefined && positionInfo.end.offset !== undefined) {\n const varCallText = valueText.substring(positionInfo.start.offset, positionInfo.end.offset);\n // Find the comma after the token name and extract everything after it (before the closing paren)\n const commaIndex = varCallText.indexOf(',');\n if (commaIndex !== -1) {\n // Extract from after comma to before closing paren\n fallbackValue = varCallText.substring(commaIndex + 1, varCallText.length - 1).trim();\n }\n }\n \n // Create the replacement in the format: var(--slds-token, var(--lwc-token, fallback))\n // This preserves any existing fallback value\n const originalVarCall = fallbackValue \n ? `var(${lwcToken}, ${fallbackValue})`\n : `var(${lwcToken})`;\n suggestedMatch = `var(${recommendation}, ${originalVarCall})`;\n } else if (replacementCategory === ReplacementCategory.RAW_VALUE) {\n suggestedMatch = recommendation as string;\n }\n }\n\n // Calculate fix range and location using position info from AST parsing\n const valueStartOffset = node.value.loc.start.offset;\n const varStartOffset = valueStartOffset + (positionInfo.start?.offset || 0);\n const varEndOffset = valueStartOffset + (positionInfo.end?.offset || valueText.length);\n \n // Calculate precise location if position info is available\n const preciseLoc = positionInfo.start && positionInfo.end && node.value.loc ? {\n start: {\n line: node.value.loc.start.line + positionInfo.start.line - 1,\n column: node.value.loc.start.column + positionInfo.start.column - 1\n },\n end: {\n line: node.value.loc.start.line + positionInfo.end.line - 1,\n column: node.value.loc.start.column + positionInfo.end.column - 1\n }\n } : node.value.loc;\n \n reportAndFix(node, suggestedMatch, messageId, data, [varStartOffset, varEndOffset], preciseLoc);\n });\n }\n },\n };\n },\n} as Rule.RuleModule;\n"],
5
+ "mappings": "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",
6
+ "names": ["ruleMessages", "metadata"]
7
7
  }