tailwind-to-style 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -0
- package/dist/index.cjs +511 -35
- package/dist/index.d.ts +101 -0
- package/dist/index.esm.js +511 -36
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -156,6 +156,80 @@ const formatted = twsx(styles, { format: 'pretty' })
|
|
|
156
156
|
- `'.nested'` - Descendants
|
|
157
157
|
- `'@media ...'` - Media queries (root level only)
|
|
158
158
|
|
|
159
|
+
### `twsxVariants(className, config)`
|
|
160
|
+
|
|
161
|
+
Create variant-based component styles with automatic CSS generation. Similar to `tailwind-variants` but with auto-injection.
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
import { twsxVariants } from 'tailwind-to-style'
|
|
165
|
+
|
|
166
|
+
const btn = twsxVariants('.btn', {
|
|
167
|
+
base: 'px-4 py-2 rounded-lg font-medium transition-all',
|
|
168
|
+
variants: {
|
|
169
|
+
variant: {
|
|
170
|
+
solid: 'border-transparent',
|
|
171
|
+
outline: 'bg-transparent border-2',
|
|
172
|
+
ghost: 'bg-transparent',
|
|
173
|
+
},
|
|
174
|
+
color: {
|
|
175
|
+
primary: 'bg-blue-500 text-white hover:bg-blue-600',
|
|
176
|
+
danger: 'bg-red-500 text-white hover:bg-red-600',
|
|
177
|
+
},
|
|
178
|
+
size: {
|
|
179
|
+
sm: 'px-3 py-1.5 text-sm',
|
|
180
|
+
md: 'px-4 py-2 text-base',
|
|
181
|
+
lg: 'px-6 py-3 text-lg',
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
compoundVariants: [
|
|
185
|
+
{ variant: 'outline', color: 'primary', class: 'border-blue-500 text-blue-600' },
|
|
186
|
+
{ variant: 'outline', color: 'danger', class: 'border-red-500 text-red-600' },
|
|
187
|
+
],
|
|
188
|
+
defaultVariants: { variant: 'solid', color: 'primary', size: 'md' }
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
// Usage - returns class name string
|
|
192
|
+
btn() // "btn"
|
|
193
|
+
btn({ color: 'danger' }) // "btn btn-danger"
|
|
194
|
+
btn({ variant: 'outline', size: 'lg' }) // "btn btn-outline-lg"
|
|
195
|
+
|
|
196
|
+
// In React
|
|
197
|
+
const Button = ({ variant, color, size, children, ...props }) => (
|
|
198
|
+
<button className={btn({ variant, color, size })} {...props}>
|
|
199
|
+
{children}
|
|
200
|
+
</button>
|
|
201
|
+
)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Nested Selectors** - Style child elements:
|
|
205
|
+
|
|
206
|
+
```javascript
|
|
207
|
+
const alert = twsxVariants('.alert', {
|
|
208
|
+
base: 'p-4 rounded-lg border flex gap-3',
|
|
209
|
+
variants: {
|
|
210
|
+
status: {
|
|
211
|
+
info: 'bg-blue-50 text-blue-800',
|
|
212
|
+
error: 'bg-red-50 text-red-800',
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
defaultVariants: { status: 'info' },
|
|
216
|
+
nested: {
|
|
217
|
+
'.alert-icon': 'flex-shrink-0 mt-0.5',
|
|
218
|
+
'.alert-content': 'flex-1',
|
|
219
|
+
'.alert-dismiss': 'p-1 rounded hover:bg-black/10',
|
|
220
|
+
}
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
// Generates CSS:
|
|
224
|
+
// .alert .alert-icon { ... }
|
|
225
|
+
// .alert .alert-content { ... }
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Class Naming Convention:**
|
|
229
|
+
- `.btn` = all defaults
|
|
230
|
+
- `.btn-outline` = outline variant (non-default)
|
|
231
|
+
- `.btn-outline-danger-lg` = multiple non-defaults
|
|
232
|
+
|
|
159
233
|
### `configure(config)`
|
|
160
234
|
|
|
161
235
|
Customize theme with your colors, spacing, fonts, and more.
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* tailwind-to-style v3.
|
|
2
|
+
* tailwind-to-style v3.1.0
|
|
3
3
|
* Runtime Tailwind CSS to inline styles converter
|
|
4
4
|
* Core only: tws, twsx, configure
|
|
5
5
|
*
|
|
@@ -8586,10 +8586,10 @@ function parseCustomClassWithPatterns(className) {
|
|
|
8586
8586
|
return null;
|
|
8587
8587
|
}
|
|
8588
8588
|
|
|
8589
|
-
/**
|
|
8590
|
-
* Resolve all CSS custom properties (var) in a CSS string and output only clear CSS (no custom property)
|
|
8591
|
-
* @param {string} cssString
|
|
8592
|
-
* @returns {string} e.g. 'color: rgba(255,255,255,1); background: #fff;'
|
|
8589
|
+
/**
|
|
8590
|
+
* Resolve all CSS custom properties (var) in a CSS string and output only clear CSS (no custom property)
|
|
8591
|
+
* @param {string} cssString
|
|
8592
|
+
* @returns {string} e.g. 'color: rgba(255,255,255,1); background: #fff;'
|
|
8593
8593
|
*/
|
|
8594
8594
|
function resolveCssToClearCss(cssString) {
|
|
8595
8595
|
const customVars = {};
|
|
@@ -8623,9 +8623,9 @@ function resolveCssToClearCss(cssString) {
|
|
|
8623
8623
|
// Cache for getConfigOptions - use LRU cache
|
|
8624
8624
|
const configOptionsCache = new LRUCache(500);
|
|
8625
8625
|
|
|
8626
|
-
/**
|
|
8627
|
-
* Clear config options cache (internal use)
|
|
8628
|
-
* Called when user configuration changes
|
|
8626
|
+
/**
|
|
8627
|
+
* Clear config options cache (internal use)
|
|
8628
|
+
* Called when user configuration changes
|
|
8629
8629
|
*/
|
|
8630
8630
|
function clearConfigCache() {
|
|
8631
8631
|
configOptionsCache.clear();
|
|
@@ -8997,11 +8997,11 @@ function separateAndResolveCSS(arr) {
|
|
|
8997
8997
|
}
|
|
8998
8998
|
}
|
|
8999
8999
|
|
|
9000
|
-
/**
|
|
9001
|
-
* Process opacity modifier from class name (e.g., text-red-500/50 -> 50% opacity)
|
|
9002
|
-
* @param {string} className - Class name with potential opacity modifier
|
|
9003
|
-
* @param {string} cssDeclaration - CSS declaration to modify
|
|
9004
|
-
* @returns {string} Modified CSS declaration with opacity applied
|
|
9000
|
+
/**
|
|
9001
|
+
* Process opacity modifier from class name (e.g., text-red-500/50 -> 50% opacity)
|
|
9002
|
+
* @param {string} className - Class name with potential opacity modifier
|
|
9003
|
+
* @param {string} cssDeclaration - CSS declaration to modify
|
|
9004
|
+
* @returns {string} Modified CSS declaration with opacity applied
|
|
9005
9005
|
*/
|
|
9006
9006
|
function processOpacityModifier(className, cssDeclaration) {
|
|
9007
9007
|
const opacityMatch = className.match(/\/(\d+)$/);
|
|
@@ -9062,11 +9062,11 @@ function processOpacityModifier(className, cssDeclaration) {
|
|
|
9062
9062
|
return modifiedDeclaration;
|
|
9063
9063
|
}
|
|
9064
9064
|
|
|
9065
|
-
/**
|
|
9066
|
-
* Convert Tailwind class string to inline CSS styles or JSON object
|
|
9067
|
-
* @param {string} classNames - String containing Tailwind classes to convert
|
|
9068
|
-
* @param {boolean} convertToJson - If true, result will be JSON object, if false becomes CSS string
|
|
9069
|
-
* @returns {string|Object} Inline CSS string or style JSON object
|
|
9065
|
+
/**
|
|
9066
|
+
* Convert Tailwind class string to inline CSS styles or JSON object
|
|
9067
|
+
* @param {string} classNames - String containing Tailwind classes to convert
|
|
9068
|
+
* @param {boolean} convertToJson - If true, result will be JSON object, if false becomes CSS string
|
|
9069
|
+
* @returns {string|Object} Inline CSS string or style JSON object
|
|
9070
9070
|
*/
|
|
9071
9071
|
function tws(classNames, convertToJson) {
|
|
9072
9072
|
const totalMarker = performanceMonitor.start("tws:total");
|
|
@@ -9565,12 +9565,12 @@ function generateCssString(styles) {
|
|
|
9565
9565
|
return cssString.trim();
|
|
9566
9566
|
}
|
|
9567
9567
|
|
|
9568
|
-
/**
|
|
9569
|
-
* Generate CSS string from style object with SCSS-like syntax
|
|
9570
|
-
* Supports nested selectors, state variants, responsive variants, and @css directives
|
|
9571
|
-
* @param {Object} obj - Object with SCSS-like style format
|
|
9572
|
-
* @param {Object} [options] - Additional options, e.g. { inject: true/false }
|
|
9573
|
-
* @returns {string} Generated CSS string
|
|
9568
|
+
/**
|
|
9569
|
+
* Generate CSS string from style object with SCSS-like syntax
|
|
9570
|
+
* Supports nested selectors, state variants, responsive variants, and @css directives
|
|
9571
|
+
* @param {Object} obj - Object with SCSS-like style format
|
|
9572
|
+
* @param {Object} [options] - Additional options, e.g. { inject: true/false }
|
|
9573
|
+
* @returns {string} Generated CSS string
|
|
9574
9574
|
*/
|
|
9575
9575
|
function twsx(obj) {
|
|
9576
9576
|
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
@@ -9766,6 +9766,481 @@ function twsx(obj) {
|
|
|
9766
9766
|
}
|
|
9767
9767
|
}
|
|
9768
9768
|
|
|
9769
|
+
/**
|
|
9770
|
+
* Create a variant-based style generator (similar to tailwind-variants)
|
|
9771
|
+
* Supports base styles, variants, compound variants, and default variants
|
|
9772
|
+
*
|
|
9773
|
+
* @param {Object} config - Configuration object
|
|
9774
|
+
* @param {string} config.base - Base Tailwind classes applied to all variants
|
|
9775
|
+
* @param {Object} config.variants - Variant definitions with their options
|
|
9776
|
+
* @param {Array} config.compoundVariants - Compound variant rules for multi-variant combinations
|
|
9777
|
+
* @param {Object} config.defaultVariants - Default variant values
|
|
9778
|
+
* @returns {Function} A function that accepts variant props and returns merged classes
|
|
9779
|
+
*
|
|
9780
|
+
* @example
|
|
9781
|
+
* const button = twsxVariants({
|
|
9782
|
+
* base: 'px-4 py-2 rounded font-medium',
|
|
9783
|
+
* variants: {
|
|
9784
|
+
* color: {
|
|
9785
|
+
* primary: 'bg-blue-500 text-white',
|
|
9786
|
+
* secondary: 'bg-gray-500 text-white'
|
|
9787
|
+
* },
|
|
9788
|
+
* size: {
|
|
9789
|
+
* sm: 'text-sm',
|
|
9790
|
+
* lg: 'text-lg'
|
|
9791
|
+
* }
|
|
9792
|
+
* },
|
|
9793
|
+
* compoundVariants: [
|
|
9794
|
+
* { color: 'primary', size: 'lg', class: 'font-bold shadow-lg' }
|
|
9795
|
+
* ],
|
|
9796
|
+
* defaultVariants: {
|
|
9797
|
+
* color: 'primary',
|
|
9798
|
+
* size: 'sm'
|
|
9799
|
+
* }
|
|
9800
|
+
* });
|
|
9801
|
+
*
|
|
9802
|
+
* // Usage:
|
|
9803
|
+
* button({ color: 'primary', size: 'lg' }) // Returns merged classes
|
|
9804
|
+
*/
|
|
9805
|
+
function twsxVariants(className) {
|
|
9806
|
+
let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
9807
|
+
const {
|
|
9808
|
+
base = "",
|
|
9809
|
+
variants = {},
|
|
9810
|
+
compoundVariants = [],
|
|
9811
|
+
defaultVariants = {},
|
|
9812
|
+
nested = {}
|
|
9813
|
+
} = config;
|
|
9814
|
+
|
|
9815
|
+
/**
|
|
9816
|
+
* Check if a compound variant matches the current props
|
|
9817
|
+
* @param {Object} compound - Compound variant definition
|
|
9818
|
+
* @param {Object} props - Current variant props
|
|
9819
|
+
* @returns {boolean}
|
|
9820
|
+
*/
|
|
9821
|
+
function matchesCompoundVariant(compound, props) {
|
|
9822
|
+
for (const key in compound) {
|
|
9823
|
+
if (key === "class" || key === "className") continue;
|
|
9824
|
+
const compoundValue = compound[key];
|
|
9825
|
+
const propValue = props[key];
|
|
9826
|
+
|
|
9827
|
+
// Handle array values in compound (match any)
|
|
9828
|
+
if (Array.isArray(compoundValue)) {
|
|
9829
|
+
if (!compoundValue.includes(propValue)) return false;
|
|
9830
|
+
} else {
|
|
9831
|
+
// Handle boolean variants - convert string 'true'/'false' to boolean
|
|
9832
|
+
const normalizedCompound = compoundValue === "true" ? true : compoundValue === "false" ? false : compoundValue;
|
|
9833
|
+
const normalizedProp = propValue === "true" ? true : propValue === "false" ? false : propValue;
|
|
9834
|
+
if (normalizedCompound !== normalizedProp) return false;
|
|
9835
|
+
}
|
|
9836
|
+
}
|
|
9837
|
+
return true;
|
|
9838
|
+
}
|
|
9839
|
+
|
|
9840
|
+
/**
|
|
9841
|
+
* Merge multiple class strings with conflict resolution
|
|
9842
|
+
* Later classes override earlier ones for the same CSS property
|
|
9843
|
+
* @param {...string} classStrings - Class strings to merge
|
|
9844
|
+
* @returns {string}
|
|
9845
|
+
*/
|
|
9846
|
+
function mergeClasses() {
|
|
9847
|
+
const result = [];
|
|
9848
|
+
const propertyMap = new Map(); // Track index by conflict key
|
|
9849
|
+
|
|
9850
|
+
/**
|
|
9851
|
+
* Extract conflict key from Tailwind class
|
|
9852
|
+
* Classes that affect the same CSS property should have the same key
|
|
9853
|
+
*/
|
|
9854
|
+
function getConflictKey(cls) {
|
|
9855
|
+
// Extract variant prefix (hover:, focus:, etc.)
|
|
9856
|
+
const variantMatch = cls.match(/^((?:[a-z-]+:)*)/);
|
|
9857
|
+
const variant = variantMatch ? variantMatch[1] : "";
|
|
9858
|
+
const baseClass = cls.slice(variant.length);
|
|
9859
|
+
|
|
9860
|
+
// Check if it's a prefixed standalone (e.g., bg-transparent, text-transparent)
|
|
9861
|
+
const prefixedStandalone = baseClass.match(/^([a-z]+)-(transparent|current|inherit|auto)$/);
|
|
9862
|
+
if (prefixedStandalone) {
|
|
9863
|
+
const prefix = prefixedStandalone[1];
|
|
9864
|
+
return variant + prefix;
|
|
9865
|
+
}
|
|
9866
|
+
|
|
9867
|
+
// Handle standalone utilities (no prefix)
|
|
9868
|
+
const standaloneGroups = {
|
|
9869
|
+
"inline-flex": "display",
|
|
9870
|
+
"inline-block": "display",
|
|
9871
|
+
inline: "display",
|
|
9872
|
+
block: "display",
|
|
9873
|
+
flex: "display",
|
|
9874
|
+
grid: "display",
|
|
9875
|
+
hidden: "display",
|
|
9876
|
+
static: "position",
|
|
9877
|
+
fixed: "position",
|
|
9878
|
+
absolute: "position",
|
|
9879
|
+
relative: "position",
|
|
9880
|
+
sticky: "position",
|
|
9881
|
+
visible: "visibility",
|
|
9882
|
+
invisible: "visibility",
|
|
9883
|
+
underline: "text-decoration",
|
|
9884
|
+
"line-through": "text-decoration",
|
|
9885
|
+
"no-underline": "text-decoration",
|
|
9886
|
+
uppercase: "text-transform",
|
|
9887
|
+
lowercase: "text-transform",
|
|
9888
|
+
capitalize: "text-transform",
|
|
9889
|
+
"normal-case": "text-transform",
|
|
9890
|
+
truncate: "text-overflow",
|
|
9891
|
+
italic: "font-style",
|
|
9892
|
+
"not-italic": "font-style",
|
|
9893
|
+
antialiased: "font-smoothing",
|
|
9894
|
+
"subpixel-antialiased": "font-smoothing"
|
|
9895
|
+
};
|
|
9896
|
+
if (standaloneGroups[baseClass]) {
|
|
9897
|
+
return variant + standaloneGroups[baseClass];
|
|
9898
|
+
}
|
|
9899
|
+
|
|
9900
|
+
// Match pattern: prefix-value or prefix-modifier-value
|
|
9901
|
+
// bg-blue-500, text-xl, px-4, rounded-lg, shadow-md, border-2, etc.
|
|
9902
|
+
const match = baseClass.match(/^([a-z]+)-(.+)$/);
|
|
9903
|
+
if (match) {
|
|
9904
|
+
const prefix = match[1];
|
|
9905
|
+
const value = match[2];
|
|
9906
|
+
|
|
9907
|
+
// Group related prefixes
|
|
9908
|
+
const prefixGroups = {
|
|
9909
|
+
// Background
|
|
9910
|
+
bg: "bg",
|
|
9911
|
+
// Text color vs text size
|
|
9912
|
+
text: /^(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl)$/.test(value) ? "text-size" : "text-color",
|
|
9913
|
+
// Padding
|
|
9914
|
+
p: "p",
|
|
9915
|
+
px: "px",
|
|
9916
|
+
py: "py",
|
|
9917
|
+
pt: "pt",
|
|
9918
|
+
pb: "pb",
|
|
9919
|
+
pl: "pl",
|
|
9920
|
+
pr: "pr",
|
|
9921
|
+
// Margin
|
|
9922
|
+
m: "m",
|
|
9923
|
+
mx: "mx",
|
|
9924
|
+
my: "my",
|
|
9925
|
+
mt: "mt",
|
|
9926
|
+
mb: "mb",
|
|
9927
|
+
ml: "ml",
|
|
9928
|
+
mr: "mr",
|
|
9929
|
+
// Sizing
|
|
9930
|
+
w: "w",
|
|
9931
|
+
h: "h",
|
|
9932
|
+
min: baseClass.startsWith("min-w") ? "min-w" : "min-h",
|
|
9933
|
+
max: baseClass.startsWith("max-w") ? "max-w" : "max-h",
|
|
9934
|
+
// Border width vs color
|
|
9935
|
+
border: /^(\d|t-|b-|l-|r-|x-|y-)/.test(value) ? "border-width" : /^(solid|dashed|dotted|double|none|hidden)$/.test(value) ? "border-style" : "border-color",
|
|
9936
|
+
rounded: "rounded",
|
|
9937
|
+
// Effects
|
|
9938
|
+
shadow: "shadow",
|
|
9939
|
+
opacity: "opacity",
|
|
9940
|
+
// Typography
|
|
9941
|
+
font: /^(sans|serif|mono)$/.test(value) ? "font-family" : "font-weight",
|
|
9942
|
+
leading: "leading",
|
|
9943
|
+
tracking: "tracking",
|
|
9944
|
+
// Layout
|
|
9945
|
+
flex: "flex",
|
|
9946
|
+
grid: "grid",
|
|
9947
|
+
gap: "gap",
|
|
9948
|
+
justify: "justify",
|
|
9949
|
+
items: "items",
|
|
9950
|
+
self: "self",
|
|
9951
|
+
place: "place",
|
|
9952
|
+
// Position
|
|
9953
|
+
top: "top",
|
|
9954
|
+
bottom: "bottom",
|
|
9955
|
+
left: "left",
|
|
9956
|
+
right: "right",
|
|
9957
|
+
inset: "inset",
|
|
9958
|
+
z: "z",
|
|
9959
|
+
// Cursor
|
|
9960
|
+
cursor: "cursor",
|
|
9961
|
+
// Pointer events
|
|
9962
|
+
pointer: "pointer-events",
|
|
9963
|
+
// Transform
|
|
9964
|
+
scale: "scale",
|
|
9965
|
+
rotate: "rotate",
|
|
9966
|
+
translate: "translate",
|
|
9967
|
+
skew: "skew",
|
|
9968
|
+
// Transition
|
|
9969
|
+
transition: "transition",
|
|
9970
|
+
duration: "duration",
|
|
9971
|
+
ease: "ease",
|
|
9972
|
+
delay: "delay",
|
|
9973
|
+
// Ring
|
|
9974
|
+
ring: /^(\d|inset)/.test(value) ? "ring-width" : /^offset/.test(value) ? "ring-offset" : "ring-color",
|
|
9975
|
+
// Outline
|
|
9976
|
+
outline: /^(\d|none)/.test(value) ? "outline-width" : /^(dashed|dotted|double|solid)$/.test(value) ? "outline-style" : /^offset/.test(value) ? "outline-offset" : "outline-color",
|
|
9977
|
+
// Overflow
|
|
9978
|
+
overflow: "overflow",
|
|
9979
|
+
// Object
|
|
9980
|
+
object: "object",
|
|
9981
|
+
// Aspect
|
|
9982
|
+
aspect: "aspect",
|
|
9983
|
+
// Underline
|
|
9984
|
+
underline: "underline-offset",
|
|
9985
|
+
// Decoration
|
|
9986
|
+
decoration: "decoration",
|
|
9987
|
+
// Accent
|
|
9988
|
+
accent: "accent",
|
|
9989
|
+
// Caret
|
|
9990
|
+
caret: "caret",
|
|
9991
|
+
// Fill & Stroke
|
|
9992
|
+
fill: "fill",
|
|
9993
|
+
stroke: /^\d/.test(value) ? "stroke-width" : "stroke-color",
|
|
9994
|
+
// Backdrop
|
|
9995
|
+
backdrop: "backdrop",
|
|
9996
|
+
// Columns
|
|
9997
|
+
columns: "columns",
|
|
9998
|
+
col: "col",
|
|
9999
|
+
row: "row",
|
|
10000
|
+
// Order
|
|
10001
|
+
order: "order",
|
|
10002
|
+
// Grow/Shrink
|
|
10003
|
+
grow: "grow",
|
|
10004
|
+
shrink: "shrink",
|
|
10005
|
+
basis: "basis",
|
|
10006
|
+
// Content
|
|
10007
|
+
content: "content",
|
|
10008
|
+
// List
|
|
10009
|
+
list: "list",
|
|
10010
|
+
// Scroll
|
|
10011
|
+
scroll: "scroll",
|
|
10012
|
+
// Snap
|
|
10013
|
+
snap: "snap",
|
|
10014
|
+
// Touch
|
|
10015
|
+
touch: "touch",
|
|
10016
|
+
// Select
|
|
10017
|
+
select: "select",
|
|
10018
|
+
// Will change
|
|
10019
|
+
will: "will-change",
|
|
10020
|
+
// Appearance
|
|
10021
|
+
appearance: "appearance",
|
|
10022
|
+
// Break
|
|
10023
|
+
break: "break",
|
|
10024
|
+
// Hyphens
|
|
10025
|
+
hyphens: "hyphens",
|
|
10026
|
+
// Whitespace
|
|
10027
|
+
whitespace: "whitespace",
|
|
10028
|
+
// Word break
|
|
10029
|
+
word: "word-break",
|
|
10030
|
+
// Overscroll
|
|
10031
|
+
overscroll: "overscroll",
|
|
10032
|
+
// Resize
|
|
10033
|
+
resize: "resize",
|
|
10034
|
+
// Float
|
|
10035
|
+
float: "float",
|
|
10036
|
+
// Clear
|
|
10037
|
+
clear: "clear",
|
|
10038
|
+
// Isolation
|
|
10039
|
+
isolation: "isolation",
|
|
10040
|
+
// Mix blend
|
|
10041
|
+
mix: "mix-blend",
|
|
10042
|
+
// Background blend
|
|
10043
|
+
bg: "bg",
|
|
10044
|
+
// Filter
|
|
10045
|
+
filter: "filter",
|
|
10046
|
+
blur: "blur",
|
|
10047
|
+
brightness: "brightness",
|
|
10048
|
+
contrast: "contrast",
|
|
10049
|
+
grayscale: "grayscale",
|
|
10050
|
+
hue: "hue-rotate",
|
|
10051
|
+
invert: "invert",
|
|
10052
|
+
saturate: "saturate",
|
|
10053
|
+
sepia: "sepia",
|
|
10054
|
+
drop: "drop-shadow"
|
|
10055
|
+
};
|
|
10056
|
+
const group = prefixGroups[prefix] || prefix;
|
|
10057
|
+
return variant + group;
|
|
10058
|
+
}
|
|
10059
|
+
return null; // No conflict tracking
|
|
10060
|
+
}
|
|
10061
|
+
for (var _len2 = arguments.length, classStrings = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
10062
|
+
classStrings[_key2] = arguments[_key2];
|
|
10063
|
+
}
|
|
10064
|
+
for (const str of classStrings) {
|
|
10065
|
+
if (!str) continue;
|
|
10066
|
+
const classes = str.trim().split(/\s+/);
|
|
10067
|
+
for (const cls of classes) {
|
|
10068
|
+
if (!cls) continue;
|
|
10069
|
+
const conflictKey = getConflictKey(cls);
|
|
10070
|
+
if (conflictKey) {
|
|
10071
|
+
// Remove previous class with same conflict key
|
|
10072
|
+
const prevIndex = propertyMap.get(conflictKey);
|
|
10073
|
+
if (prevIndex !== undefined) {
|
|
10074
|
+
result[prevIndex] = null; // Mark for removal
|
|
10075
|
+
}
|
|
10076
|
+
propertyMap.set(conflictKey, result.length);
|
|
10077
|
+
}
|
|
10078
|
+
result.push(cls);
|
|
10079
|
+
}
|
|
10080
|
+
}
|
|
10081
|
+
return result.filter(Boolean).join(" ");
|
|
10082
|
+
}
|
|
10083
|
+
|
|
10084
|
+
/**
|
|
10085
|
+
* Generate classes for a specific variant combination
|
|
10086
|
+
* @param {Object} props - Variant props
|
|
10087
|
+
* @returns {string} Merged Tailwind classes
|
|
10088
|
+
*/
|
|
10089
|
+
function generateClasses() {
|
|
10090
|
+
let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
10091
|
+
// Merge props with defaults
|
|
10092
|
+
const mergedProps = {
|
|
10093
|
+
...defaultVariants,
|
|
10094
|
+
...props
|
|
10095
|
+
};
|
|
10096
|
+
|
|
10097
|
+
// Start with base classes
|
|
10098
|
+
const classes = [base];
|
|
10099
|
+
|
|
10100
|
+
// Add variant classes
|
|
10101
|
+
for (const variantKey in variants) {
|
|
10102
|
+
const variantValue = mergedProps[variantKey];
|
|
10103
|
+
const variantOptions = variants[variantKey];
|
|
10104
|
+
if (variantValue !== undefined && variantOptions[variantValue]) {
|
|
10105
|
+
classes.push(variantOptions[variantValue]);
|
|
10106
|
+
}
|
|
10107
|
+
}
|
|
10108
|
+
|
|
10109
|
+
// Add compound variant classes
|
|
10110
|
+
for (const compound of compoundVariants) {
|
|
10111
|
+
if (matchesCompoundVariant(compound, mergedProps)) {
|
|
10112
|
+
classes.push(compound.class || compound.className || "");
|
|
10113
|
+
}
|
|
10114
|
+
}
|
|
10115
|
+
|
|
10116
|
+
// Merge all classes
|
|
10117
|
+
return mergeClasses(...classes);
|
|
10118
|
+
}
|
|
10119
|
+
|
|
10120
|
+
// If className is provided, auto-generate and inject CSS
|
|
10121
|
+
if (className) {
|
|
10122
|
+
const baseClassName = className.startsWith(".") ? className.slice(1) : className;
|
|
10123
|
+
const baseCss = {};
|
|
10124
|
+
const variantCss = {};
|
|
10125
|
+
|
|
10126
|
+
// Get all variant keys and their options
|
|
10127
|
+
const variantKeys = Object.keys(variants);
|
|
10128
|
+
|
|
10129
|
+
// Helper to generate all combinations
|
|
10130
|
+
function generateCombinations(keys) {
|
|
10131
|
+
let current = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
10132
|
+
if (keys.length === 0) {
|
|
10133
|
+
// Generate class name from current combination
|
|
10134
|
+
const parts = [baseClassName];
|
|
10135
|
+
let isBaseOnly = true;
|
|
10136
|
+
for (const key of variantKeys) {
|
|
10137
|
+
if (current[key] !== undefined && current[key] !== defaultVariants[key]) {
|
|
10138
|
+
isBaseOnly = false;
|
|
10139
|
+
// Skip boolean 'false' values
|
|
10140
|
+
if (current[key] === false || current[key] === "false") continue;
|
|
10141
|
+
// For boolean 'true', just add the key name
|
|
10142
|
+
if (current[key] === true || current[key] === "true") {
|
|
10143
|
+
parts.push(key);
|
|
10144
|
+
} else {
|
|
10145
|
+
parts.push(current[key]);
|
|
10146
|
+
}
|
|
10147
|
+
}
|
|
10148
|
+
}
|
|
10149
|
+
const selector = "." + parts.join("-");
|
|
10150
|
+
const classes = generateClasses(current);
|
|
10151
|
+
|
|
10152
|
+
// Separate base class from variant classes
|
|
10153
|
+
if (isBaseOnly) {
|
|
10154
|
+
baseCss[selector] = classes;
|
|
10155
|
+
} else {
|
|
10156
|
+
variantCss[selector] = classes;
|
|
10157
|
+
}
|
|
10158
|
+
return;
|
|
10159
|
+
}
|
|
10160
|
+
const [firstKey, ...restKeys] = keys;
|
|
10161
|
+
const options = variants[firstKey];
|
|
10162
|
+
|
|
10163
|
+
// If this variant has no default, also generate without it (undefined)
|
|
10164
|
+
const hasDefault = defaultVariants[firstKey] !== undefined;
|
|
10165
|
+
if (!hasDefault) {
|
|
10166
|
+
// Generate combinations without this variant
|
|
10167
|
+
generateCombinations(restKeys, current);
|
|
10168
|
+
}
|
|
10169
|
+
for (const optionValue of Object.keys(options)) {
|
|
10170
|
+
generateCombinations(restKeys, {
|
|
10171
|
+
...current,
|
|
10172
|
+
[firstKey]: optionValue
|
|
10173
|
+
});
|
|
10174
|
+
}
|
|
10175
|
+
}
|
|
10176
|
+
|
|
10177
|
+
// Generate all combinations
|
|
10178
|
+
generateCombinations(variantKeys);
|
|
10179
|
+
|
|
10180
|
+
// Inject base CSS first, then variant CSS (order matters for specificity)
|
|
10181
|
+
twsx(baseCss);
|
|
10182
|
+
twsx(variantCss);
|
|
10183
|
+
|
|
10184
|
+
// Handle nested selectors - generate CSS for child elements
|
|
10185
|
+
if (Object.keys(nested).length > 0) {
|
|
10186
|
+
const nestedCss = {};
|
|
10187
|
+
for (const [nestedSelector, nestedClasses] of Object.entries(nested)) {
|
|
10188
|
+
// Build full selector: .alert .icon or .alert.icon (if starts with &)
|
|
10189
|
+
let fullSelector;
|
|
10190
|
+
if (nestedSelector.startsWith("&")) {
|
|
10191
|
+
// &.active -> .alert.active (attached to parent)
|
|
10192
|
+
fullSelector = className + nestedSelector.slice(1);
|
|
10193
|
+
} else {
|
|
10194
|
+
// .icon -> .alert .icon (descendant)
|
|
10195
|
+
fullSelector = className + " " + nestedSelector;
|
|
10196
|
+
}
|
|
10197
|
+
nestedCss[fullSelector] = nestedClasses;
|
|
10198
|
+
}
|
|
10199
|
+
twsx(nestedCss);
|
|
10200
|
+
}
|
|
10201
|
+
}
|
|
10202
|
+
|
|
10203
|
+
/**
|
|
10204
|
+
* Build class name string from props (for component usage)
|
|
10205
|
+
* @param {Object} props - Variant props
|
|
10206
|
+
* @returns {string} Class name string like "alert alert-warning" or "btn btn-outline-danger"
|
|
10207
|
+
*/
|
|
10208
|
+
function buildClassName() {
|
|
10209
|
+
let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
10210
|
+
if (!className) {
|
|
10211
|
+
// No className defined, return generated classes directly
|
|
10212
|
+
return generateClasses(props);
|
|
10213
|
+
}
|
|
10214
|
+
const baseClass = className.startsWith(".") ? className.slice(1) : className;
|
|
10215
|
+
const variantParts = [baseClass];
|
|
10216
|
+
for (const key of Object.keys(variants)) {
|
|
10217
|
+
const value = props[key];
|
|
10218
|
+
if (value === undefined || value === null) continue;
|
|
10219
|
+
|
|
10220
|
+
// Skip if it's the default value
|
|
10221
|
+
if (value === defaultVariants[key]) continue;
|
|
10222
|
+
|
|
10223
|
+
// Handle boolean variants
|
|
10224
|
+
if (value === true || value === "true") {
|
|
10225
|
+
variantParts.push(key);
|
|
10226
|
+
} else if (value !== false && value !== "false") {
|
|
10227
|
+
variantParts.push(value);
|
|
10228
|
+
}
|
|
10229
|
+
}
|
|
10230
|
+
const variantClass = variantParts.join("-");
|
|
10231
|
+
|
|
10232
|
+
// Always include base class for consistency and nested selector support
|
|
10233
|
+
// e.g., "btn btn-outline-danger" instead of just "btn-outline-danger"
|
|
10234
|
+
if (variantClass !== baseClass) {
|
|
10235
|
+
return baseClass + " " + variantClass;
|
|
10236
|
+
}
|
|
10237
|
+
return variantClass;
|
|
10238
|
+
}
|
|
10239
|
+
|
|
10240
|
+
// Always return the buildClassName function
|
|
10241
|
+
return buildClassName;
|
|
10242
|
+
}
|
|
10243
|
+
|
|
9769
10244
|
// Simple hashCode function for CSS deduplication
|
|
9770
10245
|
function getCssHash(str) {
|
|
9771
10246
|
let hash = 0,
|
|
@@ -9813,19 +10288,19 @@ function autoInjectCss(cssString) {
|
|
|
9813
10288
|
}
|
|
9814
10289
|
|
|
9815
10290
|
// Enhanced debounced functions with performance monitoring configuration
|
|
9816
|
-
/**
|
|
9817
|
-
* Debounced version of tws function with performance monitoring
|
|
9818
|
-
* @param {string} classNames - String containing Tailwind classes to convert
|
|
9819
|
-
* @param {boolean} convertToJson - If true, result will be JSON object, if false becomes CSS string
|
|
9820
|
-
* @returns {string|Object} Inline CSS string or style JSON object
|
|
10291
|
+
/**
|
|
10292
|
+
* Debounced version of tws function with performance monitoring
|
|
10293
|
+
* @param {string} classNames - String containing Tailwind classes to convert
|
|
10294
|
+
* @param {boolean} convertToJson - If true, result will be JSON object, if false becomes CSS string
|
|
10295
|
+
* @returns {string|Object} Inline CSS string or style JSON object
|
|
9821
10296
|
*/
|
|
9822
10297
|
const debouncedTws = debounce(tws, 50); // Faster debounce for tws
|
|
9823
10298
|
|
|
9824
|
-
/**
|
|
9825
|
-
* Debounced version of twsx function with performance monitoring
|
|
9826
|
-
* @param {Object} obj - Object with SCSS-like style format
|
|
9827
|
-
* @param {Object} [options] - Additional options
|
|
9828
|
-
* @returns {string} Generated CSS string
|
|
10299
|
+
/**
|
|
10300
|
+
* Debounced version of twsx function with performance monitoring
|
|
10301
|
+
* @param {Object} obj - Object with SCSS-like style format
|
|
10302
|
+
* @param {Object} [options] - Additional options
|
|
10303
|
+
* @returns {string} Generated CSS string
|
|
9829
10304
|
*/
|
|
9830
10305
|
const debouncedTwsx = debounce(twsx, 100); // Standard debounce for twsx
|
|
9831
10306
|
|
|
@@ -9861,7 +10336,7 @@ const performanceUtils = {
|
|
|
9861
10336
|
}
|
|
9862
10337
|
};
|
|
9863
10338
|
|
|
9864
|
-
// End of exports - v3.0.0 core only (tws, twsx, configure)
|
|
10339
|
+
// End of exports - v3.0.0 core only (tws, twsx, twsxVariants, configure)
|
|
9865
10340
|
|
|
9866
10341
|
exports.DYNAMIC_TEMPLATES = DYNAMIC_TEMPLATES;
|
|
9867
10342
|
exports.INLINE_ANIMATIONS = INLINE_ANIMATIONS;
|
|
@@ -9894,3 +10369,4 @@ exports.resetTailwindCache = resetTailwindCache;
|
|
|
9894
10369
|
exports.staggerAnimations = staggerAnimations;
|
|
9895
10370
|
exports.tws = tws;
|
|
9896
10371
|
exports.twsx = twsx;
|
|
10372
|
+
exports.twsxVariants = twsxVariants;
|