From dd2d2d25aa5f2e8f42a7b95691468227b3cee71f Mon Sep 17 00:00:00 2001 From: ginasummation Date: Mon, 14 Apr 2025 13:51:02 -0700 Subject: [PATCH 1/2] add regex whitelist to no-arbitrary-values --- docs/rules/no-arbitrary-value.md | 9 +++++++++ lib/rules/no-arbitrary-value.js | 14 +++++++++++++- tests/lib/rules/no-arbitrary-value.js | 17 +++++++++++++++-- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/docs/rules/no-arbitrary-value.md b/docs/rules/no-arbitrary-value.md index 84f1e861..cb3fd6b9 100644 --- a/docs/rules/no-arbitrary-value.md +++ b/docs/rules/no-arbitrary-value.md @@ -28,6 +28,7 @@ Examples of **correct** code for this rule: "config": |, "skipClassAttribute": , "tags": Array, + "whitelist": Array, }] ... ``` @@ -72,6 +73,14 @@ Optional, if you are using tagged templates, you should provide the tags in this Optional, can be used to support custom attributes +### `whitelist` (default: `[]`) + +The `whitelist` is empty by default but you can add custom regular expressions to this array to avoid getting warnings or errors while using certain arbitrary values or tailwind classes. + +For example, if we want to whitelist 'text-' classes for pixel values only and all 'h-" classes the `whitelist` options should be set to: + +- `['text-\\[\\d*px]', 'h-\\[[^\\]]*]']` + ## Further Reading This rule will not fix the issue for you because it cannot guess the correct class candidate. diff --git a/lib/rules/no-arbitrary-value.js b/lib/rules/no-arbitrary-value.js index 71cf4595..447d6ab1 100644 --- a/lib/rules/no-arbitrary-value.js +++ b/lib/rules/no-arbitrary-value.js @@ -54,6 +54,11 @@ module.exports = { items: { type: 'string', minLength: 0 }, uniqueItems: true, }, + whitelist: { + type: 'array', + items: { type: 'string', minLength: 0 }, + uniqueItems: true, + }, }, }, ], @@ -65,6 +70,7 @@ module.exports = { const tags = getOption(context, 'tags'); const twConfig = getOption(context, 'config'); const classRegex = getOption(context, 'classRegex'); + const whitelist = getOption(context, 'whitelist'); const mergedConfig = customConfig.resolve(twConfig); @@ -131,9 +137,15 @@ module.exports = { let { classNames } = astUtil.extractClassnamesFromValue(originalClassNamesValue); const forbidden = []; + console.log(classNames); classNames.forEach((cls, idx) => { const parsed = groupUtil.parseClassname(cls, [], mergedConfig, idx); - if (/\[.*\]/i.test(parsed.body)) { + console.log('whitelist'); + console.log(whitelist); + console.log('parsed.body'); + console.log(parsed.body); + const whitelistIdx = groupUtil.getGroupIndex(parsed.body, whitelist, mergedConfig.separator); + if (whitelistIdx < 0 && /\[.*\]/i.test(parsed.body)) { forbidden.push(parsed.name); } }); diff --git a/tests/lib/rules/no-arbitrary-value.js b/tests/lib/rules/no-arbitrary-value.js index 0a438e0d..4cf6b696 100644 --- a/tests/lib/rules/no-arbitrary-value.js +++ b/tests/lib/rules/no-arbitrary-value.js @@ -163,7 +163,20 @@ ruleTester.run("no-arbitrary-value", rule, { code: `
Dynamic viewport units
`, errors: generateErrors(["min-h-[75dvh]"]), }, - ...(['myTag', 'myTag.subTag', 'myTag(SomeComponent)'].map(tag => ({ + { + code: ` +