Skip to content

Commit e7d2288

Browse files
Very basic whitelist option
1 parent 007f465 commit e7d2288

File tree

4 files changed

+33
-12
lines changed

4 files changed

+33
-12
lines changed

src/rules/classnames-order.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ export const createRule = RuleCreator(urlCreator);
4545
const sortClassnames = (
4646
context: RuleContext,
4747
settings: PluginSettings,
48+
options: RuleOptions,
4849
literals: Array<AtomicNode>,
4950
) => {
51+
console.log(options);
5052
for (const node of literals) {
5153
const { originalClassNamesValue, start, end, prefix, suffix } =
5254
dissectAtomicNode(node, context as unknown as GenericRuleContext);

src/rules/no-custom-classname.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,12 @@ ruleTester.run(RULE_NAME, noCustomClassname, {
4747
valid:
4848
// Angular / Native HTML + static text
4949
[
50-
`<h1 class="flex">attributeVisitor with TextAttribute (single class gets skipped)</h1>`,
50+
`<h1 class="whitelisted flex">attributeVisitor with TextAttribute (single class gets skipped)</h1>`,
5151
`<h1 class=" relative ">extra spaces</h1>`,
5252
`<h1 class=" relative " className=' flex'>Single + double quotes</h1>`,
5353
].map((testedNgCode) => ({
5454
code: testedNgCode,
55+
options: [{ whitelist: ["whitelisted"] }],
5556
languageOptions: withAngularParser,
5657
})),
5758
invalid: [

src/rules/no-custom-classname.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ export type MessageIds =
3434
| "issue:unknown-classname"
3535
| "fix:unknown-classname:remove";
3636

37-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
38-
export type RuleOptions = {};
37+
export type RuleOptions = {
38+
whitelist: Array<string>;
39+
};
3940

4041
type Options = [RuleOptions];
4142

@@ -48,8 +49,11 @@ export const createRule = RuleCreator(urlCreator);
4849
const detectCustomClassnames = (
4950
context: RuleContext,
5051
settings: PluginSettings,
52+
options: RuleOptions,
5153
literals: Array<AtomicNode>,
5254
) => {
55+
const parsedOptions: RuleOptions = options || { whitelist: [] };
56+
// console.log(parsedOptions);
5357
for (const node of literals) {
5458
const { originalClassNamesValue } = dissectAtomicNode(
5559
node,
@@ -58,6 +62,12 @@ const detectCustomClassnames = (
5862
// Process the extracted classnames and report
5963
const { classNames } = getClassnamesFromValue(originalClassNamesValue);
6064
for (const className of classNames) {
65+
// TODO extract base class without modifiers
66+
// TODO make a set from the whitelist array
67+
// TODO allow regular expressions
68+
if (parsedOptions.whitelist.includes(className)) {
69+
continue;
70+
}
6171
if (!isValidClassNameWorker(settings.cssConfigPath, className)) {
6272
const patchedLoc = generateLocForClassname(
6373
node,
@@ -119,7 +129,7 @@ export const noCustomClassname = createRule<Options, MessageIds>({
119129
additionalProperties: false,
120130
},
121131
],
122-
defaultOptions: [{}],
132+
defaultOptions: [{ whitelist: [] }],
123133
type: "suggestion",
124134
},
125135
/**
@@ -140,11 +150,16 @@ export const noCustomClassname = createRule<Options, MessageIds>({
140150
createTemplateVisitors(
141151
context,
142152
settings,
143-
options,
153+
options[0],
144154
detectCustomClassnames,
145155
),
146156
// Script visitor is used within both JSX and Vue SFC files (inside <script> section).
147-
createScriptVisitors(context, settings, options, detectCustomClassnames),
157+
createScriptVisitors(
158+
context,
159+
settings,
160+
options[0],
161+
detectCustomClassnames,
162+
),
148163
);
149164
},
150165
});

src/utils/rule.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,11 @@ export const createScriptVisitors = <TRuleContext, TOptions>(
224224
lintLiterals: (
225225
context: TRuleContext,
226226
settings: PluginSettings,
227+
options: TOptions,
227228
literals: Array<AtomicNode>,
228229
) => void,
229230
): RuleListener => {
231+
console.log(options);
230232
return {
231233
/**
232234
* In JSX + inside <script> section of Vue SFC…
@@ -251,7 +253,7 @@ export const createScriptVisitors = <TRuleContext, TOptions>(
251253
callExpressionNode,
252254
0,
253255
);
254-
lintLiterals(context, settings, literals);
256+
lintLiterals(context, settings, options, literals);
255257
},
256258

257259
/**
@@ -269,7 +271,7 @@ export const createScriptVisitors = <TRuleContext, TOptions>(
269271
jsxAttributeNode,
270272
0,
271273
);
272-
lintLiterals(context, settings, literals);
274+
lintLiterals(context, settings, options, literals);
273275
},
274276

275277
/**
@@ -293,7 +295,7 @@ export const createScriptVisitors = <TRuleContext, TOptions>(
293295
taggedTemplateExpressionNode,
294296
0,
295297
);
296-
lintLiterals(context, settings, literals);
298+
lintLiterals(context, settings, options, literals);
297299
},
298300

299301
/**
@@ -305,7 +307,7 @@ export const createScriptVisitors = <TRuleContext, TOptions>(
305307
const textAttributeNode = node as unknown as TextAttribute;
306308
if (!isValidTextAttribute(textAttributeNode, settings)) return;
307309
const literals = [textAttributeNode];
308-
lintLiterals(context, settings, literals);
310+
lintLiterals(context, settings, options, literals);
309311
},
310312
};
311313
};
@@ -326,6 +328,7 @@ export const createTemplateVisitors = <TRuleContext, TOptions>(
326328
lintLiterals: (
327329
context: TRuleContext,
328330
settings: PluginSettings,
331+
options: TOptions,
329332
literals: Array<AtomicNode>,
330333
) => void,
331334
): RuleListener => {
@@ -340,7 +343,7 @@ export const createTemplateVisitors = <TRuleContext, TOptions>(
340343
VAttribute(node: VueAST.VAttribute) {
341344
if (!isValidVAttribute(node, settings)) return;
342345
if (node.value?.type === "VLiteral") {
343-
lintLiterals(context, settings, [node.value]);
346+
lintLiterals(context, settings, options, [node.value]);
344347
}
345348
// @ts-expect-error Types have no overlap.ts(2367)
346349
if (node.value?.type !== "VExpressionContainer") return;
@@ -389,7 +392,7 @@ export const createTemplateVisitors = <TRuleContext, TOptions>(
389392
break;
390393
}
391394
}
392-
lintLiterals(context, settings, literals);
395+
lintLiterals(context, settings, options, literals);
393396
},
394397
};
395398
};

0 commit comments

Comments
 (0)