UNPKG

eslint-plugin-readable-tailwind

Version:

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

121 lines 5.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.tailwindNoDuplicateClasses = void 0; const readable_tailwind_options_default_options_js_1 = require("../options/default-options.js"); const readable_tailwind_options_descriptions_js_1 = require("../options/descriptions.js"); const readable_tailwind_utils_quotes_js_1 = require("../utils/quotes.js"); const readable_tailwind_utils_rule_js_1 = require("../utils/rule.js"); const readable_tailwind_utils_utils_js_1 = require("../utils/utils.js"); const defaultOptions = { attributes: readable_tailwind_options_default_options_js_1.DEFAULT_ATTRIBUTE_NAMES, callees: readable_tailwind_options_default_options_js_1.DEFAULT_CALLEE_NAMES, tags: readable_tailwind_options_default_options_js_1.DEFAULT_TAG_NAMES, variables: readable_tailwind_options_default_options_js_1.DEFAULT_VARIABLE_NAMES }; const DOCUMENTATION_URL = "https://github.com/schoero/eslint-plugin-readable-tailwind/blob/main/docs/rules/no-duplicate-classes.md"; exports.tailwindNoDuplicateClasses = { name: "no-duplicate-classes", rule: { create: ctx => (0, readable_tailwind_utils_rule_js_1.createRuleListener)(ctx, getOptions(ctx), lintLiterals), meta: { docs: { category: "Stylistic Issues", description: "Disallow duplicate class names in tailwind classes.", recommended: true, url: DOCUMENTATION_URL }, fixable: "code", schema: [ { additionalProperties: false, properties: { ...readable_tailwind_options_descriptions_js_1.CALLEE_SCHEMA, ...readable_tailwind_options_descriptions_js_1.ATTRIBUTE_SCHEMA, ...readable_tailwind_options_descriptions_js_1.VARIABLE_SCHEMA, ...readable_tailwind_options_descriptions_js_1.TAG_SCHEMA }, type: "object" } ], type: "layout" } } }; function lintLiterals(ctx, literals) { for (const literal of literals) { const parentClasses = literal.priorLiterals ? getClassesFromLiteralNodes(literal.priorLiterals) : []; const duplicates = []; const classes = literal.content; const classChunks = (0, readable_tailwind_utils_utils_js_1.splitClasses)(classes); const whitespaceChunks = (0, readable_tailwind_utils_utils_js_1.splitWhitespaces)(classes); const finalChunks = []; const startsWithWhitespace = whitespaceChunks.length > 0 && whitespaceChunks[0] !== ""; const endsWithWhitespace = whitespaceChunks.length > 0 && whitespaceChunks[whitespaceChunks.length - 1] !== ""; for (let i = 0; i < whitespaceChunks.length; i++) { if (whitespaceChunks[i]) { finalChunks.push(whitespaceChunks[i]); } if (classChunks[i]) { // always push sticky classes without adding to the register if (!startsWithWhitespace && i === 0 && literal.closingBraces || !endsWithWhitespace && i === classChunks.length - 1 && literal.openingBraces) { finalChunks.push(classChunks[i]); continue; } if (parentClasses.includes(classChunks[i])) { if (!duplicates.includes(classChunks[i])) { duplicates.push(classChunks[i]); } } else { finalChunks.push(classChunks[i]); parentClasses.push(classChunks[i]); } } } const escapedClasses = (0, readable_tailwind_utils_quotes_js_1.escapeNestedQuotes)(finalChunks.join(""), literal.openingQuote ?? literal.closingQuote ?? "\""); const fixedClasses = [ literal.openingQuote ?? "", literal.type === "TemplateLiteral" && literal.closingBraces ? literal.closingBraces : "", escapedClasses, literal.type === "TemplateLiteral" && literal.openingBraces ? literal.openingBraces : "", literal.closingQuote ?? "" ].join(""); if (literal.raw === fixedClasses) { continue; } for (const className of duplicates) { ctx.report({ data: { duplicateClassname: className }, fix(fixer) { return fixer.replaceTextRange(literal.range, fixedClasses); }, loc: (0, readable_tailwind_utils_utils_js_1.getExactClassLocation)(literal, className, true), message: "Duplicate classname: \"{{ duplicateClassname }}\"." }); } } } function getClassesFromLiteralNodes(literals) { return literals.reduce((combinedClasses, literal) => { if (!literal) { return combinedClasses; } const classes = literal.content; const split = (0, readable_tailwind_utils_utils_js_1.splitClasses)(classes); for (const className of split) { if (!combinedClasses.includes(className)) { combinedClasses.push(className); } } return combinedClasses; }, []); } function getOptions(ctx) { return (0, readable_tailwind_utils_utils_js_1.getCommonOptions)(ctx); } //# sourceMappingURL=tailwind-no-duplicate-classes.js.map