@salesforce-ux/eslint-plugin-slds 0.0.6 → 0.0.8

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.
@@ -2,6 +2,7 @@ root: true
2
2
  env:
3
3
  es2021: true
4
4
  node: true
5
+ parser: "@html-eslint/parser" # ✅ Ensure we are using the correct parser
5
6
  parserOptions:
6
7
  ecmaVersion: 2021
7
8
  sourceType: module
@@ -11,21 +12,11 @@ overrides:
11
12
  - files:
12
13
  - "*.html"
13
14
  - "*.cmp"
14
- parser: "@html-eslint/parser"
15
+ parser: "@html-eslint/parser" # ✅ Enforce HTML parser only for these files
15
16
  plugins:
17
+ - "@html-eslint"
16
18
  - "@salesforce-ux/slds"
17
19
  rules:
18
- "@salesforce-ux/slds/no-bem-class":
19
- - "error"
20
- "@salesforce-ux/slds/no-deprecated-slds-classes":
21
- - "error"
22
-
23
- - files:
24
- - "*.js"
25
- - "*.json"
26
- excludedFiles: "*.js"
27
- rules:
28
- "@salesforce-ux/slds/no-bem-class":
29
- - "error"
30
- "@salesforce-ux/slds/no-deprecated-slds-classes":
31
- - "error"
20
+ "@salesforce-ux/slds/enforce-bem-class": "error"
21
+ "@salesforce-ux/slds/no-deprecated-slds-classes": "error"
22
+ "@salesforce-ux/slds/modal-close-button-issue": "error"
package/build/index.js CHANGED
@@ -3407,18 +3407,18 @@ function requireNode () {
3407
3407
  return node;
3408
3408
  }
3409
3409
 
3410
- var noBemClass;
3411
- var hasRequiredNoBemClass;
3410
+ var enforceBemClass;
3411
+ var hasRequiredEnforceBemClass;
3412
3412
 
3413
- function requireNoBemClass () {
3414
- if (hasRequiredNoBemClass) return noBemClass;
3415
- hasRequiredNoBemClass = 1;
3413
+ function requireEnforceBemClass () {
3414
+ if (hasRequiredEnforceBemClass) return enforceBemClass;
3415
+ hasRequiredEnforceBemClass = 1;
3416
3416
  const {
3417
3417
  findAttr,
3418
3418
  isAttributesEmpty
3419
3419
  } = requireNode();
3420
3420
 
3421
- noBemClass = {
3421
+ enforceBemClass = {
3422
3422
  meta: {
3423
3423
  type: "problem", // The rule type
3424
3424
  docs: {
@@ -3494,7 +3494,7 @@ function requireNoBemClass () {
3494
3494
  };
3495
3495
  },
3496
3496
  };
3497
- return noBemClass;
3497
+ return enforceBemClass;
3498
3498
  }
3499
3499
 
3500
3500
  var noDeprecatedSldsClasses;
@@ -3592,6 +3592,171 @@ function requireNoDeprecatedSldsClasses () {
3592
3592
  return noDeprecatedSldsClasses;
3593
3593
  }
3594
3594
 
3595
+ var modalCloseButtonIssue;
3596
+ var hasRequiredModalCloseButtonIssue;
3597
+
3598
+ function requireModalCloseButtonIssue () {
3599
+ if (hasRequiredModalCloseButtonIssue) return modalCloseButtonIssue;
3600
+ hasRequiredModalCloseButtonIssue = 1;
3601
+ const { findAttr, isAttributesEmpty } = requireNode();
3602
+
3603
+ // This rule specific to CVS, find more details here https://issues.salesforce.com/issue/a028c00000zh1iqAAA/modal-close-button-is-not-visible-with-the-new-white-background-after-winter-25-release
3604
+ modalCloseButtonIssue = {
3605
+ meta: {
3606
+ type: "problem",
3607
+ docs: {
3608
+ description:
3609
+ "Ensure SLDS modal compliance by enforcing correct button and icon attributes.",
3610
+ category: "Best Practices",
3611
+ recommended: true,
3612
+ },
3613
+ fixable: "code",
3614
+ schema: [],
3615
+ messages: {
3616
+ removeClass:
3617
+ "Remove the class 'slds-button_icon-inverse' from SLDS Modal blueprints.",
3618
+ changeVariant:
3619
+ "Change 'variant' attribute from 'bare-inverse' to 'bare' in <lightning-button-icon> or <lightning-icon>.",
3620
+ removeVariant:
3621
+ "Remove 'variant' attribute completely in <lightning-icon> inside <button>.",
3622
+ ensureButtonClasses:
3623
+ "Ensure 'slds-button' and 'slds-button_icon' are in the class attribute of <button> or <lightning-button-icon>.",
3624
+ ensureSizeAttribute:
3625
+ "Ensure 'size' attribute is set to 'large' in <lightning-icon> or <lightning-button-icon> for correct icon sizing.",
3626
+ },
3627
+ },
3628
+
3629
+ create(context) {
3630
+ function check(node) {
3631
+ if (isAttributesEmpty(node)) {
3632
+ return;
3633
+ }
3634
+
3635
+ const tagName = node.name;
3636
+
3637
+ // ✅ Scenario 1: Remove 'slds-button_icon-inverse' from <button>
3638
+ if (tagName === "button") {
3639
+ const classAttr = findAttr(node, "class");
3640
+ if (classAttr && classAttr.value) {
3641
+ const classList = classAttr.value.value.split(/\s+/);
3642
+ if (classList.includes("slds-button_icon-inverse")) {
3643
+ context.report({
3644
+ node,
3645
+ messageId: "removeClass",
3646
+ fix(fixer) {
3647
+ const newClassList = classList
3648
+ .filter((cls) => cls !== "slds-button_icon-inverse")
3649
+ .join(" ");
3650
+ return fixer.replaceText(
3651
+ classAttr, // Replace the full attribute
3652
+ `class="${newClassList}"` // Updated class list
3653
+ );
3654
+ },
3655
+ });
3656
+ }
3657
+ }
3658
+ }
3659
+
3660
+ // ✅ Scenario 2: Fix <lightning-button-icon>
3661
+ if (tagName === "lightning-button-icon" || tagName === "lightning:buttonIcon") {
3662
+ const variantAttr = findAttr(node, "variant");
3663
+ const sizeAttr = findAttr(node, "size");
3664
+ const classAttr = findAttr(node, "class");
3665
+
3666
+ // Fix variant="bare-inverse" to "bare"
3667
+ if (variantAttr && variantAttr.value && variantAttr.value.value === "bare-inverse") {
3668
+ context.report({
3669
+ node: variantAttr,
3670
+ messageId: "changeVariant",
3671
+ fix(fixer) {
3672
+ return fixer.replaceText(variantAttr.value, `bare`);
3673
+ },
3674
+ });
3675
+ }
3676
+
3677
+ // Ensure size="large" exists
3678
+ if (!sizeAttr) {
3679
+ context.report({
3680
+ node,
3681
+ messageId: "ensureSizeAttribute",
3682
+ fix(fixer) {
3683
+ //return fixer.insertTextAfter(node, ' size="large"');
3684
+ return fixer.insertTextAfterRange([variantAttr.range[1], variantAttr.range[1]], ' size="large"')
3685
+ },
3686
+ });
3687
+ }
3688
+
3689
+ // Ensure 'slds-button' and 'slds-button_icon' are in the class attribute
3690
+ if (classAttr && classAttr.value) {
3691
+ const classList = classAttr.value.value.split(/\s+/);
3692
+ if (!classList.includes("slds-button") || !classList.includes("slds-button_icon")) {
3693
+ context.report({
3694
+ node: classAttr,
3695
+ messageId: "ensureButtonClasses",
3696
+ fix(fixer) {
3697
+ const newClassList = [
3698
+ "slds-button",
3699
+ "slds-button_icon",
3700
+ ...classList.filter(
3701
+ (cls) => cls !== "slds-button_icon-inverse"
3702
+ ),
3703
+ ].join(" ");
3704
+ return fixer.replaceText(classAttr.value, `"${newClassList}"`);
3705
+ },
3706
+ });
3707
+ }
3708
+ }
3709
+ }
3710
+
3711
+ // ✅ Scenario 3: Fix <lightning-icon> inside <button>
3712
+ if ((tagName === "lightning-icon" || tagName === "lightning:icon") && node.parent?.name === "button") {
3713
+ const variantAttr = findAttr(node, "variant");
3714
+ const sizeAttr = findAttr(node, "size");
3715
+
3716
+ // Fix variant="bare-inverse" to "bare"
3717
+ if (variantAttr && variantAttr.value && variantAttr.value.value === "bare-inverse") {
3718
+ context.report({
3719
+ node: variantAttr,
3720
+ messageId: "changeVariant",
3721
+ fix(fixer) {
3722
+ return fixer.replaceText(variantAttr.value, `"bare"`);
3723
+ },
3724
+ });
3725
+ }
3726
+
3727
+ // Remove variant attribute completely
3728
+ if (variantAttr) {
3729
+ context.report({
3730
+ node: variantAttr,
3731
+ messageId: "removeVariant",
3732
+ fix(fixer) {
3733
+ return fixer.remove(variantAttr);
3734
+ },
3735
+ });
3736
+ }
3737
+
3738
+ //Ensure size="large" is set
3739
+ if (!sizeAttr) {
3740
+ context.report({
3741
+ node,
3742
+ messageId: "ensureSizeAttribute",
3743
+ fix(fixer) {
3744
+ //return fixer.insertTextAfter(node, ' size="large"');
3745
+ return fixer.insertTextAfterRange([variantAttr.range[1], variantAttr.range[1]], ' size="large"')
3746
+ },
3747
+ });
3748
+ }
3749
+ }
3750
+ }
3751
+
3752
+ return {
3753
+ Tag: check,
3754
+ };
3755
+ },
3756
+ };
3757
+ return modalCloseButtonIssue;
3758
+ }
3759
+
3595
3760
  var src;
3596
3761
  var hasRequiredSrc;
3597
3762
 
@@ -3600,16 +3765,18 @@ function requireSrc () {
3600
3765
  hasRequiredSrc = 1;
3601
3766
  src = {
3602
3767
  rules: {
3603
- "no-bem-class": requireNoBemClass(),
3604
- "no-deprecated-slds-classes": requireNoDeprecatedSldsClasses()
3768
+ "enforce-bem-class": requireEnforceBemClass(),
3769
+ "no-deprecated-slds-classes": requireNoDeprecatedSldsClasses(),
3770
+ "modal-close-button-issue": requireModalCloseButtonIssue()
3605
3771
  },
3606
3772
  configs: {
3607
3773
  recommended: {
3608
3774
  parser: "@html-eslint/parser", // Use HTML parser
3609
3775
  plugins: ["slds"],
3610
3776
  rules: {
3611
- "slds/no-bem-class": "error",
3612
- "slds/no-deprecated-slds-classes": "error"
3777
+ "slds/enforce-bem-class": "error",
3778
+ "slds/no-deprecated-slds-classes": "error",
3779
+ "slds/modal-close-button-issue": "error"
3613
3780
  },
3614
3781
  },
3615
3782
  },