@salesforce-ux/eslint-plugin-slds 1.0.7-internal → 1.0.8-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.
- package/README.md +62 -0
- package/build/index.js +240 -104
- package/build/index.js.map +3 -3
- package/build/rules/v9/lwc-token-to-slds-hook.js.map +2 -2
- package/build/rules/v9/no-hardcoded-values/handlers/boxShadowHandler.js +86 -30
- package/build/rules/v9/no-hardcoded-values/handlers/boxShadowHandler.js.map +3 -3
- package/build/rules/v9/no-hardcoded-values/handlers/colorHandler.js +116 -104
- package/build/rules/v9/no-hardcoded-values/handlers/colorHandler.js.map +3 -3
- package/build/rules/v9/no-hardcoded-values/handlers/densityHandler.js +83 -30
- package/build/rules/v9/no-hardcoded-values/handlers/densityHandler.js.map +3 -3
- package/build/rules/v9/no-hardcoded-values/handlers/fontHandler.js +78 -74
- package/build/rules/v9/no-hardcoded-values/handlers/fontHandler.js.map +3 -3
- package/build/rules/v9/no-hardcoded-values/handlers/index.js +175 -99
- 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 +221 -101
- package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds1.js.map +3 -3
- package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds2.js +221 -101
- package/build/rules/v9/no-hardcoded-values/no-hardcoded-values-slds2.js.map +3 -3
- package/build/rules/v9/no-hardcoded-values/noHardcodedValueRule.js +221 -101
- package/build/rules/v9/no-hardcoded-values/noHardcodedValueRule.js.map +3 -3
- package/build/rules/v9/no-hardcoded-values/ruleOptionsSchema.js +63 -0
- package/build/rules/v9/no-hardcoded-values/ruleOptionsSchema.js.map +7 -0
- package/build/rules/v9/no-slds-namespace-for-custom-hooks.js.map +2 -2
- package/build/rules/v9/no-slds-var-without-fallback.js.map +2 -2
- package/build/src/rules/v9/no-hardcoded-values/ruleOptionsSchema.d.ts +40 -0
- package/build/src/types/index.d.ts +31 -0
- package/build/src/utils/color-lib-utils.d.ts +16 -9
- package/build/src/utils/custom-mapping-utils.d.ts +9 -0
- package/build/src/utils/hardcoded-shared-utils.d.ts +1 -0
- package/build/src/utils/property-matcher.d.ts +3 -1
- package/build/types/index.js.map +1 -1
- package/build/utils/boxShadowValueParser.js.map +2 -2
- package/build/utils/color-lib-utils.js +26 -50
- package/build/utils/color-lib-utils.js.map +2 -2
- package/build/utils/css-utils.js.map +2 -2
- package/build/utils/custom-mapping-utils.js +62 -0
- package/build/utils/custom-mapping-utils.js.map +7 -0
- package/build/utils/hardcoded-shared-utils.js +29 -16
- package/build/utils/hardcoded-shared-utils.js.map +2 -2
- package/build/utils/property-matcher.js +20 -6
- package/build/utils/property-matcher.js.map +2 -2
- package/package.json +2 -2
|
@@ -67,11 +67,7 @@ function isCssColorFunction(value) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
// src/utils/color-lib-utils.ts
|
|
70
|
-
var
|
|
71
|
-
var isHexCode = (color) => {
|
|
72
|
-
const hexPattern = /^#(?:[0-9a-fA-F]{3}){1,2}$/;
|
|
73
|
-
return hexPattern.test(color);
|
|
74
|
-
};
|
|
70
|
+
var DELTAE_THRESHOLD = 10;
|
|
75
71
|
var convertToHex = (color) => {
|
|
76
72
|
try {
|
|
77
73
|
return (0, import_chroma_js.default)(color).hex();
|
|
@@ -79,52 +75,40 @@ var convertToHex = (color) => {
|
|
|
79
75
|
return null;
|
|
80
76
|
}
|
|
81
77
|
};
|
|
78
|
+
var isHookPropertyMatch = (hook, cssProperty) => {
|
|
79
|
+
return hook.properties.includes(cssProperty) || hook.properties.includes("*");
|
|
80
|
+
};
|
|
81
|
+
function getOrderByCssProp(cssProperty) {
|
|
82
|
+
if (cssProperty === "color" || cssProperty === "fill") {
|
|
83
|
+
return ["surface", "theme", "feedback", "reference"];
|
|
84
|
+
} else if (cssProperty.match(/background/)) {
|
|
85
|
+
return ["surface", "surface-inverse", "theme", "feedback", "reference"];
|
|
86
|
+
} else if (cssProperty.match(/border/) || cssProperty.match(/outline/) || cssProperty.match(/stroke/)) {
|
|
87
|
+
return ["borders", "borders-inverse", "feedback", "theme", "reference"];
|
|
88
|
+
}
|
|
89
|
+
return ["surface", "surface-inverse", "borders", "borders-inverse", "theme", "feedback", "reference"];
|
|
90
|
+
}
|
|
82
91
|
var findClosestColorHook = (color, supportedColors, cssProperty) => {
|
|
83
|
-
const
|
|
84
|
-
const closestHooksWithSameProperty = [];
|
|
85
|
-
const closestHooksWithoutSameProperty = [];
|
|
86
|
-
const closestHooksWithAllProperty = [];
|
|
87
|
-
const labColor = (0, import_chroma_js.default)(color).lab();
|
|
92
|
+
const closestHooks = [];
|
|
88
93
|
Object.entries(supportedColors).forEach(([sldsValue, data]) => {
|
|
89
|
-
if (sldsValue &&
|
|
94
|
+
if (sldsValue && isValidColor(sldsValue)) {
|
|
90
95
|
const hooks = data;
|
|
91
96
|
hooks.forEach((hook) => {
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (distance <= LAB_THRESHOLD) {
|
|
96
|
-
closestHooksWithSameProperty.push({ name: hook.name, distance });
|
|
97
|
-
}
|
|
98
|
-
} else if (hook.properties.includes("*")) {
|
|
99
|
-
if (distance <= LAB_THRESHOLD) {
|
|
100
|
-
closestHooksWithAllProperty.push({ name: hook.name, distance });
|
|
101
|
-
}
|
|
102
|
-
} else {
|
|
103
|
-
if (distance <= LAB_THRESHOLD) {
|
|
104
|
-
closestHooksWithoutSameProperty.push({ name: hook.name, distance });
|
|
105
|
-
}
|
|
97
|
+
const distance = sldsValue.toLowerCase() === color.toLowerCase() ? 0 : import_chroma_js.default.deltaE(sldsValue, color);
|
|
98
|
+
if (isHookPropertyMatch(hook, cssProperty) && distance <= DELTAE_THRESHOLD) {
|
|
99
|
+
closestHooks.push({ distance, group: hook.group, name: hook.name });
|
|
106
100
|
}
|
|
107
101
|
});
|
|
108
102
|
}
|
|
109
103
|
});
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
{ hooks: closestHooksWithSameProperty, distance: Infinity },
|
|
114
|
-
// For hooks with distance > 0
|
|
115
|
-
{ hooks: closestHooksWithAllProperty, distance: Infinity },
|
|
116
|
-
{ hooks: closestHooksWithoutSameProperty, distance: Infinity }
|
|
117
|
-
];
|
|
118
|
-
for (const group of closesthookGroups) {
|
|
119
|
-
const filteredHooks = group.hooks.filter(
|
|
120
|
-
(h) => group.distance === 0 ? h.distance === 0 : h.distance > 0
|
|
121
|
-
);
|
|
122
|
-
if (returnStylingHooks.length < 1 && filteredHooks.length > 0) {
|
|
123
|
-
filteredHooks.sort((a, b) => a.distance - b.distance);
|
|
124
|
-
returnStylingHooks.push(...filteredHooks.slice(0, 5).map((h) => h.name));
|
|
104
|
+
const hooksByGroupMap = closestHooks.sort((a, b) => a.distance - b.distance).reduce((acc, hook) => {
|
|
105
|
+
if (!acc[hook.group]) {
|
|
106
|
+
acc[hook.group] = [];
|
|
125
107
|
}
|
|
126
|
-
|
|
127
|
-
|
|
108
|
+
acc[hook.group].push(hook.name);
|
|
109
|
+
return acc;
|
|
110
|
+
}, {});
|
|
111
|
+
return getOrderByCssProp(cssProperty).map((group) => hooksByGroupMap[group] || []).flat().slice(0, 5);
|
|
128
112
|
};
|
|
129
113
|
var isValidColor = (val) => import_chroma_js.default.valid(val);
|
|
130
114
|
var extractColorValue = (node) => {
|
|
@@ -223,9 +207,9 @@ function toSelector(properties) {
|
|
|
223
207
|
});
|
|
224
208
|
return selectorParts.join(", ");
|
|
225
209
|
}
|
|
226
|
-
function
|
|
210
|
+
function resolveDensityPropertyToMatch(cssProperty) {
|
|
227
211
|
const propertyToMatch = cssProperty.toLowerCase();
|
|
228
|
-
if (propertyToMatch
|
|
212
|
+
if (isOutlineWidthProperty(propertyToMatch) || isBorderWidthProperty(propertyToMatch)) {
|
|
229
213
|
return "border-width";
|
|
230
214
|
} else if (isMarginProperty(propertyToMatch)) {
|
|
231
215
|
return "margin";
|
|
@@ -237,13 +221,23 @@ function resolvePropertyToMatch(cssProperty) {
|
|
|
237
221
|
return "width";
|
|
238
222
|
} else if (isInsetProperty(propertyToMatch)) {
|
|
239
223
|
return "top";
|
|
240
|
-
}
|
|
224
|
+
}
|
|
225
|
+
return propertyToMatch;
|
|
226
|
+
}
|
|
227
|
+
function resolveColorPropertyToMatch(cssProperty) {
|
|
228
|
+
const propertyToMatch = cssProperty.toLowerCase();
|
|
229
|
+
if (propertyToMatch === "outline" || propertyToMatch === "outline-color") {
|
|
230
|
+
return "border-color";
|
|
231
|
+
} else if (propertyToMatch === "background" || propertyToMatch === "background-color") {
|
|
241
232
|
return "background-color";
|
|
242
|
-
} else if (
|
|
233
|
+
} else if (isBorderColorProperty(propertyToMatch)) {
|
|
243
234
|
return "border-color";
|
|
244
235
|
}
|
|
245
236
|
return propertyToMatch;
|
|
246
237
|
}
|
|
238
|
+
function isOutlineWidthProperty(propertyToMatch) {
|
|
239
|
+
return propertyToMatch === "outline" || propertyToMatch === "outline-width";
|
|
240
|
+
}
|
|
247
241
|
|
|
248
242
|
// src/utils/hardcoded-shared-utils.ts
|
|
249
243
|
var import_css_tree2 = require("@eslint/css-tree");
|
|
@@ -303,13 +297,33 @@ function isKnownFontWeight(value) {
|
|
|
303
297
|
return FONT_WEIGHTS.includes(stringValue.toLowerCase());
|
|
304
298
|
}
|
|
305
299
|
function handleShorthandAutoFix(declarationNode, context, valueText, replacements) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
sortedReplacements.
|
|
300
|
+
if (!replacements || replacements.length === 0) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const sortedReplacements = replacements.sort((a, b) => b.start - a.start);
|
|
304
|
+
const reportNumericValue = context.options?.reportNumericValue || "always";
|
|
305
|
+
const fixCallback = (start, originalValue, replacement) => {
|
|
306
|
+
let newValue = valueText;
|
|
307
|
+
newValue = newValue.substring(0, start) + replacement + newValue.substring(start + originalValue.length);
|
|
308
|
+
if (newValue !== valueText) {
|
|
309
|
+
return (fixer) => {
|
|
310
|
+
return fixer.replaceText(declarationNode.value, newValue);
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
sortedReplacements.forEach(({ start, end, replacement, displayValue, hasHook, isNumeric }) => {
|
|
310
315
|
const originalValue = valueText.substring(start, end);
|
|
311
|
-
|
|
312
|
-
|
|
316
|
+
if (isNumeric) {
|
|
317
|
+
if (reportNumericValue === "never") {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
if (reportNumericValue === "hasReplacement" && !hasHook) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
const valueColumnStart = declarationNode.value.loc.start.column + start;
|
|
325
|
+
const valueColumnEnd = valueColumnStart + originalValue.length;
|
|
326
|
+
const canAutoFix = originalValue !== replacement;
|
|
313
327
|
const { loc: { start: locStart, end: locEnd } } = declarationNode.value;
|
|
314
328
|
const reportNode = {
|
|
315
329
|
...declarationNode.value,
|
|
@@ -317,23 +331,16 @@ function handleShorthandAutoFix(declarationNode, context, valueText, replacement
|
|
|
317
331
|
...declarationNode.value.loc,
|
|
318
332
|
start: {
|
|
319
333
|
...locStart,
|
|
320
|
-
column:
|
|
334
|
+
column: valueColumnStart
|
|
321
335
|
},
|
|
322
336
|
end: {
|
|
323
337
|
...locEnd,
|
|
324
|
-
column:
|
|
338
|
+
column: valueColumnEnd
|
|
325
339
|
}
|
|
326
340
|
}
|
|
327
341
|
};
|
|
328
342
|
if (hasHook) {
|
|
329
|
-
const fix = canAutoFix ? (
|
|
330
|
-
let newValue = valueText;
|
|
331
|
-
for (let i = sortedReplacements.length - 1; i >= 0; i--) {
|
|
332
|
-
const { start: rStart, end: rEnd, replacement: rReplacement } = sortedReplacements[i];
|
|
333
|
-
newValue = newValue.substring(0, rStart) + rReplacement + newValue.substring(rEnd);
|
|
334
|
-
}
|
|
335
|
-
return fixer.replaceText(declarationNode.value, newValue);
|
|
336
|
-
} : void 0;
|
|
343
|
+
const fix = canAutoFix ? fixCallback(start, originalValue, replacement) : void 0;
|
|
337
344
|
context.context.report({
|
|
338
345
|
node: reportNode,
|
|
339
346
|
messageId: "hardcodedValue",
|
|
@@ -487,6 +494,41 @@ function formatSuggestionHooks(hooks) {
|
|
|
487
494
|
return "\n" + hooks.map((hook, index) => `${index + 1}. ${hook}`).join("\n");
|
|
488
495
|
}
|
|
489
496
|
|
|
497
|
+
// src/utils/custom-mapping-utils.ts
|
|
498
|
+
function matchesPropertyPattern(cssProperty, pattern) {
|
|
499
|
+
const normalizedProperty = cssProperty.toLowerCase();
|
|
500
|
+
const normalizedPattern = pattern.toLowerCase();
|
|
501
|
+
if (normalizedProperty === normalizedPattern) {
|
|
502
|
+
return true;
|
|
503
|
+
}
|
|
504
|
+
if (normalizedPattern.endsWith("*")) {
|
|
505
|
+
const prefix = normalizedPattern.slice(0, -1);
|
|
506
|
+
return normalizedProperty.startsWith(prefix);
|
|
507
|
+
}
|
|
508
|
+
return false;
|
|
509
|
+
}
|
|
510
|
+
function getCustomMapping(cssProperty, value, customMapping) {
|
|
511
|
+
if (!customMapping) {
|
|
512
|
+
return null;
|
|
513
|
+
}
|
|
514
|
+
const normalizedValue = value.toLowerCase().trim();
|
|
515
|
+
for (const [hookName, config] of Object.entries(customMapping)) {
|
|
516
|
+
const propertyMatches = config.properties.some(
|
|
517
|
+
(pattern) => matchesPropertyPattern(cssProperty, pattern)
|
|
518
|
+
);
|
|
519
|
+
if (!propertyMatches) {
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
const valueMatches = config.values.some(
|
|
523
|
+
(configValue) => configValue.toLowerCase().trim() === normalizedValue
|
|
524
|
+
);
|
|
525
|
+
if (valueMatches) {
|
|
526
|
+
return hookName;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
return null;
|
|
530
|
+
}
|
|
531
|
+
|
|
490
532
|
// src/rules/v9/no-hardcoded-values/handlers/colorHandler.ts
|
|
491
533
|
var handleColorDeclaration = (node, context) => {
|
|
492
534
|
const cssProperty = node.property.toLowerCase();
|
|
@@ -510,24 +552,32 @@ function createColorReplacement(colorValue, cssProperty, context, positionInfo,
|
|
|
510
552
|
if (!hexValue) {
|
|
511
553
|
return null;
|
|
512
554
|
}
|
|
513
|
-
const propToMatch = resolvePropertyToMatch(cssProperty);
|
|
514
|
-
const closestHooks = findClosestColorHook(hexValue, context.valueToStylinghook, propToMatch);
|
|
515
555
|
const start = positionInfo.start.offset;
|
|
516
556
|
const end = positionInfo.end.offset;
|
|
517
557
|
const originalValue = originalValueText ? originalValueText.substring(start, end) : colorValue;
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
558
|
+
const customHook = getCustomMapping(cssProperty, colorValue, context.options?.customMapping);
|
|
559
|
+
let closestHooks = [];
|
|
560
|
+
if (customHook) {
|
|
561
|
+
closestHooks = [customHook];
|
|
562
|
+
} else {
|
|
563
|
+
const propToMatch = resolveColorPropertyToMatch(cssProperty);
|
|
564
|
+
closestHooks = findClosestColorHook(hexValue, context.valueToStylinghook, propToMatch);
|
|
565
|
+
}
|
|
566
|
+
let replacement = originalValue;
|
|
567
|
+
let paletteHook = null;
|
|
568
|
+
if (context.options?.preferPaletteHook && closestHooks.length > 1) {
|
|
569
|
+
paletteHook = closestHooks.filter((hook) => hook.includes("-palette-"))[0];
|
|
570
|
+
}
|
|
571
|
+
if (paletteHook) {
|
|
572
|
+
replacement = `var(${paletteHook}, ${colorValue})`;
|
|
573
|
+
} else if (closestHooks.length === 1) {
|
|
574
|
+
replacement = `var(${closestHooks[0]}, ${colorValue})`;
|
|
575
|
+
}
|
|
576
|
+
if (closestHooks.length > 0) {
|
|
527
577
|
return {
|
|
528
578
|
start,
|
|
529
579
|
end,
|
|
530
|
-
replacement
|
|
580
|
+
replacement,
|
|
531
581
|
// Use original value to preserve spacing
|
|
532
582
|
displayValue: formatSuggestionHooks(closestHooks),
|
|
533
583
|
hasHook: true
|
|
@@ -536,7 +586,7 @@ function createColorReplacement(colorValue, cssProperty, context, positionInfo,
|
|
|
536
586
|
return {
|
|
537
587
|
start,
|
|
538
588
|
end,
|
|
539
|
-
replacement
|
|
589
|
+
replacement,
|
|
540
590
|
// Use original value to preserve spacing
|
|
541
591
|
displayValue: originalValue,
|
|
542
592
|
hasHook: false
|
|
@@ -584,8 +634,14 @@ function createDimensionReplacement(parsedDimension, cssProperty, context, posit
|
|
|
584
634
|
return null;
|
|
585
635
|
}
|
|
586
636
|
const rawValue = parsedDimension.unit ? `${parsedDimension.number}${parsedDimension.unit}` : parsedDimension.number.toString();
|
|
587
|
-
const
|
|
588
|
-
|
|
637
|
+
const customHook = getCustomMapping(cssProperty, rawValue, context.options?.customMapping);
|
|
638
|
+
let closestHooks = [];
|
|
639
|
+
if (customHook) {
|
|
640
|
+
closestHooks = [customHook];
|
|
641
|
+
} else {
|
|
642
|
+
const propToMatch = resolveDensityPropertyToMatch(cssProperty);
|
|
643
|
+
closestHooks = getStylingHooksForDensityValue(parsedDimension, context.valueToStylinghook, propToMatch);
|
|
644
|
+
}
|
|
589
645
|
const start = positionInfo.start.offset;
|
|
590
646
|
const end = positionInfo.end.offset;
|
|
591
647
|
if (closestHooks.length === 1) {
|
|
@@ -594,7 +650,8 @@ function createDimensionReplacement(parsedDimension, cssProperty, context, posit
|
|
|
594
650
|
end,
|
|
595
651
|
replacement: `var(${closestHooks[0]}, ${rawValue})`,
|
|
596
652
|
displayValue: closestHooks[0],
|
|
597
|
-
hasHook: true
|
|
653
|
+
hasHook: true,
|
|
654
|
+
isNumeric: true
|
|
598
655
|
};
|
|
599
656
|
} else if (closestHooks.length > 1) {
|
|
600
657
|
return {
|
|
@@ -602,7 +659,8 @@ function createDimensionReplacement(parsedDimension, cssProperty, context, posit
|
|
|
602
659
|
end,
|
|
603
660
|
replacement: rawValue,
|
|
604
661
|
displayValue: formatSuggestionHooks(closestHooks),
|
|
605
|
-
hasHook: true
|
|
662
|
+
hasHook: true,
|
|
663
|
+
isNumeric: true
|
|
606
664
|
};
|
|
607
665
|
} else {
|
|
608
666
|
return {
|
|
@@ -610,7 +668,8 @@ function createDimensionReplacement(parsedDimension, cssProperty, context, posit
|
|
|
610
668
|
end,
|
|
611
669
|
replacement: rawValue,
|
|
612
670
|
displayValue: rawValue,
|
|
613
|
-
hasHook: false
|
|
671
|
+
hasHook: false,
|
|
672
|
+
isNumeric: true
|
|
614
673
|
};
|
|
615
674
|
}
|
|
616
675
|
}
|
|
@@ -651,8 +710,14 @@ function createFontReplacement(fontValue, cssProperty, context, positionInfo) {
|
|
|
651
710
|
return null;
|
|
652
711
|
}
|
|
653
712
|
const rawValue = fontValue.unit ? `${fontValue.number}${fontValue.unit}` : fontValue.number.toString();
|
|
654
|
-
const propToMatch = !fontValue.unit && isKnownFontWeight(fontValue.number) ?
|
|
655
|
-
const
|
|
713
|
+
const propToMatch = !fontValue.unit && isKnownFontWeight(fontValue.number) ? "font-weight" : "font-size";
|
|
714
|
+
const customHook = getCustomMapping(propToMatch, rawValue, context.options?.customMapping);
|
|
715
|
+
let closestHooks = [];
|
|
716
|
+
if (customHook) {
|
|
717
|
+
closestHooks = [customHook];
|
|
718
|
+
} else {
|
|
719
|
+
closestHooks = getStylingHooksForDensityValue(fontValue, context.valueToStylinghook, propToMatch);
|
|
720
|
+
}
|
|
656
721
|
const start = positionInfo.start.offset;
|
|
657
722
|
const end = positionInfo.end.offset;
|
|
658
723
|
if (closestHooks.length === 1) {
|
|
@@ -661,7 +726,8 @@ function createFontReplacement(fontValue, cssProperty, context, positionInfo) {
|
|
|
661
726
|
end,
|
|
662
727
|
replacement: `var(${closestHooks[0]}, ${rawValue})`,
|
|
663
728
|
displayValue: closestHooks[0],
|
|
664
|
-
hasHook: true
|
|
729
|
+
hasHook: true,
|
|
730
|
+
isNumeric: true
|
|
665
731
|
};
|
|
666
732
|
} else if (closestHooks.length > 1) {
|
|
667
733
|
return {
|
|
@@ -669,7 +735,8 @@ function createFontReplacement(fontValue, cssProperty, context, positionInfo) {
|
|
|
669
735
|
end,
|
|
670
736
|
replacement: rawValue,
|
|
671
737
|
displayValue: formatSuggestionHooks(closestHooks),
|
|
672
|
-
hasHook: true
|
|
738
|
+
hasHook: true,
|
|
739
|
+
isNumeric: true
|
|
673
740
|
};
|
|
674
741
|
} else {
|
|
675
742
|
return {
|
|
@@ -677,7 +744,8 @@ function createFontReplacement(fontValue, cssProperty, context, positionInfo) {
|
|
|
677
744
|
end,
|
|
678
745
|
replacement: rawValue,
|
|
679
746
|
displayValue: rawValue,
|
|
680
|
-
hasHook: false
|
|
747
|
+
hasHook: false,
|
|
748
|
+
isNumeric: true
|
|
681
749
|
};
|
|
682
750
|
}
|
|
683
751
|
}
|
|
@@ -809,9 +877,30 @@ function shadowValueToHookEntries(supportedStylinghooks) {
|
|
|
809
877
|
return [key, value.map((hook) => hook.name)];
|
|
810
878
|
});
|
|
811
879
|
}
|
|
880
|
+
function reportBoxShadowViolation(node, context, valueText, hooks) {
|
|
881
|
+
const positionInfo = {
|
|
882
|
+
start: { offset: 0, line: 1, column: 1 },
|
|
883
|
+
end: { offset: valueText.length, line: 1, column: valueText.length + 1 }
|
|
884
|
+
};
|
|
885
|
+
const replacement = createBoxShadowReplacement(
|
|
886
|
+
valueText,
|
|
887
|
+
hooks,
|
|
888
|
+
context,
|
|
889
|
+
positionInfo
|
|
890
|
+
);
|
|
891
|
+
if (replacement) {
|
|
892
|
+
const replacements = [replacement];
|
|
893
|
+
handleShorthandAutoFix(node, context, valueText, replacements);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
812
896
|
var handleBoxShadowDeclaration = (node, context) => {
|
|
813
897
|
const cssProperty = node.property.toLowerCase();
|
|
814
898
|
const valueText = context.sourceCode.getText(node.value);
|
|
899
|
+
const customHook = getCustomMapping(cssProperty, valueText, context.options?.customMapping);
|
|
900
|
+
if (customHook) {
|
|
901
|
+
reportBoxShadowViolation(node, context, valueText, [customHook]);
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
815
904
|
const shadowHooks = shadowValueToHookEntries(context.valueToStylinghook);
|
|
816
905
|
const parsedCssValue = toBoxShadowValue(valueText);
|
|
817
906
|
if (!parsedCssValue) {
|
|
@@ -821,20 +910,7 @@ var handleBoxShadowDeclaration = (node, context) => {
|
|
|
821
910
|
const parsedValueHook = toBoxShadowValue(shadow);
|
|
822
911
|
if (parsedValueHook && isBoxShadowMatch(parsedCssValue, parsedValueHook)) {
|
|
823
912
|
if (closestHooks.length > 0) {
|
|
824
|
-
|
|
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
|
-
}
|
|
913
|
+
reportBoxShadowViolation(node, context, valueText, closestHooks);
|
|
838
914
|
}
|
|
839
915
|
return;
|
|
840
916
|
}
|
|
@@ -884,6 +960,42 @@ function isRuleEnabled(context, ruleName) {
|
|
|
884
960
|
}
|
|
885
961
|
}
|
|
886
962
|
|
|
963
|
+
// src/rules/v9/no-hardcoded-values/ruleOptionsSchema.ts
|
|
964
|
+
var ruleOptionsSchema = [
|
|
965
|
+
{
|
|
966
|
+
type: "object",
|
|
967
|
+
properties: {
|
|
968
|
+
reportNumericValue: {
|
|
969
|
+
type: "string",
|
|
970
|
+
enum: ["never", "always", "hasReplacement"],
|
|
971
|
+
default: "always"
|
|
972
|
+
},
|
|
973
|
+
customMapping: {
|
|
974
|
+
type: "object",
|
|
975
|
+
additionalProperties: {
|
|
976
|
+
type: "object",
|
|
977
|
+
properties: {
|
|
978
|
+
properties: {
|
|
979
|
+
type: "array",
|
|
980
|
+
items: { type: "string" }
|
|
981
|
+
},
|
|
982
|
+
values: {
|
|
983
|
+
type: "array",
|
|
984
|
+
items: { type: "string" }
|
|
985
|
+
}
|
|
986
|
+
},
|
|
987
|
+
required: ["properties", "values"]
|
|
988
|
+
}
|
|
989
|
+
},
|
|
990
|
+
preferPaletteHook: {
|
|
991
|
+
type: "boolean",
|
|
992
|
+
default: false
|
|
993
|
+
}
|
|
994
|
+
},
|
|
995
|
+
additionalProperties: false
|
|
996
|
+
}
|
|
997
|
+
];
|
|
998
|
+
|
|
887
999
|
// src/rules/v9/no-hardcoded-values/noHardcodedValueRule.ts
|
|
888
1000
|
function defineNoHardcodedValueRule(config) {
|
|
889
1001
|
const { ruleConfig, ruleName } = config;
|
|
@@ -897,16 +1009,24 @@ function defineNoHardcodedValueRule(config) {
|
|
|
897
1009
|
url
|
|
898
1010
|
},
|
|
899
1011
|
fixable: "code",
|
|
900
|
-
messages
|
|
1012
|
+
messages,
|
|
1013
|
+
schema: ruleOptionsSchema
|
|
901
1014
|
},
|
|
902
1015
|
create(context) {
|
|
903
1016
|
if (ruleName === "no-hardcoded-values-slds1" && isRuleEnabled(context, "@salesforce-ux/slds/no-hardcoded-values-slds2")) {
|
|
904
1017
|
return {};
|
|
905
1018
|
}
|
|
1019
|
+
const options = context.options[0] || {};
|
|
1020
|
+
const ruleOptions = {
|
|
1021
|
+
reportNumericValue: options.reportNumericValue || "always",
|
|
1022
|
+
customMapping: options.customMapping || {},
|
|
1023
|
+
preferPaletteHook: options.preferPaletteHook || false
|
|
1024
|
+
};
|
|
906
1025
|
const handlerContext = {
|
|
907
1026
|
valueToStylinghook: config.valueToStylinghook,
|
|
908
1027
|
context,
|
|
909
|
-
sourceCode: context.sourceCode
|
|
1028
|
+
sourceCode: context.sourceCode,
|
|
1029
|
+
options: ruleOptions
|
|
910
1030
|
};
|
|
911
1031
|
const colorOnlySelector = toSelector(colorProperties);
|
|
912
1032
|
const densityOnlySelector = toSelector(densificationProperties);
|