[Feature request] Prevent unknown classes (that follow Tailwind convention)
Is your feature request related to a problem? Please describe.
Example: in our team, some developers keep confusing gray and grey.
Describe the solution you'd like
Would be cool to report bg-gray-100 as an error because it follows Tailwind convention but doesn't exist.
Describe alternatives you've considered
- We'd rather not duplicate the entries in the theme to prevent confusion & bloat in every tools (like IDE autocomplete, Storybook, ...).
- I thought about using
no-restricted-syntaxESLint rule but it won't cover every case (Vue classes,@applytags, ...)
Additional context Add any other context or screenshots about the feature request here.
👋 @nicooprat! You should be able for that tailwindcss/no-custom-classname rule for that.
Hi, thanks for the suggestion, I tried a few regexes with the whitelist option to match everything BUT not *-gray-*, without luck. I guess something like a blacklist would be easier in my case.
I'm currently refactoring a project to use semantic tokens instead of scale values e.g. text-red-500 → text-critical. I think it's a good use case for blacklist or similar.
@kachkaev Unless there's a way to configure this behaviour using the existing API?
@blue-infinex I see two options here:
-
You can remove colors like
text-red-500from your theme.tailwindcss/no-custom-classnamewill flag them but also all existing instances will stop working (all replacements will need to happen in one go). -
You can create a custom ESLint rule or configure
no-restricted-syntax. Simplified example:{ selector: `Literal[value=/(bg|border)-(red|green)-500/]`, message: "Please use a theme color instead" }With this approach, you can start by marking existing cases (
// eslint-disable-next-line -- TODO: fix) and then gradually fix them when there is time.
Ah, okay! The no-restricted-syntax approach seems like the way to go. Thanks for the context, and for responding so quickly. I really appreciate it ✨
For Vue, this is what Cursor suggested:
'vue/no-restricted-syntax': [
{
selector:
'VAttribute[key.name="class"][value.value=/gray/] , VAttribute[directive=true][key.argument.name="class"] > VExpressionContainer:matches([value=/gray/], ArrayExpression > Literal[value=/gray/], ObjectExpression > Property > Literal[value=/gray/])',
message: 'Use "grey" instead of "gray" because it does not exist in our Tailwind config.',
}
]
Hope it helps!