├── .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 |

Mixins for Tailwind CSS

2 | 3 |
4 | 5 | [![minified size](https://img.shields.io/bundlephobia/min/tailwindcss-mixins)](https://bundlephobia.com/package/tailwindcss-mixins) 6 | [![license](https://img.shields.io/github/license/brandonmcconnell/tailwindcss-mixins?label=license)](https://github.com/brandonmcconnell/tailwindcss-mixins/blob/main/LICENSE) 7 | [![version](https://img.shields.io/npm/v/tailwindcss-mixins)](https://www.npmjs.com/package/tailwindcss-mixins) 8 | [![twitter](https://img.shields.io/twitter/follow/branmcconnell)](https://twitter.com/branmcconnell) 9 | 10 |
11 | 12 | Mixins for Tailwind CSS is a plugin that introduces a new `mixin` variant/utility pair, allowing you to create reusable groups of Tailwind CSS utilities. This provides a more declarative and maintainable approach compared to traditional methods of targeting descendants with arbitrary variants or non-Tailwind CSS selectors. 13 | 14 | ## Installation 15 | 16 | You can install the plugin via npm: 17 | 18 | ```bash 19 | npm install tailwindcss-mixins 20 | ``` 21 | 22 | Then, include it in your `tailwind.config.js`: 23 | 24 | ```js 25 | module.exports = { 26 | plugins: [ 27 | require('tailwindcss-mixins'), 28 | ] 29 | } 30 | ``` 31 | 32 | ## Usage 33 | 34 | The `mixin` variant can be used to define a group of utilities that will be applied to multiple elements simultaneously. Here's an example: 35 | 36 | ```html 37 |
38 |
Test 1
39 |
Test 2
40 |
Test 3
41 |
Test 4
42 |
43 | ``` 44 | [View this example on Tailwind Play](https://play.tailwindcss.com/JrwBfc7snO) 45 | 46 | In this example, the utilities `inline-block`, `font-bold`, and `underline` are applied to all elements with the `mixin` class. 47 | 48 | Mixins help reduce repetitive class names, keeping your code DRY (Don't Repeat Yourself) and adhering to the utility-first approach of Tailwind CSS. Instead of using arbitrary variants or non-Tailwind CSS classes to target descendants, mixins provide a consistent and declarative pattern for creating reusable styles. 49 | 50 | ### Naming Mixins 51 | 52 | If you need to differentiate between multiple mixins, you can use the Tailwind CSS modifier syntax to name your mixins: 53 | 54 | ```html 55 |
62 | Link 63 | 64 |
65 | ``` 66 | [View this example on Tailwind Play](https://play.tailwindcss.com/NGONvODQCs) 67 | 68 | In this example, we've named our mixins `mixin/{name}`, allowing us to distinguish between different mixins and apply them accordingly. 69 | 70 | ### Applying Variants to Mixins 71 | 72 | When using mixins, you can apply Tailwind CSS variants to the declaration of the mixin itself. This will affect only the property it's applied to, allowing for more customization of mixins. 73 | 74 | For example: 75 | 76 | ```html 77 |
78 |
79 |
80 | ``` 81 | 82 | In this case, the `inline-block` utility will be applied to the elements with the `mixin` class only on small screens and above. 83 | 84 | Note that the use of a variant on the consumer of the mixin, like in the below example, will not affect the mixin itself. Variants must be applied directly to the mixin declaration. 85 | 86 | This will not work: 87 | 88 | ```html 89 |
90 |
91 |
92 | ``` 93 | 94 | ## Why use Mixins for Tailwind CSS? 95 | 96 | Mixins for Tailwind CSS provides several benefits: 97 | 98 | - Simplifies the application of styles to multiple elements 99 | - Reduces code duplication and improves maintainability 100 | - Provides a more declarative and consistent approach to styling 101 | - Adheres to the utility-first approach of Tailwind CSS 102 | - Improves developer experience by avoiding the need for arbitrary targeting and non-Tailwind CSS classes 103 | 104 | ## Why NOT use Mixins for Tailwind CSS? 105 | 106 | While Mixins for Tailwind CSS is a simple and powerful tool, it may not be suitable for every project. Some potential drawbacks include: 107 | 108 | - **Learning Curve**: Mixins introduce a new concept and syntax that developers will need to learn and understand. 109 | - **Complexity**: As the number of mixins and nested mixins increases, the complexity of your codebase may also increase, potentially leading to maintainability issues. 110 | - **Performance**: Mixins may have a slight impact on performance due to the additional CSS rules generated. However, this impact is likely to be negligible in most cases. 111 | 112 | As with any tool or technique, it's important to weigh the pros and cons and choose the approach that best fits your project's needs and team's preferences. 113 | 114 | --- 115 | 116 | I hope you find `tailwindcss-mixins` a valuable addition to your projects. If you have any issues or suggestions, don't hesitate to open an issue or pull request. 117 | 118 | If you liked this, you might also like my other Tailwind CSS plugins: 119 | * [tailwindcss-multi](https://github.com/brandonmcconnell/tailwindcss-multi): Group utilities together by variant 120 | * [tailwindcss-signals](https://github.com/brandonmcconnell/tailwindcss-signals): Apply styles based on parent or ancestor state, a state-driven alterative to groups 121 | * [tailwindcss-members](https://github.com/brandonmcconnell/tailwindcss-members): Apply styles based on child or descendant state, the inverse of groups 122 | * [tailwindcss-mixins](https://github.com/brandonmcconnell/tailwindcss-mixins): Construct reusable & aliased sets of utilities inline 123 | * [tailwindcss-selector-patterns](https://github.com/brandonmcconnell/tailwindcss-selector-patterns): Dynamic CSS selector patterns 124 | * [tailwindcss-js](https://github.com/brandonmcconnell/tailwindcss-js): Effortless build-time JS script injection 125 | * [tailwindcss-directional-shadows](https://github.com/brandonmcconnell/tailwindcss-directional-shadows): Supercharge your shadow utilities with added directional support (includes directional `shadow-border` utilities too ✨) 126 | * [tailwindcss-default-shades](https://github.com/brandonmcconnell/tailwindcss-default-shades): Default shades for simpler color utility classes 127 | * [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 -------------------------------------------------------------------------------- /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 u}}),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 u=t}),t=e(function(e,t){function u(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__*/u(n).default}),u={values:{DEFAULT:""}},o=(0,(t.__esModule?t:{default:t}).default)(function(e){(0,e.matchVariant)("mixin",function(e,n){var t=n.modifier;return"& .mixin"+(t?"\\/"+t:"")+" { & }"},u)});module.exports=o; 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\n// using empty values here so the compiler plays nice and generates the styles without values\nconst EMPTY_VALUES = { values: { DEFAULT: '' } };\n\nexport default plugin(({ matchVariant }) => {\n matchVariant('mixin', (_, { modifier }) => `& .mixin${modifier ? `\\\\/${modifier}` : ''} { & }`, EMPTY_VALUES);\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","EMPTY_VALUES","values","DEFAULT","_ref","matchVariant","_","_ref2","modifier"],"mappings":"uFAUA,SAASA,EAAaC,EAAQC,GAC1B,MAAO,CACHC,QAASF,EACTC,SAER,CAdAE,OAAOC,eAAwBC,EAAA,aAAc,CACzCC,OAAO,IAEXH,OAAOC,eAAeC,EAAS,UAAW,CACtCE,YAAY,EACZC,IAAK,WACD,OAAOC,CACV,IAQLV,EAAaW,YAAc,SAASC,EAAgBC,EAAiB,MAAA,CAAO,KACxE,MAAMC,EAAkB,SAASC,GAC7B,MAAO,CACHC,UAAWD,EACXZ,QAASS,EAAeG,GACxBb,OAAQW,EAAeE,GAEnC,EAMI,OALAD,EAAgBG,qBAAsB,EAGtCH,EAAgBI,iBAAmBN,EACnCE,EAAgBK,iBAAmBN,EAC5BC,CACX,EACA,MAAMJ,EAAWV,sBCpBjB,SAASoB,EAAyBC,GAC9B,OAAOA,GAAOA,EAAIC,WAAaD,EAAM,CACjCE,QAASF,EAEjB,CAdAjB,OAAOC,eAAwBC,EAAA,aAAc,CACzCC,OAAO,IAEXH,OAAOC,eAAeC,EAAS,UAAW,CACtCE,YAAY,EACZC,IAAK,WACD,OAAOC,CACV,IAQL,MAAMA,eAN8BU,EAAyBI,GAM9BD,UCbzBE,EAAe,CAAEC,OAAQ,CAAEC,QAAS,KAE3B1B,GAAAA,GCJGD,EAAasB,WAAatB,EAAe,CAAEuB,QAASvB,IAAgBuB,SDIhE,SAAAK,IACpBC,EADmCD,EAAZC,cACV,QAAS,SAACC,EAACC,GAAI,IAAAC,EAAQD,EAARC,SAAQ,MAAA,YAAkBA,EAAQ,MAASA,EAAa,IAAE,QAAA,EAAUP,EAClG"} -------------------------------------------------------------------------------- /dist/index.modern.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 o}}),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 o=t}),t=e(function(e,t){function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return u}});const u=/*#__PURE__*/o(n).default});const o={values:{DEFAULT:""}};var u=(0,(t.__esModule?t:{default:t}).default)(({matchVariant:e})=>{e("mixin",(e,{modifier:n})=>`& .mixin${n?`\\/${n}`:""} { & }`,o)});export{u 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\n// using empty values here so the compiler plays nice and generates the styles without values\nconst EMPTY_VALUES = { values: { DEFAULT: '' } };\n\nexport default plugin(({ matchVariant }) => {\n matchVariant('mixin', (_, { modifier }) => `& .mixin${modifier ? `\\\\/${modifier}` : ''} { & }`, EMPTY_VALUES);\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","EMPTY_VALUES","values","DEFAULT","matchVariant","_","modifier"],"mappings":"uFAUA,SAASA,EAAaC,EAAQC,GAC1B,MAAO,CACHC,QAASF,EACTC,SAER,CAdAE,OAAOC,eAAwBC,EAAA,aAAc,CACzCC,OAAO,IAEXH,OAAOC,eAAeC,EAAS,UAAW,CACtCE,YAAY,EACZC,IAAK,WACD,OAAOC,CACV,IAQLV,EAAaW,YAAc,SAASC,EAAgBC,EAAiB,MAAA,CAAO,KACxE,MAAMC,EAAkB,SAASC,GAC7B,MAAO,CACHC,UAAWD,EACXZ,QAASS,EAAeG,GACxBb,OAAQW,EAAeE,GAEnC,EAMI,OALAD,EAAgBG,qBAAsB,EAGtCH,EAAgBI,iBAAmBN,EACnCE,EAAgBK,iBAAmBN,EAC5BC,CACX,EACA,MAAMJ,EAAWV,sBCpBjB,SAASoB,EAAyBC,GAC9B,OAAOA,GAAOA,EAAIC,WAAaD,EAAM,CACjCE,QAASF,EAEjB,CAdAjB,OAAOC,eAAwBC,EAAA,aAAc,CACzCC,OAAO,IAEXH,OAAOC,eAAeC,EAAS,UAAW,CACtCE,YAAY,EACZC,IAAK,WACD,OAAOC,CACV,IAQL,MAAMA,eAN8BU,EAAyBI,GAM9BD,UCb/B,MAAME,EAAe,CAAEC,OAAQ,CAAEC,QAAS,KAE1C,OAAe1B,GCJGD,EAAasB,WAAatB,EAAe,CAAEuB,QAASvB,IAAgBuB,SDIhE,EAAGK,mBACvBA,EAAa,QAAS,CAACC,GAAKC,cAA0B,WAAAA,EAAW,MAAMA,IAAa,WAAYL,EAClG"} -------------------------------------------------------------------------------- /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 u}}),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 u=t}),t=e(function(e,t){function u(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__*/u(n).default}),u={values:{DEFAULT:""}},o=(0,(t.__esModule?t:{default:t}).default)(function(e){(0,e.matchVariant)("mixin",function(e,n){var t=n.modifier;return"& .mixin"+(t?"\\/"+t:"")+" { & }"},u)});export{o 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\n// using empty values here so the compiler plays nice and generates the styles without values\nconst EMPTY_VALUES = { values: { DEFAULT: '' } };\n\nexport default plugin(({ matchVariant }) => {\n matchVariant('mixin', (_, { modifier }) => `& .mixin${modifier ? `\\\\/${modifier}` : ''} { & }`, EMPTY_VALUES);\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","EMPTY_VALUES","values","DEFAULT","_ref","matchVariant","_","_ref2","modifier"],"mappings":"uFAUA,SAASA,EAAaC,EAAQC,GAC1B,MAAO,CACHC,QAASF,EACTC,SAER,CAdAE,OAAOC,eAAwBC,EAAA,aAAc,CACzCC,OAAO,IAEXH,OAAOC,eAAeC,EAAS,UAAW,CACtCE,YAAY,EACZC,IAAK,WACD,OAAOC,CACV,IAQLV,EAAaW,YAAc,SAASC,EAAgBC,EAAiB,MAAA,CAAO,KACxE,MAAMC,EAAkB,SAASC,GAC7B,MAAO,CACHC,UAAWD,EACXZ,QAASS,EAAeG,GACxBb,OAAQW,EAAeE,GAEnC,EAMI,OALAD,EAAgBG,qBAAsB,EAGtCH,EAAgBI,iBAAmBN,EACnCE,EAAgBK,iBAAmBN,EAC5BC,CACX,EACA,MAAMJ,EAAWV,sBCpBjB,SAASoB,EAAyBC,GAC9B,OAAOA,GAAOA,EAAIC,WAAaD,EAAM,CACjCE,QAASF,EAEjB,CAdAjB,OAAOC,eAAwBC,EAAA,aAAc,CACzCC,OAAO,IAEXH,OAAOC,eAAeC,EAAS,UAAW,CACtCE,YAAY,EACZC,IAAK,WACD,OAAOC,CACV,IAQL,MAAMA,eAN8BU,EAAyBI,GAM9BD,UCbzBE,EAAe,CAAEC,OAAQ,CAAEC,QAAS,KAE3B1B,GAAAA,GCJGD,EAAasB,WAAatB,EAAe,CAAEuB,QAASvB,IAAgBuB,SDIhE,SAAAK,IACpBC,EADmCD,EAAZC,cACV,QAAS,SAACC,EAACC,GAAI,IAAAC,EAAQD,EAARC,SAAQ,MAAA,YAAkBA,EAAQ,MAASA,EAAa,IAAE,QAAA,EAAUP,EAClG"} -------------------------------------------------------------------------------- /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).tailwindcssMixins=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 o}}),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 o=t}),t=e(function(e,t){function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return i}});const i=/*#__PURE__*/o(n).default}),o={values:{DEFAULT:""}};return(0,(t.__esModule?t:{default:t}).default)(function(e){(0,e.matchVariant)("mixin",function(e,n){var t=n.modifier;return"& .mixin"+(t?"\\/"+t:"")+" { & }"},o)})}); 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\n// using empty values here so the compiler plays nice and generates the styles without values\nconst EMPTY_VALUES = { values: { DEFAULT: '' } };\n\nexport default plugin(({ matchVariant }) => {\n matchVariant('mixin', (_, { modifier }) => `& .mixin${modifier ? `\\\\/${modifier}` : ''} { & }`, EMPTY_VALUES);\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","EMPTY_VALUES","values","DEFAULT","_ref","matchVariant","_","_ref2","modifier"],"mappings":"2TAUA,SAASA,EAAaC,EAAQC,GAC1B,MAAO,CACHC,QAASF,EACTC,SAER,CAdAE,OAAOC,eAAwBC,EAAA,aAAc,CACzCC,OAAO,IAEXH,OAAOC,eAAeC,EAAS,UAAW,CACtCE,YAAY,EACZC,IAAK,WACD,OAAOC,CACV,IAQLV,EAAaW,YAAc,SAASC,EAAgBC,EAAiB,MAAA,CAAO,KACxE,MAAMC,EAAkB,SAASC,GAC7B,MAAO,CACHC,UAAWD,EACXZ,QAASS,EAAeG,GACxBb,OAAQW,EAAeE,GAEnC,EAMI,OALAD,EAAgBG,qBAAsB,EAGtCH,EAAgBI,iBAAmBN,EACnCE,EAAgBK,iBAAmBN,EAC5BC,CACX,EACA,MAAMJ,EAAWV,sBCpBjB,SAASoB,EAAyBC,GAC9B,OAAOA,GAAOA,EAAIC,WAAaD,EAAM,CACjCE,QAASF,EAEjB,CAdAjB,OAAOC,eAAwBC,EAAA,aAAc,CACzCC,OAAO,IAEXH,OAAOC,eAAeC,EAAS,UAAW,CACtCE,YAAY,EACZC,IAAK,WACD,OAAOC,CACV,IAQL,MAAMA,eAN8BU,EAAyBI,GAM9BD,UCbzBE,EAAe,CAAEC,OAAQ,CAAEC,QAAS,YAE3B1B,GCJGD,EAAasB,WAAatB,EAAe,CAAEuB,QAASvB,IAAgBuB,SDIhE,SAAAK,IACpBC,EADmCD,EAAZC,cACV,QAAS,SAACC,EAACC,GAAI,IAAAC,EAAQD,EAARC,SAAQ,MAAA,YAAkBA,EAAQ,MAASA,EAAa,IAAE,QAAA,EAAUP,EAClG"} -------------------------------------------------------------------------------- /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 | // using empty values here so the compiler plays nice and generates the styles without values 4 | const EMPTY_VALUES = { values: { DEFAULT: '' } }; 5 | 6 | export default plugin(({ matchVariant }) => { 7 | matchVariant('mixin', (_, { modifier }) => `& .mixin${modifier ? `\\/${modifier}` : ''} { & }`, EMPTY_VALUES); 8 | }); 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tailwindcss-mixins", 3 | "version": "0.0.11", 4 | "description": "Mixins for Tailwind CSS provides a declarative API for creating reusable groups of utilities, reducing code duplication and improving maintainability while emphasizing a utility-first approach.", 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-mixins.git" 27 | }, 28 | "keywords": [ 29 | "css", 30 | "utility-classes", 31 | "group", 32 | "groups", 33 | "grouping", 34 | "mixins", 35 | "plugin", 36 | "plugins", 37 | "tailwind", 38 | "tailwindcss" 39 | ], 40 | "author": "Brandon McConnell", 41 | "license": "MIT", 42 | "bugs": { 43 | "url": "https://github.com/brandonmcconnell/tailwindcss-mixins/issues" 44 | }, 45 | "homepage": "https://github.com/brandonmcconnell/tailwindcss-mixins#readme", 46 | "dependencies": { 47 | "@types/node": "^20.4.1" 48 | }, 49 | "devDependencies": { 50 | "@types/tailwindcss": "^3.1.0", 51 | "@typescript-eslint/eslint-plugin": "^5.59.8", 52 | "@typescript-eslint/parser": "^5.59.8", 53 | "eslint": "^8.41.0", 54 | "eslint-config-prettier": "^8.8.0", 55 | "eslint-plugin-prettier": "^5.0.0-alpha.1", 56 | "microbundle": "^0.15.1", 57 | "npm-run-all": "^4.1.5", 58 | "tailwindcss": "^3.4.3", 59 | "typescript": "^5.1.6" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------