1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-10 13:40:06 +00:00

add custom eslint warning

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Will Martin
2026-01-26 19:40:50 -05:00
parent 15b72c6b7c
commit 9c6da2bdb6
4 changed files with 82 additions and 0 deletions

View File

@@ -207,6 +207,7 @@ export default tseslint.config(
"error",
{ ignoreIfHas: ["bitPasswordInputToggle"] },
],
"@bitwarden/components/no-bwi-class-usage": "warn",
},
},

View File

@@ -1,9 +1,11 @@
import requireLabelOnBiticonbutton from "./require-label-on-biticonbutton.mjs";
import requireThemeColorsInSvg from "./require-theme-colors-in-svg.mjs";
import noBwiClassUsage from "./no-bwi-class-usage.mjs";
export default {
rules: {
"require-label-on-biticonbutton": requireLabelOnBiticonbutton,
"require-theme-colors-in-svg": requireThemeColorsInSvg,
"no-bwi-class-usage": noBwiClassUsage,
},
};

View File

@@ -0,0 +1,45 @@
export const errorMessage =
"Use <bit-icon> component instead of applying 'bwi' classes directly. Example: <bit-icon icon=\"bwi-lock\"></bit-icon>";
export default {
meta: {
type: "suggestion",
docs: {
description:
"Discourage using 'bwi' font icon classes directly in favor of the <bit-icon> component",
category: "Best Practices",
recommended: true,
},
schema: [],
},
create(context) {
return {
Element(node) {
// Get all class-related attributes
const classAttrs = [
...(node.attributes?.filter((attr) => attr.name === "class") ?? []),
...(node.inputs?.filter((input) => input.name === "class") ?? []),
...(node.templateAttrs?.filter((attr) => attr.name === "class") ?? []),
];
for (const classAttr of classAttrs) {
const classValue = classAttr.value || "";
// Check if the class value contains 'bwi' or 'bwi-'
// This handles both string literals and template expressions
const hasBwiClass =
typeof classValue === "string" && /\bbwi(?:-[\w-]+)?\b/.test(classValue);
if (hasBwiClass) {
context.report({
node,
message: errorMessage,
});
// Only report once per element
break;
}
}
},
};
},
};

View File

@@ -0,0 +1,34 @@
import { RuleTester } from "@angular-eslint/test-utils";
import rule, { errorMessage } from "./no-bwi-class-usage.mjs";
const ruleTester = new RuleTester({
languageOptions: {
parser: require("@angular-eslint/template-parser"),
},
});
ruleTester.run("no-bwi-class-usage", rule, {
invalid: [
{
name: "should error on direct bwi class usage",
code: `<i class="bwi bwi-lock"></i>`,
errors: [{ message: errorMessage }],
},
{
name: "should error on bwi class with other classes",
code: `<i class="tw-flex bwi bwi-lock tw-p-2"></i>`,
errors: [{ message: errorMessage }],
},
{
name: "should error on single bwi-* class",
code: `<i class="bwi-lock"></i>`,
errors: [{ message: errorMessage }],
},
{
name: "should error on bwi-fw modifier",
code: `<i class="bwi bwi-lock bwi-fw"></i>`,
errors: [{ message: errorMessage }],
},
],
});