diff --git a/README.md b/README.md index fc6eb5b4..f4cb1a16 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ If you enjoy my work you can: ## Latest changelog +- FIX: support for Tailwind CSS version `3.2.3` - FIX: [prefix parsing when using attribute variants](https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/164) - FIX: [add support for contradicting arbitrary properties](https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/163) - FIX: [conflicting rules with ambiguous arbitrary values](https://github.com/francoismassart/eslint-plugin-tailwindcss/issues/152)(by [acewf](https://github.com/acewf) 🙏) diff --git a/lib/config/groups.js b/lib/config/groups.js index 4c07bec0..859cef6d 100644 --- a/lib/config/groups.js +++ b/lib/config/groups.js @@ -196,7 +196,7 @@ module.exports.groups = [ }, { type: 'Visibility', - members: '(in)?visible', + members: '(in)?visible|collapse', }, { type: 'Z-Index', @@ -336,7 +336,7 @@ module.exports.groups = [ }, { type: 'Align Content', - members: 'content\\-(center|start|end|between|around|evenly)', + members: 'content\\-(center|start|end|between|around|evenly|baseline)', }, { type: 'Align Items', @@ -348,11 +348,11 @@ module.exports.groups = [ }, { type: 'Place Content', - members: 'place\\-content\\-(center|start|end|between|around|evenly|stretch)', + members: 'place\\-content\\-(center|start|end|between|around|evenly|stretch|baseline)', }, { type: 'Place Items', - members: 'place\\-items\\-(start|end|center|stretch)', + members: 'place\\-items\\-(start|end|center|stretch|baseline)', }, { type: 'Place Self', @@ -608,7 +608,7 @@ module.exports.groups = [ }, { type: 'Word Break', - members: 'break\\-(normal|words|all)', + members: 'break\\-(normal|words|all|keep)', }, { type: 'Content', @@ -883,7 +883,8 @@ module.exports.groups = [ }, { type: 'Outline Offset', - members: 'outline\\-offset\\-(?${outlineOffset})', + members: + '(outline\\-offset\\-(?${outlineOffset})|\\-outline\\-offset\\-(?${-outlineOffset}))', }, { type: 'Ring Width', diff --git a/lib/rules/classnames-order.js b/lib/rules/classnames-order.js index 01a2575a..c011e3d8 100644 --- a/lib/rules/classnames-order.js +++ b/lib/rules/classnames-order.js @@ -7,10 +7,8 @@ const docsUrl = require('../util/docsUrl'); const customConfig = require('../util/customConfig'); const astUtil = require('../util/ast'); -const groupUtil = require('../util/groupMethods'); const removeDuplicatesFromClassnamesAndWhitespaces = require('../util/removeDuplicatesFromClassnamesAndWhitespaces'); const getOption = require('../util/settings'); -const groups = require('../config/groups').groups; const parserUtil = require('../util/parser'); const order = require('../util/prettier/order'); const createContextFallback = require('tailwindcss/lib/lib/setupContextUtils').createContext; @@ -68,7 +66,6 @@ module.exports = { const callees = getOption(context, 'callees'); const tags = getOption(context, 'tags'); const twConfig = getOption(context, 'config'); - const groupsConfig = groups; const removeDuplicates = getOption(context, 'removeDuplicates'); const mergedConfig = customConfig.resolve(twConfig); @@ -165,7 +162,7 @@ module.exports = { return; } - let orderedClassNames = order(classNames, contextFallback); + let orderedClassNames = order(classNames, contextFallback).split(' '); if (removeDuplicates) { removeDuplicatesFromClassnamesAndWhitespaces(orderedClassNames, whitespaces, headSpace, tailSpace); diff --git a/lib/util/prettier/order.js b/lib/util/prettier/order.js index 60f84ec0..c3ec785b 100644 --- a/lib/util/prettier/order.js +++ b/lib/util/prettier/order.js @@ -1,18 +1,73 @@ -var generateRulesFallback = require('tailwindcss/lib/lib/generateRules').generateRules; - function bigSign(bigIntValue) { return (bigIntValue > 0n) - (bigIntValue < 0n); } -function order(unordered, context) { - const classNamesWithOrder = []; - unordered.forEach((className) => { - const order = - generateRulesFallback(new Set([className]), context).sort(([a], [z]) => bigSign(z - a))[0]?.[0] ?? null; +function prefixCandidate(context, selector) { + let prefix = context.tailwindConfig.prefix; + return typeof prefix === 'function' ? prefix(selector) : prefix + selector; +} + +// Polyfill for older Tailwind CSS versions +function getClassOrderPolyfill(classes, { env }) { + // A list of utilities that are used by certain Tailwind CSS utilities but + // that don't exist on their own. This will result in them "not existing" and + // sorting could be weird since you still require them in order to make the + // host utitlies work properly. (Thanks Biology) + let parasiteUtilities = new Set([prefixCandidate(env.context, 'group'), prefixCandidate(env.context, 'peer')]); + + let classNamesWithOrder = []; + + for (let className of classes) { + let order = env.generateRules(new Set([className]), env.context).sort(([a], [z]) => bigSign(z - a))[0]?.[0] ?? null; + + if (order === null && parasiteUtilities.has(className)) { + // This will make sure that it is at the very beginning of the + // `components` layer which technically means 'before any + // components'. + order = env.context.layerOrder.components; + } + classNamesWithOrder.push([className, order]); - }); + } + + return classNamesWithOrder; +} + +function sortClasses(classStr, { env, ignoreFirst = false, ignoreLast = false }) { + if (typeof classStr !== 'string' || classStr === '') { + return classStr; + } - const classes = classNamesWithOrder + // Ignore class attributes containing `{{`, to match Prettier behaviour: + // https://github.com/prettier/prettier/blob/main/src/language-html/embed.js#L83-L88 + if (classStr.includes('{{')) { + return classStr; + } + + let result = ''; + let parts = classStr.split(/(\s+)/); + let classes = parts.filter((_, i) => i % 2 === 0); + let whitespace = parts.filter((_, i) => i % 2 !== 0); + + if (classes[classes.length - 1] === '') { + classes.pop(); + } + + let prefix = ''; + if (ignoreFirst) { + prefix = `${classes.shift() ?? ''}${whitespace.shift() ?? ''}`; + } + + let suffix = ''; + if (ignoreLast) { + suffix = `${whitespace.pop() ?? ''}${classes.pop() ?? ''}`; + } + + let classNamesWithOrder = env.context.getClassOrder + ? env.context.getClassOrder(classes) + : getClassOrderPolyfill(classes, { env }); + + classes = classNamesWithOrder .sort(([, a], [, z]) => { if (a === z) return 0; // if (a === null) return options.unknownClassPosition === 'start' ? -1 : 1 @@ -22,7 +77,23 @@ function order(unordered, context) { return bigSign(a - z); }) .map(([className]) => className); - return classes; + + for (let i = 0; i < classes.length; i++) { + result += `${classes[i]}${whitespace[i] ?? ''}`; + } + + return prefix + result + suffix; +} + +/** + * + * @param {Array} unordered the unordered classnames + * @param context + * @returns {Array} the ordered classnames + */ +function order(unordered, context) { + const sorted = sortClasses(unordered.join(' '), { env: { context: context } }); + return sorted; } module.exports = order; diff --git a/package-lock.json b/package-lock.json index 3fd105b8..bda84ce9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,24 @@ { "name": "eslint-plugin-tailwindcss", - "version": "3.6.2", + "version": "3.7.0-beta.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "eslint-plugin-tailwindcss", - "version": "3.6.2", + "version": "3.7.0-beta.0", "license": "MIT", "dependencies": { "fast-glob": "^3.2.5", "postcss": "^8.4.4", - "tailwindcss": "^3.1.3" + "tailwindcss": "^3.2.2" }, "devDependencies": { "@angular-eslint/template-parser": "^13.0.1", - "@tailwindcss/aspect-ratio": "^0.4.0", - "@tailwindcss/forms": "^0.4.0", - "@tailwindcss/line-clamp": "^0.3.1", - "@tailwindcss/typography": "^0.5.2", + "@tailwindcss/aspect-ratio": "^0.4.2", + "@tailwindcss/forms": "^0.5.3", + "@tailwindcss/line-clamp": "^0.4.2", + "@tailwindcss/typography": "^0.5.8", "@typescript-eslint/parser": "^4.33.0", "autoprefixer": "^10.4.0", "daisyui": "^2.6.4", @@ -159,18 +159,18 @@ } }, "node_modules/@tailwindcss/aspect-ratio": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/aspect-ratio/-/aspect-ratio-0.4.0.tgz", - "integrity": "sha512-WJu0I4PpqNPuutpaA9zDUq2JXR+lorZ7PbLcKNLmb6GL9/HLfC7w3CRsMhJF4BbYd/lkY6CfXOvkYpuGnZfkpQ==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/aspect-ratio/-/aspect-ratio-0.4.2.tgz", + "integrity": "sha512-8QPrypskfBa7QIMuKHg2TA7BqES6vhBrDLOv8Unb6FcFyd3TjKbc6lcmb9UPQHxfl24sXoJ41ux/H7qQQvfaSQ==", "dev": true, "peerDependencies": { "tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1" } }, "node_modules/@tailwindcss/forms": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.4.0.tgz", - "integrity": "sha512-DeaQBx6EgEeuZPQACvC+mKneJsD8am1uiJugjgQK1+/Vt+Ai0GpFBC2T2fqnUad71WgOxyrZPE6BG1VaI6YqfQ==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.3.tgz", + "integrity": "sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==", "dev": true, "dependencies": { "mini-svg-data-uri": "^1.2.3" @@ -180,26 +180,27 @@ } }, "node_modules/@tailwindcss/line-clamp": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.3.1.tgz", - "integrity": "sha512-pNr0T8LAc3TUx/gxCfQZRe9NB2dPEo/cedPHzUGIPxqDMhgjwNm6jYxww4W5l0zAsAddxr+XfZcqttGiFDgrGg==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.4.2.tgz", + "integrity": "sha512-HFzAQuqYCjyy/SX9sLGB1lroPzmcnWv1FHkIpmypte10hptf4oPUfucryMKovZh2u0uiS9U5Ty3GghWfEJGwVw==", "dev": true, "peerDependencies": { "tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1" } }, "node_modules/@tailwindcss/typography": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.2.tgz", - "integrity": "sha512-coq8DBABRPFcVhVIk6IbKyyHUt7YTEC/C992tatFB+yEx5WGBQrCgsSFjxHUr8AWXphWckadVJbominEduYBqw==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.8.tgz", + "integrity": "sha512-xGQEp8KXN8Sd8m6R4xYmwxghmswrd0cPnNI2Lc6fmrC3OojysTBJJGSIVwPV56q4t6THFUK3HJ0EaWwpglSxWw==", "dev": true, "dependencies": { "lodash.castarray": "^4.4.0", "lodash.isplainobject": "^4.0.6", - "lodash.merge": "^4.6.2" + "lodash.merge": "^4.6.2", + "postcss-selector-parser": "6.0.10" }, "peerDependencies": { - "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || insiders" + "tailwindcss": ">=3.0.0 || insiders" } }, "node_modules/@typescript-eslint/parser": { @@ -1254,9 +1255,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -1871,9 +1872,9 @@ } }, "node_modules/lilconfig": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", - "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", "engines": { "node": ">=10" } @@ -1962,28 +1963,17 @@ } }, "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/mini-svg-data-uri": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.3.tgz", @@ -2397,9 +2387,9 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "engines": { "node": ">=8.6" }, @@ -2416,9 +2406,9 @@ } }, "node_modules/postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "version": "8.4.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", + "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", "funding": [ { "type": "opencollective", @@ -2501,11 +2491,11 @@ } }, "node_modules/postcss-nested": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", - "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", + "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", "dependencies": { - "postcss-selector-parser": "^6.0.6" + "postcss-selector-parser": "^6.0.10" }, "engines": { "node": ">=12.0" @@ -2974,9 +2964,9 @@ "dev": true }, "node_modules/tailwindcss": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.3.tgz", - "integrity": "sha512-PRJNYdSIthrb8hjmAyymEyEN8Yo61TMXpzyFUpxULeeyRn3Y3gpvuw6FlRTKrJvK7thSGKRnhT36VovVx4WeMA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.2.tgz", + "integrity": "sha512-c2GtSdqg+harR4QeoTmex0Ngfg8IIHNeLQH5yr2B9uZbZR1Xt1rYbjWOWTcj3YLTZhrmZnPowoQDbSRFyZHQ5Q==", "dependencies": { "arg": "^5.0.2", "chokidar": "^3.5.3", @@ -2984,22 +2974,23 @@ "detective": "^5.2.1", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.2.11", + "fast-glob": "^3.2.12", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "lilconfig": "^2.0.5", + "lilconfig": "^2.0.6", + "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.14", + "postcss": "^8.4.18", "postcss-import": "^14.1.0", "postcss-js": "^4.0.0", "postcss-load-config": "^3.1.4", - "postcss-nested": "5.0.6", + "postcss-nested": "6.0.0", "postcss-selector-parser": "^6.0.10", "postcss-value-parser": "^4.2.0", "quick-lru": "^5.1.1", - "resolve": "^1.22.0" + "resolve": "^1.22.1" }, "bin": { "tailwind": "lib/cli.js", @@ -3196,7 +3187,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/v8-compile-cache": { "version": "2.3.0", @@ -3647,37 +3638,38 @@ } }, "@tailwindcss/aspect-ratio": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/aspect-ratio/-/aspect-ratio-0.4.0.tgz", - "integrity": "sha512-WJu0I4PpqNPuutpaA9zDUq2JXR+lorZ7PbLcKNLmb6GL9/HLfC7w3CRsMhJF4BbYd/lkY6CfXOvkYpuGnZfkpQ==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/aspect-ratio/-/aspect-ratio-0.4.2.tgz", + "integrity": "sha512-8QPrypskfBa7QIMuKHg2TA7BqES6vhBrDLOv8Unb6FcFyd3TjKbc6lcmb9UPQHxfl24sXoJ41ux/H7qQQvfaSQ==", "dev": true, "requires": {} }, "@tailwindcss/forms": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.4.0.tgz", - "integrity": "sha512-DeaQBx6EgEeuZPQACvC+mKneJsD8am1uiJugjgQK1+/Vt+Ai0GpFBC2T2fqnUad71WgOxyrZPE6BG1VaI6YqfQ==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.3.tgz", + "integrity": "sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==", "dev": true, "requires": { "mini-svg-data-uri": "^1.2.3" } }, "@tailwindcss/line-clamp": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.3.1.tgz", - "integrity": "sha512-pNr0T8LAc3TUx/gxCfQZRe9NB2dPEo/cedPHzUGIPxqDMhgjwNm6jYxww4W5l0zAsAddxr+XfZcqttGiFDgrGg==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.4.2.tgz", + "integrity": "sha512-HFzAQuqYCjyy/SX9sLGB1lroPzmcnWv1FHkIpmypte10hptf4oPUfucryMKovZh2u0uiS9U5Ty3GghWfEJGwVw==", "dev": true, "requires": {} }, "@tailwindcss/typography": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.2.tgz", - "integrity": "sha512-coq8DBABRPFcVhVIk6IbKyyHUt7YTEC/C992tatFB+yEx5WGBQrCgsSFjxHUr8AWXphWckadVJbominEduYBqw==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.8.tgz", + "integrity": "sha512-xGQEp8KXN8Sd8m6R4xYmwxghmswrd0cPnNI2Lc6fmrC3OojysTBJJGSIVwPV56q4t6THFUK3HJ0EaWwpglSxWw==", "dev": true, "requires": { "lodash.castarray": "^4.4.0", "lodash.isplainobject": "^4.0.6", - "lodash.merge": "^4.6.2" + "lodash.merge": "^4.6.2", + "postcss-selector-parser": "6.0.10" } }, "@typescript-eslint/parser": { @@ -4454,9 +4446,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -4881,9 +4873,9 @@ } }, "lilconfig": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", - "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==" + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==" }, "locate-path": { "version": "3.0.0", @@ -4956,19 +4948,12 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "dependencies": { - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" - } + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, "mini-svg-data-uri": { @@ -5286,9 +5271,9 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, "pify": { "version": "2.3.0", @@ -5296,9 +5281,9 @@ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" }, "postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "version": "8.4.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", + "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -5333,11 +5318,11 @@ } }, "postcss-nested": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", - "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", + "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", "requires": { - "postcss-selector-parser": "^6.0.6" + "postcss-selector-parser": "^6.0.10" } }, "postcss-selector-parser": { @@ -5655,9 +5640,9 @@ } }, "tailwindcss": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.3.tgz", - "integrity": "sha512-PRJNYdSIthrb8hjmAyymEyEN8Yo61TMXpzyFUpxULeeyRn3Y3gpvuw6FlRTKrJvK7thSGKRnhT36VovVx4WeMA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.2.tgz", + "integrity": "sha512-c2GtSdqg+harR4QeoTmex0Ngfg8IIHNeLQH5yr2B9uZbZR1Xt1rYbjWOWTcj3YLTZhrmZnPowoQDbSRFyZHQ5Q==", "requires": { "arg": "^5.0.2", "chokidar": "^3.5.3", @@ -5665,22 +5650,23 @@ "detective": "^5.2.1", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.2.11", + "fast-glob": "^3.2.12", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "lilconfig": "^2.0.5", + "lilconfig": "^2.0.6", + "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.14", + "postcss": "^8.4.18", "postcss-import": "^14.1.0", "postcss-js": "^4.0.0", "postcss-load-config": "^3.1.4", - "postcss-nested": "5.0.6", + "postcss-nested": "6.0.0", "postcss-selector-parser": "^6.0.10", "postcss-value-parser": "^4.2.0", "quick-lru": "^5.1.1", - "resolve": "^1.22.0" + "resolve": "^1.22.1" }, "dependencies": { "chokidar": { @@ -5819,7 +5805,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "v8-compile-cache": { "version": "2.3.0", diff --git a/package.json b/package.json index e6df894d..5929eb24 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-tailwindcss", - "version": "3.6.2", + "version": "3.7.0-beta.0", "description": "Rules enforcing best practices while using Tailwind CSS", "keywords": [ "eslint", @@ -26,14 +26,14 @@ "dependencies": { "fast-glob": "^3.2.5", "postcss": "^8.4.4", - "tailwindcss": "^3.1.3" + "tailwindcss": "^3.2.2" }, "devDependencies": { "@angular-eslint/template-parser": "^13.0.1", - "@tailwindcss/aspect-ratio": "^0.4.0", - "@tailwindcss/forms": "^0.4.0", - "@tailwindcss/line-clamp": "^0.3.1", - "@tailwindcss/typography": "^0.5.2", + "@tailwindcss/aspect-ratio": "^0.4.2", + "@tailwindcss/forms": "^0.5.3", + "@tailwindcss/line-clamp": "^0.4.2", + "@tailwindcss/typography": "^0.5.8", "@typescript-eslint/parser": "^4.33.0", "autoprefixer": "^10.4.0", "daisyui": "^2.6.4", diff --git a/tests/lib/rules/arbitrary-values.js b/tests/lib/rules/arbitrary-values.js index f8267978..366c2736 100644 --- a/tests/lib/rules/arbitrary-values.js +++ b/tests/lib/rules/arbitrary-values.js @@ -554,35 +554,6 @@ ruleTester.run("arbitrary-values", rule, { `, errors: generateErrors("aspect-ko"), }, - { - code: ` -
- placeholderColor using var -
- `, - options: config, - errors: generateErrors("placeholder:text-[var(--some)]"), - }, - { - code: ` -
- placeholderColor using rgba(255 0 0 / 0.4) -
- `, - options: config, - errors: generateErrors( - "placeholder:text-[rgba(255,0,0/0.4)] placeholder:text-[rgba(255,0,0/.4)] placeholder:text-[rgba(255,0,0/40%)]" - ), - }, - { - code: ` -
- Invalid bg-color -
- `, - options: config, - errors: generateErrors("bg-[var(--donno)]"), - }, { code: `
@@ -601,53 +572,6 @@ ruleTester.run("arbitrary-values", rule, { options: config, errors: generateErrors("placeholder:text-[hsla(240,100%,50%,0.7]"), }, - { - code: ` -
- Battle testing invalid textColor -
- `, - options: config, - errors: generateErrors( - "text-[rgba(255,0,0/0.4)] text-[rgba(255,0,0/.4)] text-[rgba(255,0,0/40%)] text-[var(--some)]" - ), - }, - { - code: ` -
- Invalid / ambiguous arbitrary values for border-width -
- `, - options: config, - errors: generateErrors("border-[1cap] border-[1ic] border-[var(--some)] border-[1vb] border-[1vi]"), - }, - { - code: ` -
- Invalid / ambiguous arbitrary values for divide-width -
- `, - options: config, - errors: generateErrors("divide-x-[1cap] divide-x-[1ic] divide-y-[var(--some)]"), - }, - { - code: ` -
- Invalid / ambiguous arbitrary values for fontSize -
- `, - options: config, - errors: generateErrors("text-[1cap] text-[1ic] text-[var(--some)]"), - }, - { - code: ` -
- Invalid arbitrary values for ringWidth -
- `, - options: config, - errors: generateErrors("ring-[var(--some)] ring-[3cap] ring-[3ic] ring-[3vb] ring-[3vi]"), - }, { code: `
@@ -668,13 +592,6 @@ ruleTester.run("arbitrary-values", rule, { options: config, errors: generateErrors("list-[angle:var(--some)] list-[list:var(--some)]"), }, - { - code: ` - - `, - options: config, - errors: generateErrors("ring-offset-[4]"), - }, { code: ` @@ -750,18 +667,7 @@ ruleTester.run("arbitrary-values", rule, { `, options: config, - errors: generateErrors("stroke-[var(--some)] stroke-['yolo'] stroke-[angle:var(--some)]"), - }, - { - code: ` -
- Invalid / ambiguous arbitrary values for stroke-width -
- `, - options: config, - errors: generateErrors( - "stroke-[1cap] stroke-[1ic] stroke-[thick] stroke-[var(--some)] stroke-[1vb] stroke-[1vi]" - ), + errors: generateErrors("stroke-[angle:var(--some)]"), }, ], }); diff --git a/tests/lib/rules/classnames-order.js b/tests/lib/rules/classnames-order.js index a8ba0ee2..79a092be 100644 --- a/tests/lib/rules/classnames-order.js +++ b/tests/lib/rules/classnames-order.js @@ -198,8 +198,9 @@ ruleTester.run("classnames-order", rule, { ], }, { + // No plugin code: ` - + `, }, { @@ -214,8 +215,9 @@ ruleTester.run("classnames-order", rule, { options: sharedOptions, }, { + // Kitchensink code: ` - + `, options: sharedOptions, }, diff --git a/tests/lib/rules/no-contradicting-classname.js b/tests/lib/rules/no-contradicting-classname.js index d9a0e8ff..dcd02f58 100644 --- a/tests/lib/rules/no-contradicting-classname.js +++ b/tests/lib/rules/no-contradicting-classname.js @@ -587,6 +587,27 @@ ruleTester.run("no-contradicting-classname", rule, { />`, errors: generateErrors("[clip-path:circle(90%_at_center)] [clip-path:circle(100%_at_center)]"), }, + { + code: ` +
+ Conflicting fill +
`, + errors: generateErrors("fill-white fill-none"), + }, + { + code: ` +
+ Conflicting stroke +
`, + errors: generateErrors("stroke-white stroke-none"), + }, + { + code: ` +
+ Conflicting outline offset +
`, + errors: generateErrors("-outline-offset-2 outline-offset-4"), + }, // { // code: ` //
diff --git a/tests/lib/rules/no-custom-classname.js b/tests/lib/rules/no-custom-classname.js index 37a22b3a..4134f0be 100644 --- a/tests/lib/rules/no-custom-classname.js +++ b/tests/lib/rules/no-custom-classname.js @@ -794,6 +794,15 @@ ruleTester.run("no-custom-classname", rule, { { code: `
No errors while typing
`, }, + { + code: `
https://github.com/tailwindlabs/tailwindcss/pull/9453
`, + }, + { + code: `
https://github.com/tailwindlabs/tailwindcss/pull/9558
`, + }, + { + code: `
https://github.com/tailwindlabs/tailwindcss/pull/9557
`, + }, ], invalid: [