UNPKG

eslint-plugin-better-tailwindcss

Version:

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

142 lines 6.64 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.noUnnecessaryWhitespace = void 0; const default_options_js_1 = require("../options/default-options.js"); const descriptions_js_1 = require("../options/descriptions.js"); const options_js_1 = require("../utils/options.js"); const rule_js_1 = require("../utils/rule.js"); const utils_js_1 = require("../utils/utils.js"); const defaultOptions = { allowMultiline: true, attributes: default_options_js_1.DEFAULT_ATTRIBUTE_NAMES, callees: default_options_js_1.DEFAULT_CALLEE_NAMES, tags: default_options_js_1.DEFAULT_TAG_NAMES, variables: default_options_js_1.DEFAULT_VARIABLE_NAMES }; const DOCUMENTATION_URL = "https://github.com/schoero/eslint-plugin-better-tailwindcss/blob/main/docs/rules/no-unnecessary-whitespace.md"; exports.noUnnecessaryWhitespace = { name: "no-unnecessary-whitespace", rule: { create: ctx => (0, rule_js_1.createRuleListener)(ctx, initialize, getOptions, lintLiterals), meta: { docs: { category: "Stylistic Issues", description: "Disallow unnecessary whitespace between Tailwind CSS classes.", recommended: true, url: DOCUMENTATION_URL }, fixable: "whitespace", schema: [ { additionalProperties: false, properties: { allowMultiline: { default: defaultOptions.allowMultiline, description: "Allow multi-line class declarations. If this option is disabled, template literal strings will be collapsed into a single line string wherever possible. Must be set to `true` when used in combination with [better-tailwindcss/enforce-consistent-line-wrapping](./enforce-consistent-line-wrapping.md).", type: "boolean" }, ...descriptions_js_1.CALLEE_SCHEMA, ...descriptions_js_1.ATTRIBUTE_SCHEMA, ...descriptions_js_1.VARIABLE_SCHEMA, ...descriptions_js_1.TAG_SCHEMA }, type: "object" } ], type: "layout" } } }; function initialize() { } function lintLiterals(ctx, literals) { const { allowMultiline } = getOptions(ctx); for (const literal of literals) { const classChunks = (0, utils_js_1.splitClasses)(literal.content); const whitespaceChunks = (0, utils_js_1.splitWhitespaces)(literal.content); for (let whitespaceIndex = 0, stringIndex = 0; whitespaceIndex < whitespaceChunks.length; whitespaceIndex++) { const isFirstChunk = whitespaceIndex === 0; const isLastChunk = whitespaceIndex === whitespaceChunks.length - 1; const startIndex = stringIndex; const whitespace = whitespaceChunks[whitespaceIndex]; stringIndex += whitespace.length; const endIndex = stringIndex; const className = classChunks[whitespaceIndex] ?? ""; stringIndex += className.length; const [literalStart] = literal.range; // whitespaces only if (classChunks.length === 0 && !literal.closingBraces && !literal.openingBraces) { if (whitespace === "") { continue; } ctx.report({ fix: fixer => fixer.replaceTextRange([ literalStart + 1 + startIndex, literalStart + 1 + endIndex ], ""), loc: (0, utils_js_1.getExactClassLocation)(literal, startIndex, endIndex), message: "Unnecessary whitespace." }); continue; } // trailing whitespace before multiline string if (whitespace.includes("\n") && allowMultiline === true) { const whitespaceWithoutLeadingSpaces = whitespace.replace(/^ +/, ""); if (whitespace === whitespaceWithoutLeadingSpaces) { continue; } ctx.report({ fix: fixer => fixer.replaceTextRange([ literalStart + 1 + startIndex, literalStart + 1 + endIndex ], whitespaceWithoutLeadingSpaces), loc: (0, utils_js_1.getExactClassLocation)(literal, startIndex, endIndex), message: "Unnecessary whitespace." }); continue; } // whitespace between template literal expression if (!isFirstChunk && !isLastChunk || (literal.type === "TemplateLiteral" && literal.closingBraces && isFirstChunk && !isLastChunk || literal.type === "TemplateLiteral" && literal.openingBraces && isLastChunk && !isFirstChunk || literal.type === "TemplateLiteral" && literal.closingBraces && literal.openingBraces)) { if (whitespace.length <= 1) { continue; } ctx.report({ fix: fixer => fixer.replaceTextRange([ literalStart + 1 + startIndex, literalStart + 1 + endIndex ], " "), loc: (0, utils_js_1.getExactClassLocation)(literal, startIndex, endIndex), message: "Unnecessary whitespace." }); continue; } // leading or trailing whitespace if (isFirstChunk || isLastChunk) { if (whitespace === "") { continue; } ctx.report({ fix: fixer => fixer.replaceTextRange([ literalStart + 1 + startIndex, literalStart + 1 + endIndex ], ""), loc: (0, utils_js_1.getExactClassLocation)(literal, startIndex, endIndex), message: "Unnecessary whitespace." }); continue; } } } } function getOptions(ctx) { const options = ctx.options[0] ?? {}; const common = (0, options_js_1.getCommonOptions)(ctx); const allowMultiline = options.allowMultiline ?? defaultOptions.allowMultiline; return { ...common, allowMultiline }; } //# sourceMappingURL=no-unnecessary-whitespace.js.map