UNPKG

eslint-plugin-better-tailwindcss

Version:

auto-wraps tailwind classes after a certain print width or class count into multiple lines to improve readability.

75 lines 3.43 kB
import { array, description, optional, pipe, strictObject, string } from "valibot"; import { createGetCustomComponentClasses, getCustomComponentClasses } from "../tailwindcss/custom-component-classes.js"; import { createGetPrefix, getPrefix } from "../tailwindcss/prefix.js"; import { createGetUnknownClasses, getUnknownClasses } from "../tailwindcss/unknown-classes.js"; import { async } from "../utils/context.js"; import { escapeForRegex } from "../async-utils/escape.js"; import { lintClasses } from "../utils/lint.js"; import { getCachedRegex } from "../async-utils/regex.js"; import { createRule } from "../utils/rule.js"; import { splitClasses } from "../utils/utils.js"; export const noUnknownClasses = createRule({ autofix: true, category: "correctness", description: "Disallow any css classes that are not registered in tailwindcss.", docs: "https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/no-unknown-classes.md", name: "no-unknown-classes", recommended: true, messages: { unknown: "Unknown class detected: {{ className }}" }, schema: strictObject({ ignore: optional(pipe(array(string()), description("A list of classes that should be ignored by the rule.")), []) }), initialize: ctx => { const { detectComponentClasses } = ctx.options; createGetPrefix(ctx); createGetUnknownClasses(ctx); if (detectComponentClasses) { createGetCustomComponentClasses(ctx); } }, lintLiterals: (ctx, literals) => lintLiterals(ctx, literals) }); function lintLiterals(ctx, literals) { const { ignore } = ctx.options; const { prefix, suffix } = getPrefix(async(ctx)); const ignoredGroups = getCachedRegex(`^${escapeForRegex(`${prefix}${suffix}`)}group(?:\\/(\\S*))?$`); const ignoredPeers = getCachedRegex(`^${escapeForRegex(`${prefix}${suffix}`)}peer(?:\\/(\\S*))?$`); const customComponentClassRegexes = getCustomComponentClassRegexes(ctx); for (const literal of literals) { const classes = splitClasses(literal.content); const { unknownClasses, warnings } = getUnknownClasses(async(ctx), classes); if (unknownClasses.length === 0) { continue; } lintClasses(ctx, literal, className => { if (!unknownClasses.includes(className)) { return; } if (ignore.some(ignoredClass => getCachedRegex(ignoredClass).test(className)) || customComponentClassRegexes?.some(customComponentClassesRegex => customComponentClassesRegex.test(className)) || ignoredGroups.test(className) || ignoredPeers.test(className)) { return; } return { data: { className }, id: "unknown", warnings }; }); } } function getCustomComponentClassRegexes(ctx) { const { detectComponentClasses } = ctx.options; if (!detectComponentClasses) { return; } const { customComponentClasses } = getCustomComponentClasses(async(ctx)); const { prefix, suffix } = getPrefix(async(ctx)); return customComponentClasses.map(className => getCachedRegex(`^${escapeForRegex(`${prefix}${suffix}`)}(?:.*:)?${escapeForRegex(className)}$`)); } //# sourceMappingURL=no-unknown-classes.js.map