├── .eslintrc.json ├── .gitignore ├── .prettierignore ├── .prettierrc ├── LICENSE ├── README.md ├── dist ├── index.cjs ├── index.cjs.map ├── index.modern.js ├── index.modern.js.map ├── index.module.js ├── index.module.js.map ├── index.umd.js ├── index.umd.js.map └── types │ └── index.d.ts ├── index.ts ├── package-lock.json ├── package.json └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true, 5 | "node": true 6 | }, 7 | "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"], 8 | "overrides": [], 9 | "parser": "@typescript-eslint/parser", 10 | "parserOptions": { 11 | "ecmaVersion": "latest", 12 | "sourceType": "module" 13 | }, 14 | "plugins": ["@typescript-eslint", "prettier"], 15 | "rules": { 16 | "prettier/prettier": 1, 17 | "@typescript-eslint/no-explicit-any": "off" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | README.md 2 | dist 3 | tsconfig.json -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5", 4 | "arrowParens": "always", 5 | "bracketSameLine": false, 6 | "printWidth": 120, 7 | "tabWidth": 2, 8 | "semi": true 9 | } 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Brandon McConnell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Selector Patterns for Tailwind CSS

2 | 3 |
4 | 5 | [![minified size](https://img.shields.io/bundlephobia/min/tailwindcss-selector-patterns)](https://bundlephobia.com/package/tailwindcss-selector-patterns) 6 | [![license](https://img.shields.io/github/license/brandonmcconnell/tailwindcss-selector-patterns?label=license)](https://github.com/brandonmcconnell/tailwindcss-selector-patterns/blob/main/LICENSE) 7 | [![version](https://img.shields.io/npm/v/tailwindcss-selector-patterns)](https://www.npmjs.com/package/tailwindcss-selector-patterns) 8 | [![twitter](https://img.shields.io/twitter/follow/branmcconnell)](https://twitter.com/branmcconnell) 9 | 10 |
11 | 12 | This Tailwind CSS plugin introduces a custom variant enabling dynamic targeting of elements matching patterns that would otherwise require multiple CSS selectors, in most cases where this plugin would be especially useful. The more complex selectors are generated by the [Tailwind CSS JIT engine](https://tailwindcss.com/blog/just-in-time-the-next-generation-of-tailwind-css) at build time, so using this plugin is only as expensive—in terms of performance—as the selectors a developer uses it to generate. 13 | 14 | Some advantages of using this plugin include: 15 | - **Markup size:** Reduces the number of Tailwind CSS utilities required to target specific element(s) based on their relationship(s) to the current element within the DOM tree 16 | - **Simplicity:** Shorthand syntax, making it easy to use, and the intent easy to convey and understand 17 | - **Precision:** Simple to target a sibling N nodes away in a specified direction 18 | - **Bidirectionality:** Match siblings in prev/next direction (or both), or a parent/child N nodes away in either asc/desc direction (or both). Combining this with the precision benefit allows for truly powerful selectors, while still keeping the syntax simple and easy to understand. 19 | - **Single source of truth:** Avoid coupling custom variants to match elements in different directions (e.g. `pattern-[%]:underline` vs. `[&>*]:underline [:has(>&)]:underline`). 20 | 21 | The majority of the magic behind this plugin lies in the [Tailwind CSS JIT engine](https://tailwindcss.com/blog/just-in-time-the-next-generation-of-tailwind-css), allowing for the dynamic processing of custom variants, and the the CSS [`:has()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:has) selector, which can be used in many ways to target elements based on their relationship to the current element, even if the element you are targeting precedes the current element in the DOM tree. No run-time JS is needed. 22 | 23 | ## Syntax 24 | 25 | ``` 26 | pattern-[{combinator}{nth-index?}{inclusion-direction?}{;selector?}] 27 | ``` 28 | 29 | - `combinator` (required): Specifies the relationship between the selected element and the target element(s). Available combinators are: 30 | - `+`: Select the next sibling element 31 | - `++`: Select all next sibling elements 32 | - `-`: Select the previous sibling element 33 | - `--`: Select all previous sibling elements 34 | - `%`: Select the parent element 35 | - `%%`: Select all ancestor elements 36 | - `>`: Select direct child elements 37 | - `>>`: Select all descendant elements 38 | - `<`: Select direct parent element 39 | - `<<`: Select all ancestor elements 40 | - `^`: Select both parent and child elements 41 | - `^^`: Select both ancestor and descendant elements 42 | - `nth-index` (optional): Specifies the index of the target element(s) relative to the selected element. It starts at 1 and defaults to 1 if omitted. Not valid if used with a "double combinator". 43 | - `inclusion-direction` (optional): Only valid if `nth-index` is specified. Determines the direction of including matching elements. 44 | - `<`: Includes matching elements from the specified `nth-index` toward the element (inner/closer elements) 45 | - `>`: Includes matching elements from the specified `nth-index` away from the element (outer/farther elements) 46 | - `selector` (optional): Specifies a selector to match against the target element(s). If not provided, any selector will match. 47 | 48 | ⚠️ Keep in mind that you cannot use any spaces characters in your utility, so if your selector requires a space, use an underscore `_` instead, (e.g. `pattern-[+3<;div_a]:underline`). 49 | 50 | ## Getting started 51 | 52 | ### Installation 53 | 54 | ```bash 55 | npm install tailwindcss-selector-patterns 56 | ``` 57 | 58 | ### Tailwind CSS Configuration 59 | 60 | ```js 61 | // tailwind.config.js 62 | module.exports = { 63 | theme: { 64 | // ... 65 | }, 66 | plugins: [ 67 | require('tailwindcss-selector-patterns'), 68 | // ... 69 | ], 70 | } 71 | ``` 72 | 73 | ### Usage 74 | 75 | ```html 76 | 77 |
78 |
79 |
80 |
81 |
82 | 83 |
84 |
85 |
86 | 87 |
88 |
89 |
90 |
91 |
92 |
93 | ``` 94 | 95 | ## Examples 96 | 97 | Want to try it out for yourself? Take `tailwindcss-selector-patterns` for a spin [on Tailwind Play](https://play.tailwindcss.com/Yx80jD2QX5). 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
Plugin UsageImplementation in CSS
pattern-[+]x + y
pattern-[++]x ~ y
pattern-[+3]x + * + * + y
pattern-[+3<]x + y, x + * + y, x + * + * + y
pattern-[+3>]x + * + * ~ y
pattern-[-]y:has(+ x)
pattern-[--]y:has(~ x)
pattern-[-3]y:has(+ * + * + x)
pattern-[-3<]y:has(+ x, + * + x, + * + * + x)
pattern-[-3>]y:has(~ * + * + x)
pattern-[%]y:has(+ x),
x + y
pattern-[%%]y:has(~ x),
x ~ y
pattern-[%3]y:has(+ * + * + x),
x + * + * + y
pattern-[%3<]y:has(+ x, + * + x, + * + * + x),
x + y, x + * + y, x + * + * + y
pattern-[%3>]y:has(~ * + * + x),
x + * + * ~ y
pattern-[>]x > y
pattern-[>>]x y
pattern-[>2]x > * > y
pattern-[>2<]x > y, x > * > y
pattern-[>2>]x > * y
pattern-[<]y:has(> x)
pattern-[<<]y:has(x)
pattern-[<2]y:has(> * > x)
pattern-[<2<]y:has(> x, > * > x)
pattern-[<2>]y:has(* > x)
pattern-[^]y:has(> x),
x > y
pattern-[^^]y:has(x),
x y
pattern-[^2]y:has(> * > x),
x > * > y
pattern-[^2<]y:has(> x, > * > x),
x > y, x > * > y
pattern-[^2>]y:has(* > x),
x > * y
229 | 230 | --- 231 | 232 | I hope you find `tailwindcss-selector-patterns` a valuable addition to your projects. If you have any issues or suggestions, don't hesitate to open an issue or pull request. 233 | 234 | If you liked this, you might also like my other Tailwind CSS plugins: 235 | * [tailwindcss-multi](https://github.com/brandonmcconnell/tailwindcss-multi): Group utilities together by variant 236 | * [tailwindcss-signals](https://github.com/brandonmcconnell/tailwindcss-signals): Apply styles based on parent or ancestor state, a state-driven alterative to groups 237 | * [tailwindcss-members](https://github.com/brandonmcconnell/tailwindcss-members): Apply styles based on child or descendant state, the inverse of groups 238 | * [tailwindcss-mixins](https://github.com/brandonmcconnell/tailwindcss-mixins): Construct reusable & aliased sets of utilities inline 239 | * [tailwindcss-selector-patterns](https://github.com/brandonmcconnell/tailwindcss-selector-patterns): Dynamic CSS selector patterns 240 | * [tailwindcss-js](https://github.com/brandonmcconnell/tailwindcss-js): Effortless build-time JS script injection 241 | * [tailwind-lerp-colors](https://github.com/brandonmcconnell/tailwind-lerp-colors): Expand your color horizons and take the fuss out of generating new—or expanding existing—color palettes 242 | * [tailwindcss-directional-shadows](https://github.com/brandonmcconnell/tailwindcss-directional-shadows): Supercharge your shadow utilities with added directional support (includes directional `shadow-border` utilities too ✨) 243 | -------------------------------------------------------------------------------- /dist/index.cjs: -------------------------------------------------------------------------------- 1 | function e(e){var n={exports:{}};return e(n,n.exports),n.exports}var n=e(function(e,n){function t(e,n){return{handler:e,config:n}}Object.defineProperty(n,"__esModule",{value:!0}),Object.defineProperty(n,"default",{enumerable:!0,get:function(){return r}}),t.withOptions=function(e,n=(()=>({}))){const t=function(t){return{__options:t,handler:e(t),config:n(t)}};return t.__isOptionsFunction=!0,t.__pluginFunction=e,t.__configFunction=n,t};const r=t}),t=e(function(e,t){function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return o}});const o=/*#__PURE__*/r(n).default}),r=(0,(t.__esModule?t:{default:t}).default)(function(e){(0,e.matchVariant)("pattern",function(e){var n=e.split(";").map(function(e){return e.trim()}),t=n[0],r=n[1],o=void 0===r?"*":r,i=n[2];if(!t)throw new Error("No pattern provided in Tailwind CSS selector pattern '"+e+"'");var a="*"===o?"":o;if(i)throw new Error("Found more than 2 semicolon-delimited (;) arguments in Tailwind CSS selector pattern '"+e+"'");var c=t[0],u=["+","-","%",">","<","^"];if(!c||!u.includes(c))throw new Error("Combinator used '"+c+"' in Tailwind CSS selector pattern '"+e+"' is not one of the valid combinators: "+u.join(", "));var l=t[1]===c;if(!l&&u.includes(t[1]))throw new Error("Second character in Tailwind CSS selector pattern '"+e+"' ('"+t[1]+"') is a valid combinator but does not match the first combinator used ('"+c+"')");var s=t.slice(l?2:1);if(l&&s)throw new Error("Double combinator '"+c.repeat(2)+"' in Tailwind CSS selector pattern '"+e+"' can only be followed by an optional selector argument, delimited by a semicolon; instead found '"+s+"'");var d=!l&&["<",">"].includes(s.slice(-1)),p=l?[]:d?[s.slice(0,-1),s.slice(-1)]:s?[s]:[],f=p[0],h=void 0===f?"1":f,m=p[1],w=Number(h);if(console.log({pattern:t,hasDir:d,_nthIndex:h,dir:m,nthIndex:w}),!Number.isFinite(w))throw new Error("Invalid nth-index value '"+h+"' in Tailwind CSS selector pattern '"+e+"'");if(!(w>0))throw new Error("nth-index value '"+w+"' in Tailwind CSS selector pattern '"+e+"' must be greater than 0");var b="";return"+"!==c&&"%"!==c||(l?b+="& ~ "+o:m?"<"===m?b+=[].concat(Array(w)).map(function(e,n){return"& + "+"* + ".repeat(n)+o}).join(", "):">"===m&&(b+="& "+"+ * ".repeat(w-1)+"~ "+o):b+="& + "+"* + ".repeat(w-1)+o),"%"===c&&(b+=", "),"-"!==c&&"%"!==c||(l?b+=a+":has(~ &)":m?"<"===m?b+=a+":has("+[].concat(Array(w)).map(function(e,n){return"+ "+"* + ".repeat(n)+"&"}).join(", ")+")":">"===m&&(b+=a+":has(~"+" * +".repeat(w-1)+" &)"):b+=a+":has("+"+ * ".repeat(w-1)+"+ &)"),">"!==c&&"^"!==c||(l?b+="& "+o:m?"<"===m?b+=[].concat(Array(w)).map(function(e,n){return"& > "+"* > ".repeat(n)+o}).join(", "):">"===m&&(b+="& "+"> * ".repeat(w-1)+o):b+="& "+"> * ".repeat(w-1)+"> "+o),"^"===c&&(b+=", "),"<"!==c&&"^"!==c||(l?b+=a+":has(&)":m?"<"===m?b+=a+":has("+[].concat(Array(w)).map(function(e,n){return"> * ".repeat(n)+"> &"}).join(", ")+")":">"===m&&(b+=a+":has("+"* > ".repeat(w-1)+"&)"):b+=a+":has("+"> * ".repeat(w-1)+"> &)"),":is("+b+")"})});module.exports=r; 2 | //# sourceMappingURL=index.cjs.map 3 | -------------------------------------------------------------------------------- /dist/index.cjs.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.cjs","sources":["../node_modules/tailwindcss/lib/util/createPlugin.js","../node_modules/tailwindcss/lib/public/create-plugin.js","../index.ts","../node_modules/tailwindcss/plugin.js"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function() {\n return _default;\n }\n});\nfunction createPlugin(plugin, config) {\n return {\n handler: plugin,\n config\n };\n}\ncreatePlugin.withOptions = function(pluginFunction, configFunction = ()=>({})) {\n const optionsFunction = function(options) {\n return {\n __options: options,\n handler: pluginFunction(options),\n config: configFunction(options)\n };\n };\n optionsFunction.__isOptionsFunction = true;\n // Expose plugin dependencies so that `object-hash` returns a different\n // value if anything here changes, to ensure a rebuild is triggered.\n optionsFunction.__pluginFunction = pluginFunction;\n optionsFunction.__configFunction = configFunction;\n return optionsFunction;\n};\nconst _default = createPlugin;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function() {\n return _default;\n }\n});\nconst _createPlugin = /*#__PURE__*/ _interop_require_default(require(\"../util/createPlugin\"));\nfunction _interop_require_default(obj) {\n return obj && obj.__esModule ? obj : {\n default: obj\n };\n}\nconst _default = _createPlugin.default;\n","import plugin from 'tailwindcss/plugin.js';\n\nexport default plugin(({ matchVariant }) => {\n matchVariant('pattern', (pattern_selector) => {\n const [pattern, selector = '*', extraneous] = pattern_selector.split(';').map((str) => str.trim());\n if (!pattern) throw new Error(`No pattern provided in Tailwind CSS selector pattern '${pattern_selector}'`);\n const optionalSelector = selector === '*' ? '' : selector;\n if (extraneous)\n throw new Error(\n `Found more than 2 semicolon-delimited (;) arguments in Tailwind CSS selector pattern '${pattern_selector}'`\n );\n\n const combinator = pattern[0];\n const validCombinatorSymbols = ['+', '-', '%', '>', '<', '^'];\n if (!combinator || !validCombinatorSymbols.includes(combinator))\n throw new Error(\n `Combinator used '${combinator}' in Tailwind CSS selector pattern '${pattern_selector}' is not one of the valid combinators: ${validCombinatorSymbols.join(\n ', '\n )}`\n );\n\n const isDoubleCombinator = pattern[1] === combinator;\n if (!isDoubleCombinator && validCombinatorSymbols.includes(pattern[1] as unknown as string))\n throw new Error(\n `Second character in Tailwind CSS selector pattern '${pattern_selector}' ('${pattern[1]}') is a valid combinator but does not match the first combinator used ('${combinator}')`\n );\n\n const nthIndex_dir = isDoubleCombinator ? pattern.slice(2) : pattern.slice(1);\n if (isDoubleCombinator && nthIndex_dir)\n throw new Error(\n `Double combinator '${combinator.repeat(\n 2\n )}' in Tailwind CSS selector pattern '${pattern_selector}' can only be followed by an optional selector argument, delimited by a semicolon; instead found '${nthIndex_dir}'`\n );\n\n const validDirSymbols = ['<', '>'];\n const hasDir = !isDoubleCombinator && validDirSymbols.includes(nthIndex_dir.slice(-1));\n const [_nthIndex = '1', dir] = !isDoubleCombinator\n ? hasDir\n ? [nthIndex_dir.slice(0, -1), nthIndex_dir.slice(-1)]\n : nthIndex_dir\n ? [nthIndex_dir]\n : []\n : [];\n\n const nthIndex = Number(_nthIndex);\n console.log({\n pattern,\n hasDir,\n _nthIndex,\n dir,\n nthIndex,\n });\n if (!Number.isFinite(nthIndex))\n throw new Error(`Invalid nth-index value '${_nthIndex}' in Tailwind CSS selector pattern '${pattern_selector}'`);\n if (!(nthIndex > 0))\n throw new Error(\n `nth-index value '${nthIndex}' in Tailwind CSS selector pattern '${pattern_selector}' must be greater than 0`\n );\n\n let result = '';\n\n if (combinator === '+' || combinator === '%') {\n if (isDoubleCombinator) {\n result += `& ~ ${selector}`;\n } else if (!dir) {\n result += `& + ${'* + '.repeat(nthIndex - 1)}${selector}`;\n } else if (dir === '<') {\n result += [...Array(nthIndex)].map((_, i) => `& + ${'* + '.repeat(i)}${selector}`).join(', ');\n } else if (dir === '>') {\n result += `& ${'+ * '.repeat(nthIndex - 1)}~ ${selector}`;\n }\n }\n if (combinator === '%') result += `, `;\n if (combinator === '-' || combinator === '%') {\n if (isDoubleCombinator) {\n result += `${optionalSelector}:has(~ &)`;\n } else if (!dir) {\n result += `${optionalSelector}:has(${'+ * '.repeat(nthIndex - 1)}+ &)`;\n } else if (dir === '<') {\n result += `${optionalSelector}:has(${[...Array(nthIndex)].map((_, i) => `+ ${'* + '.repeat(i)}&`).join(', ')})`;\n } else if (dir === '>') {\n result += `${optionalSelector}:has(~${' * +'.repeat(nthIndex - 1)} &)`;\n }\n }\n if (combinator === '>' || combinator === '^') {\n if (isDoubleCombinator) {\n result += `& ${selector}`;\n } else if (!dir) {\n result += `& ${'> * '.repeat(nthIndex - 1)}> ${selector}`;\n } else if (dir === '<') {\n result += [...Array(nthIndex)].map((_, i) => `& > ${'* > '.repeat(i)}${selector}`).join(', ');\n } else if (dir === '>') {\n result += `& ${'> * '.repeat(nthIndex - 1)}${selector}`;\n }\n }\n if (combinator === '^') result += `, `;\n if (combinator === '<' || combinator === '^') {\n if (isDoubleCombinator) {\n result += `${optionalSelector}:has(&)`;\n } else if (!dir) {\n result += `${optionalSelector}:has(${'> * '.repeat(nthIndex - 1)}> &)`;\n } else if (dir === '<') {\n result += `${optionalSelector}:has(${[...Array(nthIndex)].map((_, i) => `${'> * '.repeat(i)}> &`).join(', ')})`;\n } else if (dir === '>') {\n result += `${optionalSelector}:has(${'* > '.repeat(nthIndex - 1)}&)`;\n }\n }\n return `:is(${result})`;\n });\n});\n","let createPlugin = require('./lib/public/create-plugin')\nmodule.exports = (createPlugin.__esModule ? createPlugin : { default: createPlugin }).default\n"],"names":["createPlugin","plugin","config","handler","Object","defineProperty","exports","value","enumerable","get","_default","withOptions","pluginFunction","configFunction","optionsFunction","options","__options","__isOptionsFunction","__pluginFunction","__configFunction","_interop_require_default","obj","__esModule","default","require$$0","_ref","matchVariant","pattern_selector","_pattern_selector$spl","split","map","str","trim","pattern","_pattern_selector$spl2","selector","extraneous","Error","optionalSelector","combinator","validCombinatorSymbols","includes","join","isDoubleCombinator","nthIndex_dir","slice","repeat","hasDir","_ref2","_ref2$","_nthIndex","dir","nthIndex","Number","console","log","isFinite","result","concat","Array","_","i"],"mappings":"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"} -------------------------------------------------------------------------------- /dist/index.modern.js: -------------------------------------------------------------------------------- 1 | function e(e){var t={exports:{}};return e(t,t.exports),t.exports}var t=e(function(e,t){function n(e,t){return{handler:e,config:t}}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return r}}),n.withOptions=function(e,t=(()=>({}))){const n=function(n){return{__options:n,handler:e(n),config:t(n)}};return n.__isOptionsFunction=!0,n.__pluginFunction=e,n.__configFunction=t,n};const r=n}),n=e(function(e,n){function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(n,"__esModule",{value:!0}),Object.defineProperty(n,"default",{enumerable:!0,get:function(){return o}});const o=/*#__PURE__*/r(t).default}),r=(0,(n.__esModule?n:{default:n}).default)(({matchVariant:e})=>{e("pattern",e=>{const[t,n="*",r]=e.split(";").map(e=>e.trim());if(!t)throw new Error(`No pattern provided in Tailwind CSS selector pattern '${e}'`);const o="*"===n?"":n;if(r)throw new Error(`Found more than 2 semicolon-delimited (;) arguments in Tailwind CSS selector pattern '${e}'`);const i=t[0],a=["+","-","%",">","<","^"];if(!i||!a.includes(i))throw new Error(`Combinator used '${i}' in Tailwind CSS selector pattern '${e}' is not one of the valid combinators: ${a.join(", ")}`);const s=t[1]===i;if(!s&&a.includes(t[1]))throw new Error(`Second character in Tailwind CSS selector pattern '${e}' ('${t[1]}') is a valid combinator but does not match the first combinator used ('${i}')`);const l=t.slice(s?2:1);if(s&&l)throw new Error(`Double combinator '${i.repeat(2)}' in Tailwind CSS selector pattern '${e}' can only be followed by an optional selector argument, delimited by a semicolon; instead found '${l}'`);const c=!s&&["<",">"].includes(l.slice(-1)),[u="1",d]=s?[]:c?[l.slice(0,-1),l.slice(-1)]:l?[l]:[],$=Number(u);if(console.log({pattern:t,hasDir:c,_nthIndex:u,dir:d,nthIndex:$}),!Number.isFinite($))throw new Error(`Invalid nth-index value '${u}' in Tailwind CSS selector pattern '${e}'`);if(!($>0))throw new Error(`nth-index value '${$}' in Tailwind CSS selector pattern '${e}' must be greater than 0`);let p="";return"+"!==i&&"%"!==i||(s?p+=`& ~ ${n}`:d?"<"===d?p+=[...Array($)].map((e,t)=>`& + ${"* + ".repeat(t)}${n}`).join(", "):">"===d&&(p+=`& ${"+ * ".repeat($-1)}~ ${n}`):p+=`& + ${"* + ".repeat($-1)}${n}`),"%"===i&&(p+=", "),"-"!==i&&"%"!==i||(s?p+=`${o}:has(~ &)`:d?"<"===d?p+=`${o}:has(${[...Array($)].map((e,t)=>`+ ${"* + ".repeat(t)}&`).join(", ")})`:">"===d&&(p+=`${o}:has(~${" * +".repeat($-1)} &)`):p+=`${o}:has(${"+ * ".repeat($-1)}+ &)`),">"!==i&&"^"!==i||(s?p+=`& ${n}`:d?"<"===d?p+=[...Array($)].map((e,t)=>`& > ${"* > ".repeat(t)}${n}`).join(", "):">"===d&&(p+=`& ${"> * ".repeat($-1)}${n}`):p+=`& ${"> * ".repeat($-1)}> ${n}`),"^"===i&&(p+=", "),"<"!==i&&"^"!==i||(s?p+=`${o}:has(&)`:d?"<"===d?p+=`${o}:has(${[...Array($)].map((e,t)=>`${"> * ".repeat(t)}> &`).join(", ")})`:">"===d&&(p+=`${o}:has(${"* > ".repeat($-1)}&)`):p+=`${o}:has(${"> * ".repeat($-1)}> &)`),`:is(${p})`})});export{r as default}; 2 | //# sourceMappingURL=index.modern.js.map 3 | -------------------------------------------------------------------------------- /dist/index.modern.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.modern.js","sources":["../node_modules/tailwindcss/lib/util/createPlugin.js","../node_modules/tailwindcss/lib/public/create-plugin.js","../index.ts","../node_modules/tailwindcss/plugin.js"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function() {\n return _default;\n }\n});\nfunction createPlugin(plugin, config) {\n return {\n handler: plugin,\n config\n };\n}\ncreatePlugin.withOptions = function(pluginFunction, configFunction = ()=>({})) {\n const optionsFunction = function(options) {\n return {\n __options: options,\n handler: pluginFunction(options),\n config: configFunction(options)\n };\n };\n optionsFunction.__isOptionsFunction = true;\n // Expose plugin dependencies so that `object-hash` returns a different\n // value if anything here changes, to ensure a rebuild is triggered.\n optionsFunction.__pluginFunction = pluginFunction;\n optionsFunction.__configFunction = configFunction;\n return optionsFunction;\n};\nconst _default = createPlugin;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function() {\n return _default;\n }\n});\nconst _createPlugin = /*#__PURE__*/ _interop_require_default(require(\"../util/createPlugin\"));\nfunction _interop_require_default(obj) {\n return obj && obj.__esModule ? obj : {\n default: obj\n };\n}\nconst _default = _createPlugin.default;\n","import plugin from 'tailwindcss/plugin.js';\n\nexport default plugin(({ matchVariant }) => {\n matchVariant('pattern', (pattern_selector) => {\n const [pattern, selector = '*', extraneous] = pattern_selector.split(';').map((str) => str.trim());\n if (!pattern) throw new Error(`No pattern provided in Tailwind CSS selector pattern '${pattern_selector}'`);\n const optionalSelector = selector === '*' ? '' : selector;\n if (extraneous)\n throw new Error(\n `Found more than 2 semicolon-delimited (;) arguments in Tailwind CSS selector pattern '${pattern_selector}'`\n );\n\n const combinator = pattern[0];\n const validCombinatorSymbols = ['+', '-', '%', '>', '<', '^'];\n if (!combinator || !validCombinatorSymbols.includes(combinator))\n throw new Error(\n `Combinator used '${combinator}' in Tailwind CSS selector pattern '${pattern_selector}' is not one of the valid combinators: ${validCombinatorSymbols.join(\n ', '\n )}`\n );\n\n const isDoubleCombinator = pattern[1] === combinator;\n if (!isDoubleCombinator && validCombinatorSymbols.includes(pattern[1] as unknown as string))\n throw new Error(\n `Second character in Tailwind CSS selector pattern '${pattern_selector}' ('${pattern[1]}') is a valid combinator but does not match the first combinator used ('${combinator}')`\n );\n\n const nthIndex_dir = isDoubleCombinator ? pattern.slice(2) : pattern.slice(1);\n if (isDoubleCombinator && nthIndex_dir)\n throw new Error(\n `Double combinator '${combinator.repeat(\n 2\n )}' in Tailwind CSS selector pattern '${pattern_selector}' can only be followed by an optional selector argument, delimited by a semicolon; instead found '${nthIndex_dir}'`\n );\n\n const validDirSymbols = ['<', '>'];\n const hasDir = !isDoubleCombinator && validDirSymbols.includes(nthIndex_dir.slice(-1));\n const [_nthIndex = '1', dir] = !isDoubleCombinator\n ? hasDir\n ? [nthIndex_dir.slice(0, -1), nthIndex_dir.slice(-1)]\n : nthIndex_dir\n ? [nthIndex_dir]\n : []\n : [];\n\n const nthIndex = Number(_nthIndex);\n console.log({\n pattern,\n hasDir,\n _nthIndex,\n dir,\n nthIndex,\n });\n if (!Number.isFinite(nthIndex))\n throw new Error(`Invalid nth-index value '${_nthIndex}' in Tailwind CSS selector pattern '${pattern_selector}'`);\n if (!(nthIndex > 0))\n throw new Error(\n `nth-index value '${nthIndex}' in Tailwind CSS selector pattern '${pattern_selector}' must be greater than 0`\n );\n\n let result = '';\n\n if (combinator === '+' || combinator === '%') {\n if (isDoubleCombinator) {\n result += `& ~ ${selector}`;\n } else if (!dir) {\n result += `& + ${'* + '.repeat(nthIndex - 1)}${selector}`;\n } else if (dir === '<') {\n result += [...Array(nthIndex)].map((_, i) => `& + ${'* + '.repeat(i)}${selector}`).join(', ');\n } else if (dir === '>') {\n result += `& ${'+ * '.repeat(nthIndex - 1)}~ ${selector}`;\n }\n }\n if (combinator === '%') result += `, `;\n if (combinator === '-' || combinator === '%') {\n if (isDoubleCombinator) {\n result += `${optionalSelector}:has(~ &)`;\n } else if (!dir) {\n result += `${optionalSelector}:has(${'+ * '.repeat(nthIndex - 1)}+ &)`;\n } else if (dir === '<') {\n result += `${optionalSelector}:has(${[...Array(nthIndex)].map((_, i) => `+ ${'* + '.repeat(i)}&`).join(', ')})`;\n } else if (dir === '>') {\n result += `${optionalSelector}:has(~${' * +'.repeat(nthIndex - 1)} &)`;\n }\n }\n if (combinator === '>' || combinator === '^') {\n if (isDoubleCombinator) {\n result += `& ${selector}`;\n } else if (!dir) {\n result += `& ${'> * '.repeat(nthIndex - 1)}> ${selector}`;\n } else if (dir === '<') {\n result += [...Array(nthIndex)].map((_, i) => `& > ${'* > '.repeat(i)}${selector}`).join(', ');\n } else if (dir === '>') {\n result += `& ${'> * '.repeat(nthIndex - 1)}${selector}`;\n }\n }\n if (combinator === '^') result += `, `;\n if (combinator === '<' || combinator === '^') {\n if (isDoubleCombinator) {\n result += `${optionalSelector}:has(&)`;\n } else if (!dir) {\n result += `${optionalSelector}:has(${'> * '.repeat(nthIndex - 1)}> &)`;\n } else if (dir === '<') {\n result += `${optionalSelector}:has(${[...Array(nthIndex)].map((_, i) => `${'> * '.repeat(i)}> &`).join(', ')})`;\n } else if (dir === '>') {\n result += `${optionalSelector}:has(${'* > '.repeat(nthIndex - 1)}&)`;\n }\n }\n return `:is(${result})`;\n });\n});\n","let createPlugin = require('./lib/public/create-plugin')\nmodule.exports = (createPlugin.__esModule ? createPlugin : { default: createPlugin }).default\n"],"names":["createPlugin","plugin","config","handler","Object","defineProperty","exports","value","enumerable","get","_default","withOptions","pluginFunction","configFunction","optionsFunction","options","__options","__isOptionsFunction","__pluginFunction","__configFunction","_interop_require_default","obj","__esModule","default","require$$0","matchVariant","pattern_selector","pattern","selector","extraneous","split","map","str","trim","Error","optionalSelector","combinator","validCombinatorSymbols","includes","join","isDoubleCombinator","nthIndex_dir","slice","repeat","hasDir","_nthIndex","dir","nthIndex","Number","console","log","isFinite","result","Array","_","i"],"mappings":"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"} -------------------------------------------------------------------------------- /dist/index.module.js: -------------------------------------------------------------------------------- 1 | function e(e){var n={exports:{}};return e(n,n.exports),n.exports}var n=e(function(e,n){function t(e,n){return{handler:e,config:n}}Object.defineProperty(n,"__esModule",{value:!0}),Object.defineProperty(n,"default",{enumerable:!0,get:function(){return r}}),t.withOptions=function(e,n=(()=>({}))){const t=function(t){return{__options:t,handler:e(t),config:n(t)}};return t.__isOptionsFunction=!0,t.__pluginFunction=e,t.__configFunction=n,t};const r=t}),t=e(function(e,t){function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return o}});const o=/*#__PURE__*/r(n).default}),r=(0,(t.__esModule?t:{default:t}).default)(function(e){(0,e.matchVariant)("pattern",function(e){var n=e.split(";").map(function(e){return e.trim()}),t=n[0],r=n[1],o=void 0===r?"*":r,i=n[2];if(!t)throw new Error("No pattern provided in Tailwind CSS selector pattern '"+e+"'");var a="*"===o?"":o;if(i)throw new Error("Found more than 2 semicolon-delimited (;) arguments in Tailwind CSS selector pattern '"+e+"'");var c=t[0],u=["+","-","%",">","<","^"];if(!c||!u.includes(c))throw new Error("Combinator used '"+c+"' in Tailwind CSS selector pattern '"+e+"' is not one of the valid combinators: "+u.join(", "));var l=t[1]===c;if(!l&&u.includes(t[1]))throw new Error("Second character in Tailwind CSS selector pattern '"+e+"' ('"+t[1]+"') is a valid combinator but does not match the first combinator used ('"+c+"')");var s=t.slice(l?2:1);if(l&&s)throw new Error("Double combinator '"+c.repeat(2)+"' in Tailwind CSS selector pattern '"+e+"' can only be followed by an optional selector argument, delimited by a semicolon; instead found '"+s+"'");var d=!l&&["<",">"].includes(s.slice(-1)),p=l?[]:d?[s.slice(0,-1),s.slice(-1)]:s?[s]:[],f=p[0],h=void 0===f?"1":f,m=p[1],w=Number(h);if(console.log({pattern:t,hasDir:d,_nthIndex:h,dir:m,nthIndex:w}),!Number.isFinite(w))throw new Error("Invalid nth-index value '"+h+"' in Tailwind CSS selector pattern '"+e+"'");if(!(w>0))throw new Error("nth-index value '"+w+"' in Tailwind CSS selector pattern '"+e+"' must be greater than 0");var b="";return"+"!==c&&"%"!==c||(l?b+="& ~ "+o:m?"<"===m?b+=[].concat(Array(w)).map(function(e,n){return"& + "+"* + ".repeat(n)+o}).join(", "):">"===m&&(b+="& "+"+ * ".repeat(w-1)+"~ "+o):b+="& + "+"* + ".repeat(w-1)+o),"%"===c&&(b+=", "),"-"!==c&&"%"!==c||(l?b+=a+":has(~ &)":m?"<"===m?b+=a+":has("+[].concat(Array(w)).map(function(e,n){return"+ "+"* + ".repeat(n)+"&"}).join(", ")+")":">"===m&&(b+=a+":has(~"+" * +".repeat(w-1)+" &)"):b+=a+":has("+"+ * ".repeat(w-1)+"+ &)"),">"!==c&&"^"!==c||(l?b+="& "+o:m?"<"===m?b+=[].concat(Array(w)).map(function(e,n){return"& > "+"* > ".repeat(n)+o}).join(", "):">"===m&&(b+="& "+"> * ".repeat(w-1)+o):b+="& "+"> * ".repeat(w-1)+"> "+o),"^"===c&&(b+=", "),"<"!==c&&"^"!==c||(l?b+=a+":has(&)":m?"<"===m?b+=a+":has("+[].concat(Array(w)).map(function(e,n){return"> * ".repeat(n)+"> &"}).join(", ")+")":">"===m&&(b+=a+":has("+"* > ".repeat(w-1)+"&)"):b+=a+":has("+"> * ".repeat(w-1)+"> &)"),":is("+b+")"})});export{r as default}; 2 | //# sourceMappingURL=index.module.js.map 3 | -------------------------------------------------------------------------------- /dist/index.module.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.module.js","sources":["../node_modules/tailwindcss/lib/util/createPlugin.js","../node_modules/tailwindcss/lib/public/create-plugin.js","../index.ts","../node_modules/tailwindcss/plugin.js"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function() {\n return _default;\n }\n});\nfunction createPlugin(plugin, config) {\n return {\n handler: plugin,\n config\n };\n}\ncreatePlugin.withOptions = function(pluginFunction, configFunction = ()=>({})) {\n const optionsFunction = function(options) {\n return {\n __options: options,\n handler: pluginFunction(options),\n config: configFunction(options)\n };\n };\n optionsFunction.__isOptionsFunction = true;\n // Expose plugin dependencies so that `object-hash` returns a different\n // value if anything here changes, to ensure a rebuild is triggered.\n optionsFunction.__pluginFunction = pluginFunction;\n optionsFunction.__configFunction = configFunction;\n return optionsFunction;\n};\nconst _default = createPlugin;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function() {\n return _default;\n }\n});\nconst _createPlugin = /*#__PURE__*/ _interop_require_default(require(\"../util/createPlugin\"));\nfunction _interop_require_default(obj) {\n return obj && obj.__esModule ? obj : {\n default: obj\n };\n}\nconst _default = _createPlugin.default;\n","import plugin from 'tailwindcss/plugin.js';\n\nexport default plugin(({ matchVariant }) => {\n matchVariant('pattern', (pattern_selector) => {\n const [pattern, selector = '*', extraneous] = pattern_selector.split(';').map((str) => str.trim());\n if (!pattern) throw new Error(`No pattern provided in Tailwind CSS selector pattern '${pattern_selector}'`);\n const optionalSelector = selector === '*' ? '' : selector;\n if (extraneous)\n throw new Error(\n `Found more than 2 semicolon-delimited (;) arguments in Tailwind CSS selector pattern '${pattern_selector}'`\n );\n\n const combinator = pattern[0];\n const validCombinatorSymbols = ['+', '-', '%', '>', '<', '^'];\n if (!combinator || !validCombinatorSymbols.includes(combinator))\n throw new Error(\n `Combinator used '${combinator}' in Tailwind CSS selector pattern '${pattern_selector}' is not one of the valid combinators: ${validCombinatorSymbols.join(\n ', '\n )}`\n );\n\n const isDoubleCombinator = pattern[1] === combinator;\n if (!isDoubleCombinator && validCombinatorSymbols.includes(pattern[1] as unknown as string))\n throw new Error(\n `Second character in Tailwind CSS selector pattern '${pattern_selector}' ('${pattern[1]}') is a valid combinator but does not match the first combinator used ('${combinator}')`\n );\n\n const nthIndex_dir = isDoubleCombinator ? pattern.slice(2) : pattern.slice(1);\n if (isDoubleCombinator && nthIndex_dir)\n throw new Error(\n `Double combinator '${combinator.repeat(\n 2\n )}' in Tailwind CSS selector pattern '${pattern_selector}' can only be followed by an optional selector argument, delimited by a semicolon; instead found '${nthIndex_dir}'`\n );\n\n const validDirSymbols = ['<', '>'];\n const hasDir = !isDoubleCombinator && validDirSymbols.includes(nthIndex_dir.slice(-1));\n const [_nthIndex = '1', dir] = !isDoubleCombinator\n ? hasDir\n ? [nthIndex_dir.slice(0, -1), nthIndex_dir.slice(-1)]\n : nthIndex_dir\n ? [nthIndex_dir]\n : []\n : [];\n\n const nthIndex = Number(_nthIndex);\n console.log({\n pattern,\n hasDir,\n _nthIndex,\n dir,\n nthIndex,\n });\n if (!Number.isFinite(nthIndex))\n throw new Error(`Invalid nth-index value '${_nthIndex}' in Tailwind CSS selector pattern '${pattern_selector}'`);\n if (!(nthIndex > 0))\n throw new Error(\n `nth-index value '${nthIndex}' in Tailwind CSS selector pattern '${pattern_selector}' must be greater than 0`\n );\n\n let result = '';\n\n if (combinator === '+' || combinator === '%') {\n if (isDoubleCombinator) {\n result += `& ~ ${selector}`;\n } else if (!dir) {\n result += `& + ${'* + '.repeat(nthIndex - 1)}${selector}`;\n } else if (dir === '<') {\n result += [...Array(nthIndex)].map((_, i) => `& + ${'* + '.repeat(i)}${selector}`).join(', ');\n } else if (dir === '>') {\n result += `& ${'+ * '.repeat(nthIndex - 1)}~ ${selector}`;\n }\n }\n if (combinator === '%') result += `, `;\n if (combinator === '-' || combinator === '%') {\n if (isDoubleCombinator) {\n result += `${optionalSelector}:has(~ &)`;\n } else if (!dir) {\n result += `${optionalSelector}:has(${'+ * '.repeat(nthIndex - 1)}+ &)`;\n } else if (dir === '<') {\n result += `${optionalSelector}:has(${[...Array(nthIndex)].map((_, i) => `+ ${'* + '.repeat(i)}&`).join(', ')})`;\n } else if (dir === '>') {\n result += `${optionalSelector}:has(~${' * +'.repeat(nthIndex - 1)} &)`;\n }\n }\n if (combinator === '>' || combinator === '^') {\n if (isDoubleCombinator) {\n result += `& ${selector}`;\n } else if (!dir) {\n result += `& ${'> * '.repeat(nthIndex - 1)}> ${selector}`;\n } else if (dir === '<') {\n result += [...Array(nthIndex)].map((_, i) => `& > ${'* > '.repeat(i)}${selector}`).join(', ');\n } else if (dir === '>') {\n result += `& ${'> * '.repeat(nthIndex - 1)}${selector}`;\n }\n }\n if (combinator === '^') result += `, `;\n if (combinator === '<' || combinator === '^') {\n if (isDoubleCombinator) {\n result += `${optionalSelector}:has(&)`;\n } else if (!dir) {\n result += `${optionalSelector}:has(${'> * '.repeat(nthIndex - 1)}> &)`;\n } else if (dir === '<') {\n result += `${optionalSelector}:has(${[...Array(nthIndex)].map((_, i) => `${'> * '.repeat(i)}> &`).join(', ')})`;\n } else if (dir === '>') {\n result += `${optionalSelector}:has(${'* > '.repeat(nthIndex - 1)}&)`;\n }\n }\n return `:is(${result})`;\n });\n});\n","let createPlugin = require('./lib/public/create-plugin')\nmodule.exports = (createPlugin.__esModule ? createPlugin : { default: createPlugin }).default\n"],"names":["createPlugin","plugin","config","handler","Object","defineProperty","exports","value","enumerable","get","_default","withOptions","pluginFunction","configFunction","optionsFunction","options","__options","__isOptionsFunction","__pluginFunction","__configFunction","_interop_require_default","obj","__esModule","default","require$$0","_ref","matchVariant","pattern_selector","_pattern_selector$spl","split","map","str","trim","pattern","_pattern_selector$spl2","selector","extraneous","Error","optionalSelector","combinator","validCombinatorSymbols","includes","join","isDoubleCombinator","nthIndex_dir","slice","repeat","hasDir","_ref2","_ref2$","_nthIndex","dir","nthIndex","Number","console","log","isFinite","result","concat","Array","_","i"],"mappings":"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"} -------------------------------------------------------------------------------- /dist/index.umd.js: -------------------------------------------------------------------------------- 1 | !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e||self).tailwindcssSelectorPatterns=n()}(this,function(){function e(e){var n={exports:{}};return e(n,n.exports),n.exports}var n=e(function(e,n){function t(e,n){return{handler:e,config:n}}Object.defineProperty(n,"__esModule",{value:!0}),Object.defineProperty(n,"default",{enumerable:!0,get:function(){return r}}),t.withOptions=function(e,n=(()=>({}))){const t=function(t){return{__options:t,handler:e(t),config:n(t)}};return t.__isOptionsFunction=!0,t.__pluginFunction=e,t.__configFunction=n,t};const r=t}),t=e(function(e,t){function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return o}});const o=/*#__PURE__*/r(n).default});return(0,(t.__esModule?t:{default:t}).default)(function(e){(0,e.matchVariant)("pattern",function(e){var n=e.split(";").map(function(e){return e.trim()}),t=n[0],r=n[1],o=void 0===r?"*":r,i=n[2];if(!t)throw new Error("No pattern provided in Tailwind CSS selector pattern '"+e+"'");var a="*"===o?"":o;if(i)throw new Error("Found more than 2 semicolon-delimited (;) arguments in Tailwind CSS selector pattern '"+e+"'");var c=t[0],u=["+","-","%",">","<","^"];if(!c||!u.includes(c))throw new Error("Combinator used '"+c+"' in Tailwind CSS selector pattern '"+e+"' is not one of the valid combinators: "+u.join(", "));var l=t[1]===c;if(!l&&u.includes(t[1]))throw new Error("Second character in Tailwind CSS selector pattern '"+e+"' ('"+t[1]+"') is a valid combinator but does not match the first combinator used ('"+c+"')");var s=t.slice(l?2:1);if(l&&s)throw new Error("Double combinator '"+c.repeat(2)+"' in Tailwind CSS selector pattern '"+e+"' can only be followed by an optional selector argument, delimited by a semicolon; instead found '"+s+"'");var d=!l&&["<",">"].includes(s.slice(-1)),f=l?[]:d?[s.slice(0,-1),s.slice(-1)]:s?[s]:[],p=f[0],h=void 0===p?"1":p,m=f[1],w=Number(h);if(console.log({pattern:t,hasDir:d,_nthIndex:h,dir:m,nthIndex:w}),!Number.isFinite(w))throw new Error("Invalid nth-index value '"+h+"' in Tailwind CSS selector pattern '"+e+"'");if(!(w>0))throw new Error("nth-index value '"+w+"' in Tailwind CSS selector pattern '"+e+"' must be greater than 0");var b="";return"+"!==c&&"%"!==c||(l?b+="& ~ "+o:m?"<"===m?b+=[].concat(Array(w)).map(function(e,n){return"& + "+"* + ".repeat(n)+o}).join(", "):">"===m&&(b+="& "+"+ * ".repeat(w-1)+"~ "+o):b+="& + "+"* + ".repeat(w-1)+o),"%"===c&&(b+=", "),"-"!==c&&"%"!==c||(l?b+=a+":has(~ &)":m?"<"===m?b+=a+":has("+[].concat(Array(w)).map(function(e,n){return"+ "+"* + ".repeat(n)+"&"}).join(", ")+")":">"===m&&(b+=a+":has(~"+" * +".repeat(w-1)+" &)"):b+=a+":has("+"+ * ".repeat(w-1)+"+ &)"),">"!==c&&"^"!==c||(l?b+="& "+o:m?"<"===m?b+=[].concat(Array(w)).map(function(e,n){return"& > "+"* > ".repeat(n)+o}).join(", "):">"===m&&(b+="& "+"> * ".repeat(w-1)+o):b+="& "+"> * ".repeat(w-1)+"> "+o),"^"===c&&(b+=", "),"<"!==c&&"^"!==c||(l?b+=a+":has(&)":m?"<"===m?b+=a+":has("+[].concat(Array(w)).map(function(e,n){return"> * ".repeat(n)+"> &"}).join(", ")+")":">"===m&&(b+=a+":has("+"* > ".repeat(w-1)+"&)"):b+=a+":has("+"> * ".repeat(w-1)+"> &)"),":is("+b+")"})})}); 2 | //# sourceMappingURL=index.umd.js.map 3 | -------------------------------------------------------------------------------- /dist/index.umd.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.umd.js","sources":["../node_modules/tailwindcss/lib/util/createPlugin.js","../node_modules/tailwindcss/lib/public/create-plugin.js","../index.ts","../node_modules/tailwindcss/plugin.js"],"sourcesContent":["\"use strict\";\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function() {\n return _default;\n }\n});\nfunction createPlugin(plugin, config) {\n return {\n handler: plugin,\n config\n };\n}\ncreatePlugin.withOptions = function(pluginFunction, configFunction = ()=>({})) {\n const optionsFunction = function(options) {\n return {\n __options: options,\n handler: pluginFunction(options),\n config: configFunction(options)\n };\n };\n optionsFunction.__isOptionsFunction = true;\n // Expose plugin dependencies so that `object-hash` returns a different\n // value if anything here changes, to ensure a rebuild is triggered.\n optionsFunction.__pluginFunction = pluginFunction;\n optionsFunction.__configFunction = configFunction;\n return optionsFunction;\n};\nconst _default = createPlugin;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function() {\n return _default;\n }\n});\nconst _createPlugin = /*#__PURE__*/ _interop_require_default(require(\"../util/createPlugin\"));\nfunction _interop_require_default(obj) {\n return obj && obj.__esModule ? obj : {\n default: obj\n };\n}\nconst _default = _createPlugin.default;\n","import plugin from 'tailwindcss/plugin.js';\n\nexport default plugin(({ matchVariant }) => {\n matchVariant('pattern', (pattern_selector) => {\n const [pattern, selector = '*', extraneous] = pattern_selector.split(';').map((str) => str.trim());\n if (!pattern) throw new Error(`No pattern provided in Tailwind CSS selector pattern '${pattern_selector}'`);\n const optionalSelector = selector === '*' ? '' : selector;\n if (extraneous)\n throw new Error(\n `Found more than 2 semicolon-delimited (;) arguments in Tailwind CSS selector pattern '${pattern_selector}'`\n );\n\n const combinator = pattern[0];\n const validCombinatorSymbols = ['+', '-', '%', '>', '<', '^'];\n if (!combinator || !validCombinatorSymbols.includes(combinator))\n throw new Error(\n `Combinator used '${combinator}' in Tailwind CSS selector pattern '${pattern_selector}' is not one of the valid combinators: ${validCombinatorSymbols.join(\n ', '\n )}`\n );\n\n const isDoubleCombinator = pattern[1] === combinator;\n if (!isDoubleCombinator && validCombinatorSymbols.includes(pattern[1] as unknown as string))\n throw new Error(\n `Second character in Tailwind CSS selector pattern '${pattern_selector}' ('${pattern[1]}') is a valid combinator but does not match the first combinator used ('${combinator}')`\n );\n\n const nthIndex_dir = isDoubleCombinator ? pattern.slice(2) : pattern.slice(1);\n if (isDoubleCombinator && nthIndex_dir)\n throw new Error(\n `Double combinator '${combinator.repeat(\n 2\n )}' in Tailwind CSS selector pattern '${pattern_selector}' can only be followed by an optional selector argument, delimited by a semicolon; instead found '${nthIndex_dir}'`\n );\n\n const validDirSymbols = ['<', '>'];\n const hasDir = !isDoubleCombinator && validDirSymbols.includes(nthIndex_dir.slice(-1));\n const [_nthIndex = '1', dir] = !isDoubleCombinator\n ? hasDir\n ? [nthIndex_dir.slice(0, -1), nthIndex_dir.slice(-1)]\n : nthIndex_dir\n ? [nthIndex_dir]\n : []\n : [];\n\n const nthIndex = Number(_nthIndex);\n console.log({\n pattern,\n hasDir,\n _nthIndex,\n dir,\n nthIndex,\n });\n if (!Number.isFinite(nthIndex))\n throw new Error(`Invalid nth-index value '${_nthIndex}' in Tailwind CSS selector pattern '${pattern_selector}'`);\n if (!(nthIndex > 0))\n throw new Error(\n `nth-index value '${nthIndex}' in Tailwind CSS selector pattern '${pattern_selector}' must be greater than 0`\n );\n\n let result = '';\n\n if (combinator === '+' || combinator === '%') {\n if (isDoubleCombinator) {\n result += `& ~ ${selector}`;\n } else if (!dir) {\n result += `& + ${'* + '.repeat(nthIndex - 1)}${selector}`;\n } else if (dir === '<') {\n result += [...Array(nthIndex)].map((_, i) => `& + ${'* + '.repeat(i)}${selector}`).join(', ');\n } else if (dir === '>') {\n result += `& ${'+ * '.repeat(nthIndex - 1)}~ ${selector}`;\n }\n }\n if (combinator === '%') result += `, `;\n if (combinator === '-' || combinator === '%') {\n if (isDoubleCombinator) {\n result += `${optionalSelector}:has(~ &)`;\n } else if (!dir) {\n result += `${optionalSelector}:has(${'+ * '.repeat(nthIndex - 1)}+ &)`;\n } else if (dir === '<') {\n result += `${optionalSelector}:has(${[...Array(nthIndex)].map((_, i) => `+ ${'* + '.repeat(i)}&`).join(', ')})`;\n } else if (dir === '>') {\n result += `${optionalSelector}:has(~${' * +'.repeat(nthIndex - 1)} &)`;\n }\n }\n if (combinator === '>' || combinator === '^') {\n if (isDoubleCombinator) {\n result += `& ${selector}`;\n } else if (!dir) {\n result += `& ${'> * '.repeat(nthIndex - 1)}> ${selector}`;\n } else if (dir === '<') {\n result += [...Array(nthIndex)].map((_, i) => `& > ${'* > '.repeat(i)}${selector}`).join(', ');\n } else if (dir === '>') {\n result += `& ${'> * '.repeat(nthIndex - 1)}${selector}`;\n }\n }\n if (combinator === '^') result += `, `;\n if (combinator === '<' || combinator === '^') {\n if (isDoubleCombinator) {\n result += `${optionalSelector}:has(&)`;\n } else if (!dir) {\n result += `${optionalSelector}:has(${'> * '.repeat(nthIndex - 1)}> &)`;\n } else if (dir === '<') {\n result += `${optionalSelector}:has(${[...Array(nthIndex)].map((_, i) => `${'> * '.repeat(i)}> &`).join(', ')})`;\n } else if (dir === '>') {\n result += `${optionalSelector}:has(${'* > '.repeat(nthIndex - 1)}&)`;\n }\n }\n return `:is(${result})`;\n });\n});\n","let createPlugin = require('./lib/public/create-plugin')\nmodule.exports = (createPlugin.__esModule ? createPlugin : { default: createPlugin }).default\n"],"names":["createPlugin","plugin","config","handler","Object","defineProperty","exports","value","enumerable","get","_default","withOptions","pluginFunction","configFunction","optionsFunction","options","__options","__isOptionsFunction","__pluginFunction","__configFunction","_interop_require_default","obj","__esModule","default","require$$0","_ref","matchVariant","pattern_selector","_pattern_selector$spl","split","map","str","trim","pattern","_pattern_selector$spl2","selector","extraneous","Error","optionalSelector","combinator","validCombinatorSymbols","includes","join","isDoubleCombinator","nthIndex_dir","slice","repeat","hasDir","_ref2","_ref2$","_nthIndex","dir","nthIndex","Number","console","log","isFinite","result","concat","Array","_","i"],"mappings":"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"} -------------------------------------------------------------------------------- /dist/types/index.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: { 2 | handler: import("tailwindcss/types/config").PluginCreator; 3 | config?: Partial | undefined; 4 | }; 5 | export default _default; 6 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | import plugin from 'tailwindcss/plugin.js'; 2 | 3 | export default plugin(({ matchVariant }) => { 4 | matchVariant('pattern', (pattern_selector) => { 5 | const [pattern, selector = '*', extraneous] = pattern_selector.split(';').map((str) => str.trim()); 6 | if (!pattern) throw new Error(`No pattern provided in Tailwind CSS selector pattern '${pattern_selector}'`); 7 | const optionalSelector = selector === '*' ? '' : selector; 8 | if (extraneous) 9 | throw new Error( 10 | `Found more than 2 semicolon-delimited (;) arguments in Tailwind CSS selector pattern '${pattern_selector}'` 11 | ); 12 | 13 | const combinator = pattern[0]; 14 | const validCombinatorSymbols = ['+', '-', '%', '>', '<', '^']; 15 | if (!combinator || !validCombinatorSymbols.includes(combinator)) 16 | throw new Error( 17 | `Combinator used '${combinator}' in Tailwind CSS selector pattern '${pattern_selector}' is not one of the valid combinators: ${validCombinatorSymbols.join( 18 | ', ' 19 | )}` 20 | ); 21 | 22 | const isDoubleCombinator = pattern[1] === combinator; 23 | if (!isDoubleCombinator && validCombinatorSymbols.includes(pattern[1] as unknown as string)) 24 | throw new Error( 25 | `Second character in Tailwind CSS selector pattern '${pattern_selector}' ('${pattern[1]}') is a valid combinator but does not match the first combinator used ('${combinator}')` 26 | ); 27 | 28 | const nthIndex_dir = isDoubleCombinator ? pattern.slice(2) : pattern.slice(1); 29 | if (isDoubleCombinator && nthIndex_dir) 30 | throw new Error( 31 | `Double combinator '${combinator.repeat( 32 | 2 33 | )}' in Tailwind CSS selector pattern '${pattern_selector}' can only be followed by an optional selector argument, delimited by a semicolon; instead found '${nthIndex_dir}'` 34 | ); 35 | 36 | const validDirSymbols = ['<', '>']; 37 | const hasDir = !isDoubleCombinator && validDirSymbols.includes(nthIndex_dir.slice(-1)); 38 | const [_nthIndex = '1', dir] = !isDoubleCombinator 39 | ? hasDir 40 | ? [nthIndex_dir.slice(0, -1), nthIndex_dir.slice(-1)] 41 | : nthIndex_dir 42 | ? [nthIndex_dir] 43 | : [] 44 | : []; 45 | 46 | const nthIndex = Number(_nthIndex); 47 | console.log({ 48 | pattern, 49 | hasDir, 50 | _nthIndex, 51 | dir, 52 | nthIndex, 53 | }); 54 | if (!Number.isFinite(nthIndex)) 55 | throw new Error(`Invalid nth-index value '${_nthIndex}' in Tailwind CSS selector pattern '${pattern_selector}'`); 56 | if (!(nthIndex > 0)) 57 | throw new Error( 58 | `nth-index value '${nthIndex}' in Tailwind CSS selector pattern '${pattern_selector}' must be greater than 0` 59 | ); 60 | 61 | let result = ''; 62 | 63 | if (combinator === '+' || combinator === '%') { 64 | if (isDoubleCombinator) { 65 | result += `& ~ ${selector}`; 66 | } else if (!dir) { 67 | result += `& + ${'* + '.repeat(nthIndex - 1)}${selector}`; 68 | } else if (dir === '<') { 69 | result += [...Array(nthIndex)].map((_, i) => `& + ${'* + '.repeat(i)}${selector}`).join(', '); 70 | } else if (dir === '>') { 71 | result += `& ${'+ * '.repeat(nthIndex - 1)}~ ${selector}`; 72 | } 73 | } 74 | if (combinator === '%') result += `, `; 75 | if (combinator === '-' || combinator === '%') { 76 | if (isDoubleCombinator) { 77 | result += `${optionalSelector}:has(~ &)`; 78 | } else if (!dir) { 79 | result += `${optionalSelector}:has(${'+ * '.repeat(nthIndex - 1)}+ &)`; 80 | } else if (dir === '<') { 81 | result += `${optionalSelector}:has(${[...Array(nthIndex)].map((_, i) => `+ ${'* + '.repeat(i)}&`).join(', ')})`; 82 | } else if (dir === '>') { 83 | result += `${optionalSelector}:has(~${' * +'.repeat(nthIndex - 1)} &)`; 84 | } 85 | } 86 | if (combinator === '>' || combinator === '^') { 87 | if (isDoubleCombinator) { 88 | result += `& ${selector}`; 89 | } else if (!dir) { 90 | result += `& ${'> * '.repeat(nthIndex - 1)}> ${selector}`; 91 | } else if (dir === '<') { 92 | result += [...Array(nthIndex)].map((_, i) => `& > ${'* > '.repeat(i)}${selector}`).join(', '); 93 | } else if (dir === '>') { 94 | result += `& ${'> * '.repeat(nthIndex - 1)}${selector}`; 95 | } 96 | } 97 | if (combinator === '^') result += `, `; 98 | if (combinator === '<' || combinator === '^') { 99 | if (isDoubleCombinator) { 100 | result += `${optionalSelector}:has(&)`; 101 | } else if (!dir) { 102 | result += `${optionalSelector}:has(${'> * '.repeat(nthIndex - 1)}> &)`; 103 | } else if (dir === '<') { 104 | result += `${optionalSelector}:has(${[...Array(nthIndex)].map((_, i) => `${'> * '.repeat(i)}> &`).join(', ')})`; 105 | } else if (dir === '>') { 106 | result += `${optionalSelector}:has(${'* > '.repeat(nthIndex - 1)}&)`; 107 | } 108 | } 109 | return `:is(${result})`; 110 | }); 111 | }); 112 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tailwindcss-selector-patterns", 3 | "version": "0.0.16", 4 | "description": "Selector Patterns for Tailwind CSS", 5 | "type": "module", 6 | "source": "index.ts", 7 | "exports": { 8 | "types": "./dist/types/index.d.ts", 9 | "require": "./dist/index.cjs", 10 | "default": "./dist/index.modern.js" 11 | }, 12 | "types": "dist/types/index.d.ts", 13 | "main": "./dist/index.cjs", 14 | "module": "./dist/index.module.js", 15 | "unpkg": "./dist/index.umd.js", 16 | "scripts": { 17 | "test": "echo \"Error: no test specified\" && exit 1", 18 | "build": "microbundle", 19 | "dev": "microbundle watch" 20 | }, 21 | "publishConfig": { 22 | "access": "public" 23 | }, 24 | "repository": { 25 | "type": "git", 26 | "url": "git+https://github.com/brandonmcconnell/tailwindcss-selector-patterns.git" 27 | }, 28 | "keywords": [ 29 | "tailwind", 30 | "tailwindcss", 31 | "css", 32 | "pattern", 33 | "postcss", 34 | "matching", 35 | "selector", 36 | "selectors", 37 | "style", 38 | "styling", 39 | "styles", 40 | "has" 41 | ], 42 | "author": "Brandon McConnell", 43 | "license": "MIT", 44 | "bugs": { 45 | "url": "https://github.com/brandonmcconnell/tailwindcss-selector-patterns/issues" 46 | }, 47 | "homepage": "https://github.com/brandonmcconnell/tailwindcss-selector-patterns#readme", 48 | "dependencies": { 49 | "@types/node": "^20.4.1" 50 | }, 51 | "devDependencies": { 52 | "@types/tailwindcss": "^3.1.0", 53 | "@typescript-eslint/eslint-plugin": "^5.59.8", 54 | "@typescript-eslint/parser": "^5.59.8", 55 | "eslint": "^8.41.0", 56 | "eslint-config-prettier": "^8.8.0", 57 | "eslint-plugin-prettier": "^5.0.0-alpha.1", 58 | "microbundle": "^0.15.1", 59 | "npm-run-all": "^4.1.5", 60 | "tailwindcss": "^3.4.3", 61 | "typescript": "^5.1.6" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "skipLibCheck": true, 5 | "target": "es2022", 6 | "allowJs": true, 7 | "resolveJsonModule": true, 8 | "moduleDetection": "force", 9 | "isolatedModules": true, 10 | "strict": true, 11 | "noUncheckedIndexedAccess": true, 12 | "module": "NodeNext", 13 | "outDir": "dist", 14 | "sourceMap": true, 15 | "declaration": true, 16 | "lib": ["es2022"] 17 | } 18 | } 19 | --------------------------------------------------------------------------------