@salesforce-ux/eslint-plugin-slds 1.0.0-internal-alpha.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -1
- package/build/index.js +1072 -1016
- package/build/index.js.map +4 -4
- package/build/rules/enforce-bem-usage.js +5 -5
- package/build/rules/enforce-bem-usage.js.map +3 -3
- package/build/rules/no-deprecated-classes-slds2.js +2 -2
- package/build/rules/no-deprecated-classes-slds2.js.map +2 -2
- package/build/rules/v9/enforce-bem-usage.js +2 -2
- package/build/rules/v9/enforce-bem-usage.js.map +2 -2
- package/build/rules/v9/enforce-component-hook-naming-convention.js +2 -2
- package/build/rules/v9/enforce-component-hook-naming-convention.js.map +2 -2
- package/build/rules/v9/enforce-sds-to-slds-hooks.js +2 -2
- package/build/rules/v9/enforce-sds-to-slds-hooks.js.map +2 -2
- package/build/rules/v9/lwc-token-to-slds-hook.js +42 -3
- package/build/rules/v9/lwc-token-to-slds-hook.js.map +4 -4
- package/build/rules/v9/no-deprecated-slds-classes.js +2 -2
- package/build/rules/v9/no-deprecated-slds-classes.js.map +2 -2
- package/build/rules/v9/no-deprecated-tokens-slds1.js +2 -2
- package/build/rules/v9/no-deprecated-tokens-slds1.js.map +2 -2
- package/build/rules/v9/no-hardcoded-values/handlers/boxShadowHandler.js +49 -54
- package/build/rules/v9/no-hardcoded-values/handlers/boxShadowHandler.js.map +3 -3
- package/build/rules/v9/no-hardcoded-values/handlers/colorHandler.js +9 -2
- package/build/rules/v9/no-hardcoded-values/handlers/colorHandler.js.map +3 -3
- package/build/rules/v9/no-hardcoded-values/handlers/densityHandler.js +14 -3
- package/build/rules/v9/no-hardcoded-values/handlers/densityHandler.js.map +3 -3
- package/build/rules/v9/no-hardcoded-values/handlers/fontHandler.js +14 -3
- package/build/rules/v9/no-hardcoded-values/handlers/fontHandler.js.map +3 -3
- package/build/rules/v9/no-hardcoded-values/handlers/index.js +86 -90
- package/build/rules/v9/no-hardcoded-values/handlers/index.js.map +3 -3
- package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds1.js +116 -96
- package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds1.js.map +4 -4
- package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds2.js +116 -96
- package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds2.js.map +4 -4
- package/build/rules/v9/no-hardcoded-values/noHardcodedValueRule.js +110 -92
- package/build/rules/v9/no-hardcoded-values/noHardcodedValueRule.js.map +3 -3
- package/build/rules/v9/no-slds-class-overrides.js +2 -2
- package/build/rules/v9/no-slds-class-overrides.js.map +2 -2
- package/build/rules/v9/no-slds-namespace-for-custom-hooks.js +2 -2
- package/build/rules/v9/no-slds-namespace-for-custom-hooks.js.map +2 -2
- package/build/rules/v9/no-slds-var-without-fallback.js +121 -35
- package/build/rules/v9/no-slds-var-without-fallback.js.map +4 -4
- package/build/rules/v9/no-sldshook-fallback-for-lwctoken.js +2 -2
- package/build/rules/v9/no-sldshook-fallback-for-lwctoken.js.map +2 -2
- package/build/rules/v9/no-unsupported-hooks-slds2.js +2 -2
- package/build/rules/v9/no-unsupported-hooks-slds2.js.map +2 -2
- package/build/src/rules/v9/no-hardcoded-values/noHardcodedValueRule.d.ts +3 -1
- package/build/src/rules/v9/no-slds-var-without-fallback.d.ts +4 -0
- package/build/src/utils/css-utils.d.ts +19 -0
- package/build/src/utils/rule-utils.d.ts +8 -0
- package/build/src/utils/value-utils.d.ts +3 -2
- package/build/types/index.js.map +1 -1
- package/build/utils/boxShadowValueParser.js +4 -1
- package/build/utils/boxShadowValueParser.js.map +2 -2
- package/build/utils/color-lib-utils.js.map +1 -1
- package/build/utils/css-utils.js +108 -0
- package/build/utils/css-utils.js.map +4 -4
- package/build/utils/hardcoded-shared-utils.js +5 -2
- package/build/utils/hardcoded-shared-utils.js.map +3 -3
- package/build/utils/property-matcher.js +1 -1
- package/build/utils/property-matcher.js.map +2 -2
- package/build/utils/rule-utils.js +46 -0
- package/build/utils/rule-utils.js.map +7 -0
- package/build/utils/styling-hook-utils.js +4 -1
- package/build/utils/styling-hook-utils.js.map +2 -2
- package/build/utils/value-utils.js +6 -1
- package/build/utils/value-utils.js.map +2 -2
- package/package.json +1 -1
|
@@ -216,7 +216,7 @@ function toSelector(properties) {
|
|
|
216
216
|
const selectorParts = properties.map((prop) => {
|
|
217
217
|
if (prop.includes("*")) {
|
|
218
218
|
const regexPattern = prop.replace(/\*/g, ".*");
|
|
219
|
-
return `Declaration[property
|
|
219
|
+
return `Declaration[property=/^${regexPattern}$/]`;
|
|
220
220
|
} else {
|
|
221
221
|
return `Declaration[property='${prop}']`;
|
|
222
222
|
}
|
|
@@ -247,6 +247,42 @@ function resolvePropertyToMatch(cssProperty) {
|
|
|
247
247
|
|
|
248
248
|
// src/utils/hardcoded-shared-utils.ts
|
|
249
249
|
var import_css_tree2 = require("@eslint/css-tree");
|
|
250
|
+
|
|
251
|
+
// src/utils/value-utils.ts
|
|
252
|
+
var ALLOWED_UNITS = ["px", "em", "rem", "%", "ch"];
|
|
253
|
+
function parseUnitValue(value) {
|
|
254
|
+
if (!value) return null;
|
|
255
|
+
const unitsPattern = ALLOWED_UNITS.join("|");
|
|
256
|
+
const regex = new RegExp(`^(-?\\d*\\.?\\d+)(${unitsPattern})?$`);
|
|
257
|
+
const match = value.match(regex);
|
|
258
|
+
if (!match) return null;
|
|
259
|
+
const number = parseFloat(match[1]);
|
|
260
|
+
const unit = match[2] ? match[2] : null;
|
|
261
|
+
if (isNaN(number)) return null;
|
|
262
|
+
return { number, unit };
|
|
263
|
+
}
|
|
264
|
+
function toAlternateUnitValue(numberVal, unitType) {
|
|
265
|
+
if (unitType === "px") {
|
|
266
|
+
let floatValue = parseFloat(`${numberVal / 16}`);
|
|
267
|
+
if (!isNaN(floatValue)) {
|
|
268
|
+
return {
|
|
269
|
+
unit: "rem",
|
|
270
|
+
number: parseFloat(floatValue.toFixed(4))
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
} else if (unitType === "rem") {
|
|
274
|
+
const intValue = parseInt(`${numberVal * 16}`);
|
|
275
|
+
if (!isNaN(intValue)) {
|
|
276
|
+
return {
|
|
277
|
+
unit: "px",
|
|
278
|
+
number: intValue
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// src/utils/hardcoded-shared-utils.ts
|
|
250
286
|
var FONT_WEIGHTS = [
|
|
251
287
|
"normal",
|
|
252
288
|
"bold",
|
|
@@ -356,7 +392,7 @@ function extractDimensionValue(valueNode, cssProperty) {
|
|
|
356
392
|
const numValue = Number(valueNode.value);
|
|
357
393
|
if (numValue === 0) return null;
|
|
358
394
|
const unit = valueNode.unit.toLowerCase();
|
|
359
|
-
if (unit
|
|
395
|
+
if (!ALLOWED_UNITS.includes(unit)) return null;
|
|
360
396
|
return {
|
|
361
397
|
number: numValue,
|
|
362
398
|
unit
|
|
@@ -398,7 +434,7 @@ function extractFontValue(node) {
|
|
|
398
434
|
const numValue = Number(node.value);
|
|
399
435
|
if (numValue <= 0) return null;
|
|
400
436
|
const unit = node.unit.toLowerCase();
|
|
401
|
-
if (unit
|
|
437
|
+
if (!ALLOWED_UNITS.includes(unit)) return null;
|
|
402
438
|
return {
|
|
403
439
|
number: numValue,
|
|
404
440
|
unit
|
|
@@ -443,6 +479,14 @@ function forEachFontValue(valueText, callback) {
|
|
|
443
479
|
forEachValue(valueText, extractFontValue, shouldSkipFontNode, callback);
|
|
444
480
|
}
|
|
445
481
|
|
|
482
|
+
// src/utils/css-utils.ts
|
|
483
|
+
function formatSuggestionHooks(hooks) {
|
|
484
|
+
if (hooks.length === 1) {
|
|
485
|
+
return `${hooks[0]}`;
|
|
486
|
+
}
|
|
487
|
+
return "\n" + hooks.map((hook, index) => `${index + 1}. ${hook}`).join("\n");
|
|
488
|
+
}
|
|
489
|
+
|
|
446
490
|
// src/rules/v9/no-hardcoded-values/handlers/colorHandler.ts
|
|
447
491
|
var handleColorDeclaration = (node, context) => {
|
|
448
492
|
const cssProperty = node.property.toLowerCase();
|
|
@@ -485,9 +529,8 @@ function createColorReplacement(colorValue, cssProperty, context, positionInfo,
|
|
|
485
529
|
end,
|
|
486
530
|
replacement: originalValue,
|
|
487
531
|
// Use original value to preserve spacing
|
|
488
|
-
displayValue: closestHooks
|
|
532
|
+
displayValue: formatSuggestionHooks(closestHooks),
|
|
489
533
|
hasHook: true
|
|
490
|
-
// ← THE FIX: Multiple hooks still means "has hooks"
|
|
491
534
|
};
|
|
492
535
|
} else {
|
|
493
536
|
return {
|
|
@@ -501,37 +544,6 @@ function createColorReplacement(colorValue, cssProperty, context, positionInfo,
|
|
|
501
544
|
}
|
|
502
545
|
}
|
|
503
546
|
|
|
504
|
-
// src/utils/value-utils.ts
|
|
505
|
-
function parseUnitValue(value) {
|
|
506
|
-
if (!value) return null;
|
|
507
|
-
const match = value.match(/^(-?\d*\.?\d+)(px|rem|%)?$/);
|
|
508
|
-
if (!match) return null;
|
|
509
|
-
const number = parseFloat(match[1]);
|
|
510
|
-
const unit = match[2] ? match[2] : null;
|
|
511
|
-
if (isNaN(number)) return null;
|
|
512
|
-
return { number, unit };
|
|
513
|
-
}
|
|
514
|
-
function toAlternateUnitValue(numberVal, unitType) {
|
|
515
|
-
if (unitType === "px") {
|
|
516
|
-
let floatValue = parseFloat(`${numberVal / 16}`);
|
|
517
|
-
if (!isNaN(floatValue)) {
|
|
518
|
-
return {
|
|
519
|
-
unit: "rem",
|
|
520
|
-
number: parseFloat(floatValue.toFixed(4))
|
|
521
|
-
};
|
|
522
|
-
}
|
|
523
|
-
} else if (unitType === "rem") {
|
|
524
|
-
const intValue = parseInt(`${numberVal * 16}`);
|
|
525
|
-
if (!isNaN(intValue)) {
|
|
526
|
-
return {
|
|
527
|
-
unit: "px",
|
|
528
|
-
number: intValue
|
|
529
|
-
};
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
return null;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
547
|
// src/utils/styling-hook-utils.ts
|
|
536
548
|
function isValueMatch(valueToMatch, sldsValue) {
|
|
537
549
|
if (!valueToMatch || !sldsValue) {
|
|
@@ -589,7 +601,7 @@ function createDimensionReplacement(parsedDimension, cssProperty, context, posit
|
|
|
589
601
|
start,
|
|
590
602
|
end,
|
|
591
603
|
replacement: rawValue,
|
|
592
|
-
displayValue: closestHooks
|
|
604
|
+
displayValue: formatSuggestionHooks(closestHooks),
|
|
593
605
|
hasHook: true
|
|
594
606
|
};
|
|
595
607
|
} else {
|
|
@@ -656,7 +668,7 @@ function createFontReplacement(fontValue, cssProperty, context, positionInfo) {
|
|
|
656
668
|
start,
|
|
657
669
|
end,
|
|
658
670
|
replacement: rawValue,
|
|
659
|
-
displayValue: closestHooks
|
|
671
|
+
displayValue: formatSuggestionHooks(closestHooks),
|
|
660
672
|
hasHook: true
|
|
661
673
|
};
|
|
662
674
|
} else {
|
|
@@ -783,59 +795,51 @@ function isBoxShadowMatch(parsedCssValue, parsedValueHook) {
|
|
|
783
795
|
}
|
|
784
796
|
|
|
785
797
|
// src/rules/v9/no-hardcoded-values/handlers/boxShadowHandler.ts
|
|
786
|
-
function
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
const cssProperty = node.property.toLowerCase();
|
|
791
|
-
const valueText = context.sourceCode.getText(node.value);
|
|
792
|
-
if (containsCssVariable(valueText)) {
|
|
793
|
-
return;
|
|
794
|
-
}
|
|
795
|
-
const replacements = [];
|
|
796
|
-
const parsedCssValue = parseAndValidateBoxShadow(valueText);
|
|
797
|
-
if (parsedCssValue) {
|
|
798
|
-
const shadowHooks = getBoxShadowHooks(context.valueToStylinghook);
|
|
799
|
-
const closestHooks = findMatchingBoxShadowHooks(parsedCssValue, shadowHooks);
|
|
800
|
-
const positionInfo = {
|
|
801
|
-
start: { offset: 0, line: 1, column: 1 },
|
|
802
|
-
end: { offset: valueText.length, line: 1, column: valueText.length + 1 }
|
|
803
|
-
};
|
|
804
|
-
const replacement = createBoxShadowReplacement(
|
|
805
|
-
valueText,
|
|
806
|
-
closestHooks,
|
|
807
|
-
context,
|
|
808
|
-
positionInfo
|
|
809
|
-
);
|
|
810
|
-
if (replacement) {
|
|
811
|
-
replacements.push(replacement);
|
|
812
|
-
}
|
|
798
|
+
function toBoxShadowValue(cssValue) {
|
|
799
|
+
const parsedCssValue = parseBoxShadowValue(cssValue).filter((shadow) => Object.keys(shadow).length > 0);
|
|
800
|
+
if (parsedCssValue.length === 0) {
|
|
801
|
+
return null;
|
|
813
802
|
}
|
|
814
|
-
|
|
815
|
-
}
|
|
816
|
-
function
|
|
803
|
+
return parsedCssValue;
|
|
804
|
+
}
|
|
805
|
+
function shadowValueToHookEntries(supportedStylinghooks) {
|
|
817
806
|
return Object.entries(supportedStylinghooks).filter(([key, value]) => {
|
|
818
807
|
return value.some((hook) => hook.properties.includes("box-shadow"));
|
|
819
808
|
}).map(([key, value]) => {
|
|
820
809
|
return [key, value.map((hook) => hook.name)];
|
|
821
810
|
});
|
|
822
811
|
}
|
|
823
|
-
|
|
824
|
-
const
|
|
825
|
-
|
|
826
|
-
|
|
812
|
+
var handleBoxShadowDeclaration = (node, context) => {
|
|
813
|
+
const cssProperty = node.property.toLowerCase();
|
|
814
|
+
const valueText = context.sourceCode.getText(node.value);
|
|
815
|
+
const shadowHooks = shadowValueToHookEntries(context.valueToStylinghook);
|
|
816
|
+
const parsedCssValue = toBoxShadowValue(valueText);
|
|
817
|
+
if (!parsedCssValue) {
|
|
818
|
+
return;
|
|
827
819
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
820
|
+
for (const [shadow, closestHooks] of shadowHooks) {
|
|
821
|
+
const parsedValueHook = toBoxShadowValue(shadow);
|
|
822
|
+
if (parsedValueHook && isBoxShadowMatch(parsedCssValue, parsedValueHook)) {
|
|
823
|
+
if (closestHooks.length > 0) {
|
|
824
|
+
const positionInfo = {
|
|
825
|
+
start: { offset: 0, line: 1, column: 1 },
|
|
826
|
+
end: { offset: valueText.length, line: 1, column: valueText.length + 1 }
|
|
827
|
+
};
|
|
828
|
+
const replacement = createBoxShadowReplacement(
|
|
829
|
+
valueText,
|
|
830
|
+
closestHooks,
|
|
831
|
+
context,
|
|
832
|
+
positionInfo
|
|
833
|
+
);
|
|
834
|
+
if (replacement) {
|
|
835
|
+
const replacements = [replacement];
|
|
836
|
+
handleShorthandAutoFix(node, context, valueText, replacements);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
return;
|
|
835
840
|
}
|
|
836
841
|
}
|
|
837
|
-
|
|
838
|
-
}
|
|
842
|
+
};
|
|
839
843
|
function createBoxShadowReplacement(originalValue, hooks, context, positionInfo) {
|
|
840
844
|
if (!positionInfo?.start) {
|
|
841
845
|
return null;
|
|
@@ -850,28 +854,39 @@ function createBoxShadowReplacement(originalValue, hooks, context, positionInfo)
|
|
|
850
854
|
displayValue: hooks[0],
|
|
851
855
|
hasHook: true
|
|
852
856
|
};
|
|
853
|
-
} else if (hooks.length > 1) {
|
|
854
|
-
return {
|
|
855
|
-
start,
|
|
856
|
-
end,
|
|
857
|
-
replacement: originalValue,
|
|
858
|
-
displayValue: hooks.join(", "),
|
|
859
|
-
hasHook: true
|
|
860
|
-
};
|
|
861
857
|
} else {
|
|
862
858
|
return {
|
|
863
859
|
start,
|
|
864
860
|
end,
|
|
865
861
|
replacement: originalValue,
|
|
866
|
-
displayValue:
|
|
867
|
-
hasHook:
|
|
862
|
+
displayValue: formatSuggestionHooks(hooks),
|
|
863
|
+
hasHook: true
|
|
868
864
|
};
|
|
869
865
|
}
|
|
870
866
|
}
|
|
871
867
|
|
|
868
|
+
// src/utils/rule-utils.ts
|
|
869
|
+
function isRuleEnabled(context, ruleName) {
|
|
870
|
+
try {
|
|
871
|
+
const rules = context.settings?.sldsRules || {};
|
|
872
|
+
if (ruleName in rules) {
|
|
873
|
+
const ruleConfig = rules[ruleName];
|
|
874
|
+
if (Array.isArray(ruleConfig)) {
|
|
875
|
+
return ruleConfig[0] === true;
|
|
876
|
+
} else if (ruleConfig !== void 0 && ruleConfig !== null) {
|
|
877
|
+
return true;
|
|
878
|
+
} else if (ruleConfig === false) {
|
|
879
|
+
return false;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
} catch (error) {
|
|
883
|
+
return false;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
|
|
872
887
|
// src/rules/v9/no-hardcoded-values/noHardcodedValueRule.ts
|
|
873
888
|
function defineNoHardcodedValueRule(config) {
|
|
874
|
-
const { ruleConfig } = config;
|
|
889
|
+
const { ruleConfig, ruleName } = config;
|
|
875
890
|
const { type, description, url, messages } = ruleConfig;
|
|
876
891
|
return {
|
|
877
892
|
meta: {
|
|
@@ -885,6 +900,9 @@ function defineNoHardcodedValueRule(config) {
|
|
|
885
900
|
messages
|
|
886
901
|
},
|
|
887
902
|
create(context) {
|
|
903
|
+
if (ruleName === "no-hardcoded-values-slds1" && isRuleEnabled(context, "@salesforce-ux/slds/no-hardcoded-values-slds2")) {
|
|
904
|
+
return {};
|
|
905
|
+
}
|
|
888
906
|
const handlerContext = {
|
|
889
907
|
valueToStylinghook: config.valueToStylinghook,
|
|
890
908
|
context,
|