@salesforce-ux/eslint-plugin-slds 1.0.0 → 1.0.2-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 (69) hide show
  1. package/README.md +18 -1
  2. package/build/index.js +693 -697
  3. package/build/index.js.map +4 -4
  4. package/build/rules/enforce-bem-usage.js +6 -6
  5. package/build/rules/enforce-bem-usage.js.map +3 -3
  6. package/build/rules/modal-close-button-issue.js +1 -1
  7. package/build/rules/modal-close-button-issue.js.map +1 -1
  8. package/build/rules/no-deprecated-classes-slds2.js +3 -3
  9. package/build/rules/no-deprecated-classes-slds2.js.map +2 -2
  10. package/build/rules/v9/enforce-bem-usage.js +3 -3
  11. package/build/rules/v9/enforce-bem-usage.js.map +2 -2
  12. package/build/rules/v9/enforce-component-hook-naming-convention.js +3 -3
  13. package/build/rules/v9/enforce-component-hook-naming-convention.js.map +2 -2
  14. package/build/rules/v9/enforce-sds-to-slds-hooks.js +3 -3
  15. package/build/rules/v9/enforce-sds-to-slds-hooks.js.map +2 -2
  16. package/build/rules/v9/lwc-token-to-slds-hook.js +43 -4
  17. package/build/rules/v9/lwc-token-to-slds-hook.js.map +4 -4
  18. package/build/rules/v9/no-deprecated-slds-classes.js +3 -3
  19. package/build/rules/v9/no-deprecated-slds-classes.js.map +2 -2
  20. package/build/rules/v9/no-deprecated-tokens-slds1.js +3 -3
  21. package/build/rules/v9/no-deprecated-tokens-slds1.js.map +2 -2
  22. package/build/rules/v9/no-hardcoded-values/handlers/boxShadowHandler.js +49 -54
  23. package/build/rules/v9/no-hardcoded-values/handlers/boxShadowHandler.js.map +3 -3
  24. package/build/rules/v9/no-hardcoded-values/handlers/colorHandler.js +9 -2
  25. package/build/rules/v9/no-hardcoded-values/handlers/colorHandler.js.map +3 -3
  26. package/build/rules/v9/no-hardcoded-values/handlers/densityHandler.js +14 -3
  27. package/build/rules/v9/no-hardcoded-values/handlers/densityHandler.js.map +3 -3
  28. package/build/rules/v9/no-hardcoded-values/handlers/fontHandler.js +14 -3
  29. package/build/rules/v9/no-hardcoded-values/handlers/fontHandler.js.map +3 -3
  30. package/build/rules/v9/no-hardcoded-values/handlers/index.js +86 -90
  31. package/build/rules/v9/no-hardcoded-values/handlers/index.js.map +3 -3
  32. package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds1.js +90 -94
  33. package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds1.js.map +3 -3
  34. package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds2.js +90 -94
  35. package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds2.js.map +3 -3
  36. package/build/rules/v9/no-hardcoded-values/noHardcodedValueRule.js +87 -91
  37. package/build/rules/v9/no-hardcoded-values/noHardcodedValueRule.js.map +3 -3
  38. package/build/rules/v9/no-slds-class-overrides.js +3 -3
  39. package/build/rules/v9/no-slds-class-overrides.js.map +2 -2
  40. package/build/rules/v9/no-slds-namespace-for-custom-hooks.js +3 -3
  41. package/build/rules/v9/no-slds-namespace-for-custom-hooks.js.map +2 -2
  42. package/build/rules/v9/no-slds-private-var.js +1 -1
  43. package/build/rules/v9/no-slds-private-var.js.map +1 -1
  44. package/build/rules/v9/no-slds-var-without-fallback.js +3 -3
  45. package/build/rules/v9/no-slds-var-without-fallback.js.map +2 -2
  46. package/build/rules/v9/no-sldshook-fallback-for-lwctoken.js +3 -3
  47. package/build/rules/v9/no-sldshook-fallback-for-lwctoken.js.map +2 -2
  48. package/build/rules/v9/no-unsupported-hooks-slds2.js +3 -3
  49. package/build/rules/v9/no-unsupported-hooks-slds2.js.map +2 -2
  50. package/build/rules/v9/reduce-annotations.js +1 -1
  51. package/build/rules/v9/reduce-annotations.js.map +1 -1
  52. package/build/src/utils/css-utils.d.ts +6 -0
  53. package/build/src/utils/value-utils.d.ts +3 -2
  54. package/build/types/index.js.map +1 -1
  55. package/build/utils/boxShadowValueParser.js +4 -1
  56. package/build/utils/boxShadowValueParser.js.map +2 -2
  57. package/build/utils/color-lib-utils.js.map +1 -1
  58. package/build/utils/css-utils.js +8 -0
  59. package/build/utils/css-utils.js.map +2 -2
  60. package/build/utils/hardcoded-shared-utils.js +5 -2
  61. package/build/utils/hardcoded-shared-utils.js.map +3 -3
  62. package/build/utils/property-matcher.js +1 -1
  63. package/build/utils/property-matcher.js.map +2 -2
  64. package/build/utils/styling-hook-utils.js +4 -1
  65. package/build/utils/styling-hook-utils.js.map +2 -2
  66. package/build/utils/value-utils.js +6 -1
  67. package/build/utils/value-utils.js.map +2 -2
  68. package/package.json +2 -2
  69. package/src/config/rule-messages.yml +1 -1
@@ -167,7 +167,7 @@ var require_rule_messages = __commonJS({
167
167
  },
168
168
  "no-hardcoded-values-slds2": {
169
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-value",
170
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-hardcoded-values-slds2",
171
171
  "type": "suggestion",
172
172
  "messages": {
173
173
  "hardcodedValue": "Consider replacing the {{oldValue}} static value with an SLDS 2 styling hook that has a similar value: {{newValue}}.",
@@ -192,7 +192,7 @@ __export(no_hardcoded_values_slds2_exports, {
192
192
  default: () => no_hardcoded_values_slds2_default
193
193
  });
194
194
  module.exports = __toCommonJS(no_hardcoded_values_slds2_exports);
195
- var import_sds_metadata = __toESM(require("@salesforce-ux/sds-metadata"));
195
+ var import_next = __toESM(require("@salesforce-ux/sds-metadata/next"));
196
196
  var import_rule_messages = __toESM(require_rule_messages());
197
197
 
198
198
  // src/utils/color-lib-utils.ts
@@ -378,7 +378,7 @@ function toSelector(properties) {
378
378
  const selectorParts = properties.map((prop) => {
379
379
  if (prop.includes("*")) {
380
380
  const regexPattern = prop.replace(/\*/g, ".*");
381
- return `Declaration[property=/${regexPattern}$/]`;
381
+ return `Declaration[property=/^${regexPattern}$/]`;
382
382
  } else {
383
383
  return `Declaration[property='${prop}']`;
384
384
  }
@@ -409,6 +409,42 @@ function resolvePropertyToMatch(cssProperty) {
409
409
 
410
410
  // src/utils/hardcoded-shared-utils.ts
411
411
  var import_css_tree2 = require("@eslint/css-tree");
412
+
413
+ // src/utils/value-utils.ts
414
+ var ALLOWED_UNITS = ["px", "em", "rem", "%", "ch"];
415
+ function parseUnitValue(value) {
416
+ if (!value) return null;
417
+ const unitsPattern = ALLOWED_UNITS.join("|");
418
+ const regex = new RegExp(`^(-?\\d*\\.?\\d+)(${unitsPattern})?$`);
419
+ const match = value.match(regex);
420
+ if (!match) return null;
421
+ const number = parseFloat(match[1]);
422
+ const unit = match[2] ? match[2] : null;
423
+ if (isNaN(number)) return null;
424
+ return { number, unit };
425
+ }
426
+ function toAlternateUnitValue(numberVal, unitType) {
427
+ if (unitType === "px") {
428
+ let floatValue = parseFloat(`${numberVal / 16}`);
429
+ if (!isNaN(floatValue)) {
430
+ return {
431
+ unit: "rem",
432
+ number: parseFloat(floatValue.toFixed(4))
433
+ };
434
+ }
435
+ } else if (unitType === "rem") {
436
+ const intValue = parseInt(`${numberVal * 16}`);
437
+ if (!isNaN(intValue)) {
438
+ return {
439
+ unit: "px",
440
+ number: intValue
441
+ };
442
+ }
443
+ }
444
+ return null;
445
+ }
446
+
447
+ // src/utils/hardcoded-shared-utils.ts
412
448
  var FONT_WEIGHTS = [
413
449
  "normal",
414
450
  "bold",
@@ -518,7 +554,7 @@ function extractDimensionValue(valueNode, cssProperty) {
518
554
  const numValue = Number(valueNode.value);
519
555
  if (numValue === 0) return null;
520
556
  const unit = valueNode.unit.toLowerCase();
521
- if (unit !== "px" && unit !== "rem" && unit !== "%") return null;
557
+ if (!ALLOWED_UNITS.includes(unit)) return null;
522
558
  return {
523
559
  number: numValue,
524
560
  unit
@@ -560,7 +596,7 @@ function extractFontValue(node) {
560
596
  const numValue = Number(node.value);
561
597
  if (numValue <= 0) return null;
562
598
  const unit = node.unit.toLowerCase();
563
- if (unit !== "px" && unit !== "rem" && unit !== "%") return null;
599
+ if (!ALLOWED_UNITS.includes(unit)) return null;
564
600
  return {
565
601
  number: numValue,
566
602
  unit
@@ -605,6 +641,14 @@ function forEachFontValue(valueText, callback) {
605
641
  forEachValue(valueText, extractFontValue, shouldSkipFontNode, callback);
606
642
  }
607
643
 
644
+ // src/utils/css-utils.ts
645
+ function formatSuggestionHooks(hooks) {
646
+ if (hooks.length === 1) {
647
+ return `${hooks[0]}`;
648
+ }
649
+ return "\n" + hooks.map((hook, index) => `${index + 1}. ${hook}`).join("\n");
650
+ }
651
+
608
652
  // src/rules/v9/no-hardcoded-values/handlers/colorHandler.ts
609
653
  var handleColorDeclaration = (node, context) => {
610
654
  const cssProperty = node.property.toLowerCase();
@@ -647,9 +691,8 @@ function createColorReplacement(colorValue, cssProperty, context, positionInfo,
647
691
  end,
648
692
  replacement: originalValue,
649
693
  // Use original value to preserve spacing
650
- displayValue: closestHooks.join(", "),
694
+ displayValue: formatSuggestionHooks(closestHooks),
651
695
  hasHook: true
652
- // ← THE FIX: Multiple hooks still means "has hooks"
653
696
  };
654
697
  } else {
655
698
  return {
@@ -663,37 +706,6 @@ function createColorReplacement(colorValue, cssProperty, context, positionInfo,
663
706
  }
664
707
  }
665
708
 
666
- // src/utils/value-utils.ts
667
- function parseUnitValue(value) {
668
- if (!value) return null;
669
- const match = value.match(/^(-?\d*\.?\d+)(px|rem|%)?$/);
670
- if (!match) return null;
671
- const number = parseFloat(match[1]);
672
- const unit = match[2] ? match[2] : null;
673
- if (isNaN(number)) return null;
674
- return { number, unit };
675
- }
676
- function toAlternateUnitValue(numberVal, unitType) {
677
- if (unitType === "px") {
678
- let floatValue = parseFloat(`${numberVal / 16}`);
679
- if (!isNaN(floatValue)) {
680
- return {
681
- unit: "rem",
682
- number: parseFloat(floatValue.toFixed(4))
683
- };
684
- }
685
- } else if (unitType === "rem") {
686
- const intValue = parseInt(`${numberVal * 16}`);
687
- if (!isNaN(intValue)) {
688
- return {
689
- unit: "px",
690
- number: intValue
691
- };
692
- }
693
- }
694
- return null;
695
- }
696
-
697
709
  // src/utils/styling-hook-utils.ts
698
710
  function isValueMatch(valueToMatch, sldsValue) {
699
711
  if (!valueToMatch || !sldsValue) {
@@ -751,7 +763,7 @@ function createDimensionReplacement(parsedDimension, cssProperty, context, posit
751
763
  start,
752
764
  end,
753
765
  replacement: rawValue,
754
- displayValue: closestHooks.join(", "),
766
+ displayValue: formatSuggestionHooks(closestHooks),
755
767
  hasHook: true
756
768
  };
757
769
  } else {
@@ -818,7 +830,7 @@ function createFontReplacement(fontValue, cssProperty, context, positionInfo) {
818
830
  start,
819
831
  end,
820
832
  replacement: rawValue,
821
- displayValue: closestHooks.join(", "),
833
+ displayValue: formatSuggestionHooks(closestHooks),
822
834
  hasHook: true
823
835
  };
824
836
  } else {
@@ -945,59 +957,51 @@ function isBoxShadowMatch(parsedCssValue, parsedValueHook) {
945
957
  }
946
958
 
947
959
  // src/rules/v9/no-hardcoded-values/handlers/boxShadowHandler.ts
948
- function containsCssVariable(valueText) {
949
- return valueText.includes("var(");
950
- }
951
- var handleBoxShadowDeclaration = (node, context) => {
952
- const cssProperty = node.property.toLowerCase();
953
- const valueText = context.sourceCode.getText(node.value);
954
- if (containsCssVariable(valueText)) {
955
- return;
956
- }
957
- const replacements = [];
958
- const parsedCssValue = parseAndValidateBoxShadow(valueText);
959
- if (parsedCssValue) {
960
- const shadowHooks = getBoxShadowHooks(context.valueToStylinghook);
961
- const closestHooks = findMatchingBoxShadowHooks(parsedCssValue, shadowHooks);
962
- const positionInfo = {
963
- start: { offset: 0, line: 1, column: 1 },
964
- end: { offset: valueText.length, line: 1, column: valueText.length + 1 }
965
- };
966
- const replacement = createBoxShadowReplacement(
967
- valueText,
968
- closestHooks,
969
- context,
970
- positionInfo
971
- );
972
- if (replacement) {
973
- replacements.push(replacement);
974
- }
960
+ function toBoxShadowValue(cssValue) {
961
+ const parsedCssValue = parseBoxShadowValue(cssValue).filter((shadow) => Object.keys(shadow).length > 0);
962
+ if (parsedCssValue.length === 0) {
963
+ return null;
975
964
  }
976
- handleShorthandAutoFix(node, context, valueText, replacements);
977
- };
978
- function getBoxShadowHooks(supportedStylinghooks) {
965
+ return parsedCssValue;
966
+ }
967
+ function shadowValueToHookEntries(supportedStylinghooks) {
979
968
  return Object.entries(supportedStylinghooks).filter(([key, value]) => {
980
969
  return value.some((hook) => hook.properties.includes("box-shadow"));
981
970
  }).map(([key, value]) => {
982
971
  return [key, value.map((hook) => hook.name)];
983
972
  });
984
973
  }
985
- function parseAndValidateBoxShadow(cssValue) {
986
- const parsedCssValue = parseBoxShadowValue(cssValue).filter((shadow) => Object.keys(shadow).length > 0);
987
- if (parsedCssValue.length === 0) {
988
- return null;
974
+ var handleBoxShadowDeclaration = (node, context) => {
975
+ const cssProperty = node.property.toLowerCase();
976
+ const valueText = context.sourceCode.getText(node.value);
977
+ const shadowHooks = shadowValueToHookEntries(context.valueToStylinghook);
978
+ const parsedCssValue = toBoxShadowValue(valueText);
979
+ if (!parsedCssValue) {
980
+ return;
989
981
  }
990
- return parsedCssValue;
991
- }
992
- function findMatchingBoxShadowHooks(parsedCssValue, shadowHooks) {
993
- for (const [shadowHookValue, closestHooks] of shadowHooks) {
994
- const parsedHookValue = parseAndValidateBoxShadow(shadowHookValue);
995
- if (parsedHookValue && isBoxShadowMatch(parsedCssValue, parsedHookValue)) {
996
- return closestHooks;
982
+ for (const [shadow, closestHooks] of shadowHooks) {
983
+ const parsedValueHook = toBoxShadowValue(shadow);
984
+ if (parsedValueHook && isBoxShadowMatch(parsedCssValue, parsedValueHook)) {
985
+ if (closestHooks.length > 0) {
986
+ const positionInfo = {
987
+ start: { offset: 0, line: 1, column: 1 },
988
+ end: { offset: valueText.length, line: 1, column: valueText.length + 1 }
989
+ };
990
+ const replacement = createBoxShadowReplacement(
991
+ valueText,
992
+ closestHooks,
993
+ context,
994
+ positionInfo
995
+ );
996
+ if (replacement) {
997
+ const replacements = [replacement];
998
+ handleShorthandAutoFix(node, context, valueText, replacements);
999
+ }
1000
+ }
1001
+ return;
997
1002
  }
998
1003
  }
999
- return [];
1000
- }
1004
+ };
1001
1005
  function createBoxShadowReplacement(originalValue, hooks, context, positionInfo) {
1002
1006
  if (!positionInfo?.start) {
1003
1007
  return null;
@@ -1012,21 +1016,13 @@ function createBoxShadowReplacement(originalValue, hooks, context, positionInfo)
1012
1016
  displayValue: hooks[0],
1013
1017
  hasHook: true
1014
1018
  };
1015
- } else if (hooks.length > 1) {
1016
- return {
1017
- start,
1018
- end,
1019
- replacement: originalValue,
1020
- displayValue: hooks.join(", "),
1021
- hasHook: true
1022
- };
1023
1019
  } else {
1024
1020
  return {
1025
1021
  start,
1026
1022
  end,
1027
1023
  replacement: originalValue,
1028
- displayValue: originalValue,
1029
- hasHook: false
1024
+ displayValue: formatSuggestionHooks(hooks),
1025
+ hasHook: true
1030
1026
  };
1031
1027
  }
1032
1028
  }
@@ -1127,7 +1123,7 @@ function defineNoHardcodedValueRule(config) {
1127
1123
  var ruleName = "no-hardcoded-values-slds2";
1128
1124
  var ruleConfig = import_rule_messages.default[ruleName];
1129
1125
  var { type, description, url, messages } = ruleConfig;
1130
- var valueToStylinghook = import_sds_metadata.default.valueToStylingHooksCosmos;
1126
+ var valueToStylinghook = import_next.default.valueToStylingHooksCosmos;
1131
1127
  var no_hardcoded_values_slds2_default = defineNoHardcodedValueRule({
1132
1128
  ruleConfig,
1133
1129
  valueToStylinghook,