windrunner 1.1.0 → 1.1.2

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/dist/index.esm.js CHANGED
@@ -1,59 +1,3 @@
1
- // src/variants.js
2
- var variants = {
3
- accentColor: ["hover", "focus", "not-hover", "not-focus", "not-disabled"],
4
- accessibility: ["hover", "focus"],
5
- aspect: ["hover", "focus"],
6
- backgroundColor: ["hover", "focus", "not-hover", "not-focus", "not-disabled"],
7
- blur: ["hover", "focus"],
8
- borderColor: ["hover", "focus", "not-hover", "not-focus", "not-disabled"],
9
- boxShadow: ["hover", "focus"],
10
- brightness: ["hover", "focus"],
11
- caretColor: ["hover", "focus", "not-hover", "not-focus", "not-disabled"],
12
- contrast: ["hover", "focus"],
13
- dropShadow: ["hover", "focus"],
14
- fill: ["hover", "focus", "not-hover", "not-focus", "not-disabled"],
15
- flexBasis: ["hover", "focus"],
16
- gradientColorStops: ["hover", "focus", "not-hover", "not-focus", "not-disabled"],
17
- grayscale: ["hover", "focus"],
18
- hueRotate: ["hover", "focus"],
19
- insetRing: ["hover", "focus"],
20
- insetShadow: ["hover", "focus"],
21
- invert: ["hover", "focus"],
22
- opacity: ["hover", "focus"],
23
- outlineColor: ["hover", "focus", "not-hover", "not-focus", "not-disabled"],
24
- outlineOffset: ["hover", "focus"],
25
- outlineStyle: ["hover", "focus"],
26
- outlineWidth: ["hover", "focus"],
27
- placeholderColor: ["hover", "focus", "not-hover", "not-focus", "not-disabled"],
28
- ringColor: ["hover", "focus", "not-hover", "not-focus", "not-disabled"],
29
- ringOffsetColor: ["hover", "focus", "not-hover", "not-focus", "not-disabled"],
30
- ringOffsetWidth: ["hover", "focus"],
31
- ringWidth: ["hover", "focus"],
32
- rotate: ["hover", "focus"],
33
- saturate: ["hover", "focus"],
34
- scale: ["hover", "focus"],
35
- sepia: ["hover", "focus"],
36
- skew: ["hover", "focus"],
37
- stroke: ["hover", "focus", "not-hover", "not-focus", "not-disabled"],
38
- strokeWidth: ["hover", "focus"],
39
- textColor: ["hover", "focus", "not-hover", "not-focus", "not-disabled"],
40
- textDecoration: ["focus", "hover"],
41
- textDecorationColor: ["focus", "hover", "not-hover", "not-focus", "not-disabled"],
42
- textDecorationStyle: ["focus", "hover"],
43
- textDecorationThickness: ["focus", "hover"],
44
- textShadowBlur: ["hover", "focus"],
45
- textShadowColor: ["hover", "focus", "not-hover", "not-focus", "not-disabled"],
46
- textShadowOpacity: ["hover", "focus"],
47
- textShadowX: ["hover", "focus"],
48
- textShadowY: ["hover", "focus"],
49
- touchAction: ["hover", "focus"],
50
- mask: ["hover", "focus"],
51
- transform3d: ["hover", "focus"],
52
- translate: ["hover", "focus"],
53
- zIndex: ["hover", "focus"]
54
- };
55
- var variants_default = variants;
56
-
57
1
  // src/theme.js
58
2
  var theme = {
59
3
  accentColor: ({ theme: theme2 }) => ({
@@ -1401,7 +1345,6 @@ var vars_default = vars;
1401
1345
 
1402
1346
  // src/config.js
1403
1347
  var configOptions = {
1404
- variants: variants_default,
1405
1348
  theme: theme_default,
1406
1349
  vars: vars_default
1407
1350
  };
@@ -1436,6 +1379,13 @@ function getConfigOptions(options = {}, pluginKeys = []) {
1436
1379
  };
1437
1380
  }
1438
1381
 
1382
+ // src/constants.js
1383
+ var TIME_VALUE_WITH_UNIT_REGEX = /^\d+(?:\.\d+)?(?:ms|s)$/;
1384
+ var TIME_VALUE_NUMERIC_REGEX = /^\d+(?:\.\d+)?$/;
1385
+ var CSS_ESCAPE_BACKSLASH_REGEX = /\\/g;
1386
+ var CSS_ESCAPE_SPECIAL_CHARS_REGEX = /([ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g;
1387
+ var CSS_ESCAPE_LEADING_DIGIT_REGEX = /^(\d)/;
1388
+
1439
1389
  // src/resolvers.js
1440
1390
  function resolveArbitraryValue(valueKey) {
1441
1391
  if (valueKey.startsWith("[") && valueKey.endsWith("]")) {
@@ -1455,8 +1405,8 @@ function resolveThemeValue(scale, valueKey) {
1455
1405
  function resolveTimeValue(valueKey) {
1456
1406
  const arbitrary = resolveArbitraryValue(valueKey);
1457
1407
  if (arbitrary !== void 0) return arbitrary;
1458
- if (/^\d+(?:\.\d+)?(?:ms|s)$/.test(valueKey)) return valueKey;
1459
- if (/^\d+(?:\.\d+)?$/.test(valueKey)) return `${valueKey}ms`;
1408
+ if (TIME_VALUE_WITH_UNIT_REGEX.test(valueKey)) return valueKey;
1409
+ if (TIME_VALUE_NUMERIC_REGEX.test(valueKey)) return `${valueKey}ms`;
1460
1410
  return void 0;
1461
1411
  }
1462
1412
  function resolveColorValue(colors, colorKey) {
@@ -1492,15 +1442,21 @@ function resolveColorWithOpacity(colors, rawKey) {
1492
1442
  const color = resolveColorValue(colors, colorKey);
1493
1443
  if (color === void 0) return void 0;
1494
1444
  const arbOpacity = resolveArbitraryValue(opacityStr);
1495
- const opacityVal = arbOpacity !== void 0 ? arbOpacity : String(parseFloat(opacityStr) / 100);
1496
- if (!opacityVal || opacityVal === "NaN") return void 0;
1497
- return `color-mix(in oklch, ${color} ${parseFloat(opacityStr)}%, transparent)`;
1445
+ if (arbOpacity !== void 0) {
1446
+ const opacityVal = parseFloat(arbOpacity);
1447
+ if (isNaN(opacityVal)) return void 0;
1448
+ const finalOpacity = opacityVal <= 1 ? opacityVal * 100 : opacityVal;
1449
+ return `color-mix(in oklch, ${color} ${finalOpacity}%, transparent)`;
1450
+ }
1451
+ const opacityNum = parseFloat(opacityStr);
1452
+ if (isNaN(opacityNum)) return void 0;
1453
+ return `color-mix(in oklch, ${color} ${opacityNum}%, transparent)`;
1498
1454
  }
1499
1455
  function escapeCssIdentifier(value) {
1500
1456
  if (typeof CSS !== "undefined" && typeof CSS.escape === "function") {
1501
1457
  return CSS.escape(value);
1502
1458
  }
1503
- return String(value).replace(/\\/g, "\\\\").replace(/([ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1").replace(/^(\d)/, "\\3$1 ");
1459
+ return String(value).replace(CSS_ESCAPE_BACKSLASH_REGEX, "\\\\").replace(CSS_ESCAPE_SPECIAL_CHARS_REGEX, "\\$1").replace(CSS_ESCAPE_LEADING_DIGIT_REGEX, "\\3$1 ");
1504
1460
  }
1505
1461
  function appendImportant(declaration, isImportant) {
1506
1462
  if (!isImportant) return declaration;
@@ -3295,8 +3251,8 @@ var PluginRegistry = class {
3295
3251
  * Register multiple variants at once
3296
3252
  * @param {Object} variants - Object mapping names to handlers
3297
3253
  */
3298
- addVariants(variants2) {
3299
- Object.entries(variants2).forEach(([name, handler]) => {
3254
+ addVariants(variants) {
3255
+ Object.entries(variants).forEach(([name, handler]) => {
3300
3256
  this.addVariant(name, handler);
3301
3257
  });
3302
3258
  }
@@ -3378,6 +3334,178 @@ function objectToCss(obj) {
3378
3334
  }
3379
3335
 
3380
3336
  // src/compiler.js
3337
+ var PREFIX_ROUTER = {
3338
+ // Layout & Display
3339
+ "block": [buildLayoutDeclaration],
3340
+ "inline": [buildLayoutDeclaration],
3341
+ "flex": [buildFlexGridDeclaration, buildLayoutDeclaration],
3342
+ "grid": [buildFlexGridDeclaration, buildLayoutDeclaration],
3343
+ "hidden": [buildLayoutDeclaration],
3344
+ "table": [buildLayoutDeclaration],
3345
+ "flow": [buildLayoutDeclaration],
3346
+ // Position
3347
+ "static": [buildLayoutDeclaration],
3348
+ "fixed": [buildLayoutDeclaration],
3349
+ "absolute": [buildLayoutDeclaration],
3350
+ "relative": [buildLayoutDeclaration],
3351
+ "sticky": [buildLayoutDeclaration],
3352
+ "inset": [buildPositionInsetDeclaration, buildInsetShadowDeclaration, buildInsetRingDeclaration],
3353
+ "top": [buildPositionInsetDeclaration],
3354
+ "right": [buildPositionInsetDeclaration],
3355
+ "bottom": [buildPositionInsetDeclaration],
3356
+ "left": [buildPositionInsetDeclaration],
3357
+ "start": [buildPositionInsetDeclaration],
3358
+ "end": [buildPositionInsetDeclaration],
3359
+ "z": [buildLayoutDeclaration],
3360
+ // Spacing
3361
+ "m": [buildSpacingDeclaration],
3362
+ "mx": [buildSpacingDeclaration],
3363
+ "my": [buildSpacingDeclaration],
3364
+ "mt": [buildSpacingDeclaration],
3365
+ "mr": [buildSpacingDeclaration],
3366
+ "mb": [buildSpacingDeclaration],
3367
+ "ml": [buildSpacingDeclaration],
3368
+ "ms": [buildSpacingDeclaration],
3369
+ "me": [buildSpacingDeclaration],
3370
+ "p": [buildSpacingDeclaration],
3371
+ "px": [buildSpacingDeclaration],
3372
+ "py": [buildSpacingDeclaration],
3373
+ "pt": [buildSpacingDeclaration],
3374
+ "pr": [buildSpacingDeclaration],
3375
+ "pb": [buildSpacingDeclaration],
3376
+ "pl": [buildSpacingDeclaration],
3377
+ "ps": [buildSpacingDeclaration],
3378
+ "pe": [buildSpacingDeclaration],
3379
+ "space": [buildSpaceBetweenDeclaration],
3380
+ // Sizing
3381
+ "w": [buildDimensionDeclaration],
3382
+ "h": [buildDimensionDeclaration],
3383
+ "min": [buildDimensionDeclaration],
3384
+ "max": [buildDimensionDeclaration],
3385
+ "size": [buildDimensionDeclaration],
3386
+ // Typography
3387
+ "text": [buildTypographyDeclaration, buildColorDeclaration],
3388
+ "font": [buildTypographyDeclaration],
3389
+ "leading": [buildTypographyDeclaration],
3390
+ "tracking": [buildTypographyDeclaration],
3391
+ "line": [buildTypographyDeclaration],
3392
+ "whitespace": [buildTypographyDeclaration],
3393
+ "break": [buildTypographyDeclaration],
3394
+ "hyphens": [buildTypographyDeclaration],
3395
+ "list": [buildTypographyDeclaration],
3396
+ "italic": [buildTypographyDeclaration],
3397
+ "underline": [buildTypographyDeclaration],
3398
+ "overline": [buildTypographyDeclaration],
3399
+ "uppercase": [buildTypographyDeclaration],
3400
+ "lowercase": [buildTypographyDeclaration],
3401
+ "capitalize": [buildTypographyDeclaration],
3402
+ "normal": [buildTypographyDeclaration, buildLayoutDeclaration],
3403
+ "truncate": [buildTypographyDeclaration],
3404
+ // Colors & Backgrounds
3405
+ "bg": [buildBackgroundDeclaration, buildColorDeclaration, buildGradientDeclaration],
3406
+ "from": [buildGradientDeclaration],
3407
+ "via": [buildGradientDeclaration],
3408
+ "to": [buildGradientDeclaration],
3409
+ "fill": [buildColorDeclaration],
3410
+ "stroke": [buildColorDeclaration],
3411
+ // Borders
3412
+ "border": [buildBorderDeclaration, buildColorDeclaration],
3413
+ "rounded": [buildBorderRadiusDeclaration],
3414
+ "divide": [buildDivideDeclaration],
3415
+ // Effects
3416
+ "shadow": [buildShadowDeclaration, buildTextShadowDeclaration],
3417
+ "opacity": [buildOpacityDeclaration],
3418
+ "ring": [buildRingDeclaration, buildRingOffsetDeclaration],
3419
+ // Transforms
3420
+ "scale": [buildTransformDeclaration],
3421
+ "rotate": [buildTransformDeclaration],
3422
+ "translate": [buildTransformDeclaration],
3423
+ "skew": [buildTransformDeclaration],
3424
+ "origin": [buildTransformDeclaration],
3425
+ "transform": [buildTransformDeclaration],
3426
+ // Filters
3427
+ "blur": [buildFilterDeclaration],
3428
+ "brightness": [buildFilterDeclaration],
3429
+ "contrast": [buildFilterDeclaration],
3430
+ "grayscale": [buildFilterDeclaration],
3431
+ "hue": [buildFilterDeclaration],
3432
+ "invert": [buildFilterDeclaration],
3433
+ "saturate": [buildFilterDeclaration],
3434
+ "sepia": [buildFilterDeclaration],
3435
+ "drop": [buildFilterDeclaration],
3436
+ "backdrop": [buildFilterDeclaration],
3437
+ // Transitions & Animations
3438
+ "transition": [buildTransitionDeclaration],
3439
+ "duration": [buildTransitionDeclaration],
3440
+ "ease": [buildTransitionDeclaration],
3441
+ "delay": [buildTransitionDeclaration],
3442
+ "animate": [buildAnimationDeclaration],
3443
+ // Interactivity
3444
+ "cursor": [buildInteractivityDeclaration],
3445
+ "pointer": [buildInteractivityDeclaration],
3446
+ "resize": [buildInteractivityDeclaration],
3447
+ "select": [buildInteractivityDeclaration],
3448
+ "appearance": [buildInteractivityDeclaration],
3449
+ "outline": [buildColorDeclaration, buildInteractivityDeclaration],
3450
+ "caret": [buildColorDeclaration],
3451
+ "accent": [buildColorDeclaration],
3452
+ // Flexbox & Grid specific
3453
+ "items": [buildFlexGridDeclaration],
3454
+ "justify": [buildFlexGridDeclaration],
3455
+ "place": [buildFlexGridDeclaration],
3456
+ "content": [buildFlexGridDeclaration, buildTypographyDeclaration],
3457
+ "self": [buildFlexGridDeclaration],
3458
+ "order": [buildFlexGridDeclaration],
3459
+ "gap": [buildGapDeclaration],
3460
+ "grow": [buildFlexGridDeclaration],
3461
+ "shrink": [buildFlexGridDeclaration],
3462
+ "basis": [buildFlexGridDeclaration],
3463
+ "cols": [buildFlexGridDeclaration],
3464
+ "rows": [buildFlexGridDeclaration],
3465
+ "col": [buildFlexGridDeclaration],
3466
+ "row": [buildFlexGridDeclaration],
3467
+ "auto": [buildFlexGridDeclaration, buildLayoutDeclaration],
3468
+ // Misc
3469
+ "overflow": [buildLayoutDeclaration],
3470
+ "overscroll": [buildInteractivityDeclaration],
3471
+ "scroll": [buildScrollSnapDeclaration, buildInteractivityDeclaration],
3472
+ "snap": [buildScrollSnapDeclaration],
3473
+ "touch": [buildInteractivityDeclaration],
3474
+ "will": [buildInteractivityDeclaration],
3475
+ "mix": [buildBlendingDeclaration],
3476
+ "blend": [buildBlendingDeclaration],
3477
+ "isolation": [buildLayoutDeclaration],
3478
+ "object": [buildLayoutDeclaration],
3479
+ "container": [buildContainerQueryDeclaration],
3480
+ "columns": [buildLayoutDeclaration],
3481
+ "aspect": [buildLayoutDeclaration],
3482
+ "clear": [buildLayoutDeclaration],
3483
+ "float": [buildLayoutDeclaration],
3484
+ "box": [buildLayoutDeclaration],
3485
+ "visible": [buildLayoutDeclaration],
3486
+ "invisible": [buildLayoutDeclaration],
3487
+ "collapse": [buildLayoutDeclaration],
3488
+ "mask": [buildMaskDeclaration],
3489
+ "forced": [buildForcedColorDeclaration],
3490
+ "field": [buildInteractivityDeclaration],
3491
+ "placeholder": [buildColorDeclaration],
3492
+ "sr": [buildAccessibilityDeclaration],
3493
+ "not": [buildAccessibilityDeclaration]
3494
+ };
3495
+ function extractPrefix(token) {
3496
+ const dashIndex = token.indexOf("-");
3497
+ if (dashIndex === -1) return token;
3498
+ const prefix = token.slice(0, dashIndex);
3499
+ const secondDashIndex = token.indexOf("-", dashIndex + 1);
3500
+ if (secondDashIndex !== -1) {
3501
+ const twoPartPrefix = token.slice(0, secondDashIndex);
3502
+ if (PREFIX_ROUTER[twoPartPrefix]) return twoPartPrefix;
3503
+ }
3504
+ return prefix;
3505
+ }
3506
+ function checkAllBuilders(baseToken, theme2) {
3507
+ return buildLayoutDeclaration(baseToken, theme2) || buildPositionInsetDeclaration(baseToken, theme2) || buildSpacingDeclaration(baseToken, theme2) || buildSpaceBetweenDeclaration(baseToken, theme2) || buildGapDeclaration(baseToken, theme2) || buildDimensionDeclaration(baseToken, theme2) || buildFlexGridDeclaration(baseToken, theme2) || buildBorderDeclaration(baseToken, theme2) || buildBorderRadiusDeclaration(baseToken, theme2) || buildBorderSpacingDeclaration(baseToken, theme2) || buildDivideDeclaration(baseToken, theme2) || buildOpacityDeclaration(baseToken, theme2) || buildShadowDeclaration(baseToken, theme2) || buildInsetShadowDeclaration(baseToken, theme2) || buildInsetRingDeclaration(baseToken, theme2) || buildRingDeclaration(baseToken, theme2) || buildRingOffsetDeclaration(baseToken, theme2) || buildTextShadowDeclaration(baseToken, theme2) || buildTransitionDeclaration(baseToken) || buildTransformDeclaration(baseToken, theme2) || buildFilterDeclaration(baseToken, theme2) || buildBackgroundDeclaration(baseToken, theme2) || buildGradientDeclaration(baseToken, theme2) || buildColorDeclaration(baseToken, theme2) || buildTypographyDeclaration(baseToken, theme2) || buildBlendingDeclaration(baseToken) || buildInteractivityDeclaration(baseToken, theme2) || buildAnimationDeclaration(baseToken) || buildMaskDeclaration(baseToken) || buildContainerQueryDeclaration(baseToken) || buildScrollSnapDeclaration(baseToken) || buildAccessibilityDeclaration(baseToken) || buildZoomDeclaration(baseToken, theme2) || buildForcedColorDeclaration(baseToken);
3508
+ }
3381
3509
  function compileBaseToken(baseToken, theme2, pluginRegistry) {
3382
3510
  if (pluginRegistry) {
3383
3511
  const pluginMatch = pluginRegistry.matchUtility(baseToken);
@@ -3395,11 +3523,85 @@ function compileBaseToken(baseToken, theme2, pluginRegistry) {
3395
3523
  }
3396
3524
  }
3397
3525
  }
3398
- return buildLayoutDeclaration(baseToken, theme2) || buildPositionInsetDeclaration(baseToken, theme2) || buildSpacingDeclaration(baseToken, theme2) || buildSpaceBetweenDeclaration(baseToken, theme2) || buildGapDeclaration(baseToken, theme2) || buildDimensionDeclaration(baseToken, theme2) || buildFlexGridDeclaration(baseToken, theme2) || buildBorderDeclaration(baseToken, theme2) || buildBorderRadiusDeclaration(baseToken, theme2) || buildBorderSpacingDeclaration(baseToken, theme2) || buildDivideDeclaration(baseToken, theme2) || buildOpacityDeclaration(baseToken, theme2) || buildShadowDeclaration(baseToken, theme2) || buildInsetShadowDeclaration(baseToken, theme2) || buildInsetRingDeclaration(baseToken, theme2) || buildRingDeclaration(baseToken, theme2) || buildRingOffsetDeclaration(baseToken, theme2) || buildTextShadowDeclaration(baseToken, theme2) || buildTransitionDeclaration(baseToken) || buildTransformDeclaration(baseToken, theme2) || buildFilterDeclaration(baseToken, theme2) || buildBackgroundDeclaration(baseToken, theme2) || buildGradientDeclaration(baseToken, theme2) || buildColorDeclaration(baseToken, theme2) || buildTypographyDeclaration(baseToken, theme2) || buildBlendingDeclaration(baseToken) || buildInteractivityDeclaration(baseToken, theme2) || buildAnimationDeclaration(baseToken) || buildMaskDeclaration(baseToken) || buildContainerQueryDeclaration(baseToken) || buildScrollSnapDeclaration(baseToken) || buildAccessibilityDeclaration(baseToken) || buildZoomDeclaration(baseToken, theme2) || buildForcedColorDeclaration(baseToken);
3526
+ const prefix = extractPrefix(baseToken);
3527
+ const builders = PREFIX_ROUTER[prefix];
3528
+ if (builders) {
3529
+ for (let i = 0; i < builders.length; i += 1) {
3530
+ const result = builders[i](baseToken, theme2);
3531
+ if (result) return result;
3532
+ }
3533
+ }
3534
+ return checkAllBuilders(baseToken, theme2);
3399
3535
  }
3400
- function applyVariants(selector, variants2, pluginRegistry) {
3536
+ var VARIANT_MAP = /* @__PURE__ */ new Map([
3537
+ // Dark mode
3538
+ ["dark", (s) => `.dark ${s}`],
3539
+ // Pseudo-classes – interactive
3540
+ ["hover", (s) => `${s}:hover`],
3541
+ ["focus", (s) => `${s}:focus`],
3542
+ ["focus-visible", (s) => `${s}:focus-visible`],
3543
+ ["focus-within", (s) => `${s}:focus-within`],
3544
+ ["active", (s) => `${s}:active`],
3545
+ ["visited", (s) => `${s}:visited`],
3546
+ ["disabled", (s) => `${s}:disabled`],
3547
+ ["checked", (s) => `${s}:checked`],
3548
+ ["indeterminate", (s) => `${s}:indeterminate`],
3549
+ ["required", (s) => `${s}:required`],
3550
+ ["valid", (s) => `${s}:valid`],
3551
+ ["invalid", (s) => `${s}:invalid`],
3552
+ ["target", (s) => `${s}:target`],
3553
+ ["enabled", (s) => `${s}:enabled`],
3554
+ ["default", (s) => `${s}:default`],
3555
+ ["optional", (s) => `${s}:optional`],
3556
+ ["user-valid", (s) => `${s}:user-valid`],
3557
+ ["user-invalid", (s) => `${s}:user-invalid`],
3558
+ ["in-range", (s) => `${s}:in-range`],
3559
+ ["out-of-range", (s) => `${s}:out-of-range`],
3560
+ ["placeholder-shown", (s) => `${s}:placeholder-shown`],
3561
+ ["autofill", (s) => `${s}:autofill`],
3562
+ ["details-content", (s) => `${s}:details-content`],
3563
+ ["read-only", (s) => `${s}:read-only`],
3564
+ ["open", (s) => `${s}[open]`],
3565
+ // Pseudo-elements
3566
+ ["placeholder", (s) => `${s}::placeholder`],
3567
+ ["backdrop", (s) => `${s}::backdrop`],
3568
+ ["before", (s) => `${s}::before`],
3569
+ ["after", (s) => `${s}::after`],
3570
+ ["first-letter", (s) => `${s}::first-letter`],
3571
+ ["first-line", (s) => `${s}::first-line`],
3572
+ ["marker", (s) => `${s}::marker`],
3573
+ ["selection", (s) => `${s}::selection`],
3574
+ ["file", (s) => `${s}::file-selector-button`],
3575
+ // Structural pseudo-classes
3576
+ ["first", (s) => `${s}:first-child`],
3577
+ ["last", (s) => `${s}:last-child`],
3578
+ ["odd", (s) => `${s}:nth-child(odd)`],
3579
+ ["even", (s) => `${s}:nth-child(even)`],
3580
+ ["first-of-type", (s) => `${s}:first-of-type`],
3581
+ ["last-of-type", (s) => `${s}:last-of-type`],
3582
+ ["only", (s) => `${s}:only-child`],
3583
+ ["only-of-type", (s) => `${s}:only-of-type`],
3584
+ ["empty", (s) => `${s}:empty`],
3585
+ // Group & peer variants
3586
+ ["group-hover", (s) => `.group:hover ${s}`],
3587
+ ["group-focus", (s) => `.group:focus ${s}`],
3588
+ ["group-active", (s) => `.group:active ${s}`],
3589
+ ["peer-hover", (s) => `.peer:hover ~ ${s}`],
3590
+ ["peer-focus", (s) => `.peer:focus ~ ${s}`],
3591
+ ["peer-checked", (s) => `.peer:checked ~ ${s}`],
3592
+ ["peer-disabled", (s) => `.peer:disabled ~ ${s}`],
3593
+ // Negation variants
3594
+ ["not-hover", (s) => `${s}:not(:hover)`],
3595
+ ["not-focus", (s) => `${s}:not(:focus)`],
3596
+ ["not-disabled", (s) => `${s}:not(:disabled)`],
3597
+ ["not-checked", (s) => `${s}:not(:checked)`],
3598
+ // In-* variants (group-based)
3599
+ ["in-hover", (s) => `.group:hover ${s}`],
3600
+ ["in-focus", (s) => `.group:focus ${s}`]
3601
+ ]);
3602
+ function applyVariants(selector, variants, pluginRegistry) {
3401
3603
  let currentSelector = selector;
3402
- for (const variant of variants2) {
3604
+ for (const variant of variants) {
3403
3605
  if (pluginRegistry) {
3404
3606
  const customHandler = pluginRegistry.matchVariant(variant);
3405
3607
  if (customHandler) {
@@ -3414,180 +3616,11 @@ function applyVariants(selector, variants2, pluginRegistry) {
3414
3616
  }
3415
3617
  }
3416
3618
  }
3417
- switch (variant) {
3418
- case "dark":
3419
- currentSelector = `.dark ${currentSelector}`;
3420
- break;
3421
- case "hover":
3422
- currentSelector = `${currentSelector}:hover`;
3423
- break;
3424
- case "focus":
3425
- currentSelector = `${currentSelector}:focus`;
3426
- break;
3427
- case "focus-visible":
3428
- currentSelector = `${currentSelector}:focus-visible`;
3429
- break;
3430
- case "focus-within":
3431
- currentSelector = `${currentSelector}:focus-within`;
3432
- break;
3433
- case "active":
3434
- currentSelector = `${currentSelector}:active`;
3435
- break;
3436
- case "visited":
3437
- currentSelector = `${currentSelector}:visited`;
3438
- break;
3439
- case "disabled":
3440
- currentSelector = `${currentSelector}:disabled`;
3441
- break;
3442
- case "checked":
3443
- currentSelector = `${currentSelector}:checked`;
3444
- break;
3445
- case "indeterminate":
3446
- currentSelector = `${currentSelector}:indeterminate`;
3447
- break;
3448
- case "required":
3449
- currentSelector = `${currentSelector}:required`;
3450
- break;
3451
- case "valid":
3452
- currentSelector = `${currentSelector}:valid`;
3453
- break;
3454
- case "invalid":
3455
- currentSelector = `${currentSelector}:invalid`;
3456
- break;
3457
- case "target":
3458
- currentSelector = `${currentSelector}:target`;
3459
- break;
3460
- case "enabled":
3461
- currentSelector = `${currentSelector}:enabled`;
3462
- break;
3463
- case "default":
3464
- currentSelector = `${currentSelector}:default`;
3465
- break;
3466
- case "optional":
3467
- currentSelector = `${currentSelector}:optional`;
3468
- break;
3469
- case "user-valid":
3470
- currentSelector = `${currentSelector}:user-valid`;
3471
- break;
3472
- case "user-invalid":
3473
- currentSelector = `${currentSelector}:user-invalid`;
3474
- break;
3475
- case "in-range":
3476
- currentSelector = `${currentSelector}:in-range`;
3477
- break;
3478
- case "out-of-range":
3479
- currentSelector = `${currentSelector}:out-of-range`;
3480
- break;
3481
- case "placeholder-shown":
3482
- currentSelector = `${currentSelector}:placeholder-shown`;
3483
- break;
3484
- case "autofill":
3485
- currentSelector = `${currentSelector}:autofill`;
3486
- break;
3487
- case "details-content":
3488
- currentSelector = `${currentSelector}:details-content`;
3489
- break;
3490
- case "placeholder":
3491
- currentSelector = `${currentSelector}::placeholder`;
3492
- break;
3493
- case "backdrop":
3494
- currentSelector = `${currentSelector}::backdrop`;
3495
- break;
3496
- case "before":
3497
- currentSelector = `${currentSelector}::before`;
3498
- break;
3499
- case "after":
3500
- currentSelector = `${currentSelector}::after`;
3501
- break;
3502
- case "first-letter":
3503
- currentSelector = `${currentSelector}::first-letter`;
3504
- break;
3505
- case "first-line":
3506
- currentSelector = `${currentSelector}::first-line`;
3507
- break;
3508
- case "marker":
3509
- currentSelector = `${currentSelector}::marker`;
3510
- break;
3511
- case "selection":
3512
- currentSelector = `${currentSelector}::selection`;
3513
- break;
3514
- case "file":
3515
- currentSelector = `${currentSelector}::file-selector-button`;
3516
- break;
3517
- case "first":
3518
- currentSelector = `${currentSelector}:first-child`;
3519
- break;
3520
- case "last":
3521
- currentSelector = `${currentSelector}:last-child`;
3522
- break;
3523
- case "odd":
3524
- currentSelector = `${currentSelector}:nth-child(odd)`;
3525
- break;
3526
- case "even":
3527
- currentSelector = `${currentSelector}:nth-child(even)`;
3528
- break;
3529
- case "first-of-type":
3530
- currentSelector = `${currentSelector}:first-of-type`;
3531
- break;
3532
- case "last-of-type":
3533
- currentSelector = `${currentSelector}:last-of-type`;
3534
- break;
3535
- case "only":
3536
- currentSelector = `${currentSelector}:only-child`;
3537
- break;
3538
- case "only-of-type":
3539
- currentSelector = `${currentSelector}:only-of-type`;
3540
- break;
3541
- case "empty":
3542
- currentSelector = `${currentSelector}:empty`;
3543
- break;
3544
- case "read-only":
3545
- currentSelector = `${currentSelector}:read-only`;
3546
- break;
3547
- case "open":
3548
- currentSelector = `${currentSelector}[open]`;
3549
- break;
3550
- case "group-hover":
3551
- currentSelector = `.group:hover ${currentSelector}`;
3552
- break;
3553
- case "group-focus":
3554
- currentSelector = `.group:focus ${currentSelector}`;
3555
- break;
3556
- case "group-active":
3557
- currentSelector = `.group:active ${currentSelector}`;
3558
- break;
3559
- case "peer-hover":
3560
- currentSelector = `.peer:hover ~ ${currentSelector}`;
3561
- break;
3562
- case "peer-focus":
3563
- currentSelector = `.peer:focus ~ ${currentSelector}`;
3564
- break;
3565
- case "peer-checked":
3566
- currentSelector = `.peer:checked ~ ${currentSelector}`;
3567
- break;
3568
- case "peer-disabled":
3569
- currentSelector = `.peer:disabled ~ ${currentSelector}`;
3570
- break;
3571
- case "not-hover":
3572
- currentSelector = `${currentSelector}:not(:hover)`;
3573
- break;
3574
- case "not-focus":
3575
- currentSelector = `${currentSelector}:not(:focus)`;
3576
- break;
3577
- case "not-disabled":
3578
- currentSelector = `${currentSelector}:not(:disabled)`;
3579
- break;
3580
- case "not-checked":
3581
- currentSelector = `${currentSelector}:not(:checked)`;
3582
- break;
3583
- case "in-hover":
3584
- currentSelector = `.group:hover ${currentSelector}`;
3585
- break;
3586
- case "in-focus":
3587
- currentSelector = `.group:focus ${currentSelector}`;
3588
- break;
3589
- default:
3590
- return void 0;
3619
+ const builtinHandler = VARIANT_MAP.get(variant);
3620
+ if (builtinHandler) {
3621
+ currentSelector = builtinHandler(currentSelector);
3622
+ } else {
3623
+ return void 0;
3591
3624
  }
3592
3625
  }
3593
3626
  return currentSelector;
@@ -3603,7 +3636,7 @@ function resolveRuntimeContext(options = {}) {
3603
3636
  addUtility: (pattern, handler) => pluginRegistry.addUtility(pattern, handler),
3604
3637
  addUtilities: (utilities) => pluginRegistry.addUtilities(utilities),
3605
3638
  addVariant: (name, handler) => pluginRegistry.addVariant(name, handler),
3606
- addVariants: (variants2) => pluginRegistry.addVariants(variants2),
3639
+ addVariants: (variants) => pluginRegistry.addVariants(variants),
3607
3640
  theme: (key) => {
3608
3641
  if (!key) return config.theme || {};
3609
3642
  const keys = key.split(".");
@@ -3634,16 +3667,29 @@ function getBaseTailwindOptions(options = {}) {
3634
3667
  const { id, autoStart, compatMode, compatStyleId, compatGenerateCss, ...tailwindOptions } = options;
3635
3668
  return tailwindOptions;
3636
3669
  }
3670
+ var parseCache = /* @__PURE__ */ new Map();
3671
+ var PARSE_CACHE_MAX_SIZE = 2e3;
3672
+ function getConfigHash(screens, containers) {
3673
+ const screensEmpty = !screens || Object.keys(screens).length === 0;
3674
+ const containersEmpty = !containers || Object.keys(containers).length === 0;
3675
+ if (screensEmpty && containersEmpty) return "default";
3676
+ return `${Object.keys(screens || {}).join(",")}|${Object.keys(containers || {}).join(",")}`;
3677
+ }
3637
3678
  function parseClass(className, screens = {}, containers = {}) {
3638
3679
  if (typeof className !== "string") return null;
3639
3680
  const token = className.trim();
3640
3681
  if (!token) return null;
3682
+ const configHash = getConfigHash(screens, containers);
3683
+ const cacheKey = `${token}:${configHash}`;
3684
+ if (parseCache.has(cacheKey)) {
3685
+ return parseCache.get(cacheKey);
3686
+ }
3641
3687
  const important = token.startsWith("!");
3642
3688
  const normalized = important ? token.slice(1) : token;
3643
3689
  const parts = splitByVariantDelimiter(normalized);
3644
3690
  if (parts.length === 0) return null;
3645
3691
  const baseToken = parts[parts.length - 1];
3646
- const variants2 = [];
3692
+ const variants = [];
3647
3693
  let breakpoint = null;
3648
3694
  let containerBreakpoint = null;
3649
3695
  let starting = false;
@@ -3664,9 +3710,15 @@ function parseClass(className, screens = {}, containers = {}) {
3664
3710
  breakpoint = part;
3665
3711
  continue;
3666
3712
  }
3667
- variants2.push(part);
3713
+ variants.push(part);
3714
+ }
3715
+ const result = { original: token, baseToken, variants, breakpoint, containerBreakpoint, important, starting };
3716
+ if (parseCache.size >= PARSE_CACHE_MAX_SIZE) {
3717
+ const firstKey = parseCache.keys().next().value;
3718
+ parseCache.delete(firstKey);
3668
3719
  }
3669
- return { original: token, baseToken, variants: variants2, breakpoint, containerBreakpoint, important, starting };
3720
+ parseCache.set(cacheKey, result);
3721
+ return result;
3670
3722
  }
3671
3723
  function compileRuntimeClassNameWithContext(className, context) {
3672
3724
  const parsed = parseClass(className, context.screens, context.containers);
@@ -3769,6 +3821,9 @@ function createWindrunner(options = {}) {
3769
3821
  const preflight2 = options.preflight !== false;
3770
3822
  const compatMode = options.compatMode || "none";
3771
3823
  const compatStyleId = options.compatStyleId || `${styleId}-full`;
3824
+ const maxCacheSize = options.maxCacheSize || 1e4;
3825
+ const onError = typeof options.onError === "function" ? options.onError : null;
3826
+ const onCompile = typeof options.onCompile === "function" ? options.onCompile : null;
3772
3827
  const tailwindOptions = getBaseTailwindOptions(options);
3773
3828
  const context = resolveRuntimeContext(tailwindOptions);
3774
3829
  const cache = /* @__PURE__ */ new Map();
@@ -3814,6 +3869,10 @@ function createWindrunner(options = {}) {
3814
3869
  const compileWithCache = (className) => {
3815
3870
  if (cache.has(className)) return cache.get(className);
3816
3871
  const cssRule = compileRuntimeClassNameWithContext(className, context);
3872
+ if (cache.size >= maxCacheSize) {
3873
+ const firstKey = cache.keys().next().value;
3874
+ cache.delete(firstKey);
3875
+ }
3817
3876
  cache.set(className, cssRule);
3818
3877
  return cssRule;
3819
3878
  };
@@ -3836,8 +3895,10 @@ function createWindrunner(options = {}) {
3836
3895
  const cssRule = compileWithCache(className);
3837
3896
  if (!cssRule) {
3838
3897
  ensureCompatStyle();
3898
+ if (onError) onError(className);
3839
3899
  } else {
3840
3900
  insertRule(cssRule);
3901
+ if (onCompile) onCompile(className, cssRule);
3841
3902
  }
3842
3903
  return cssRule;
3843
3904
  };
@@ -3940,6 +4001,16 @@ function createWindrunner(options = {}) {
3940
4001
  }
3941
4002
  runStart();
3942
4003
  };
4004
+ const clearCache = () => {
4005
+ cache.clear();
4006
+ };
4007
+ const getStats = () => ({
4008
+ cacheSize: cache.size,
4009
+ insertedRuleCount: insertedRules.size,
4010
+ pendingElementCount: pendingElements.size,
4011
+ isObserving: observer !== null,
4012
+ isCompatLoaded: compatLoaded
4013
+ });
3943
4014
  return {
3944
4015
  processClassName,
3945
4016
  processClassList,
@@ -3949,6 +4020,8 @@ function createWindrunner(options = {}) {
3949
4020
  flush,
3950
4021
  start,
3951
4022
  disconnect,
4023
+ clearCache,
4024
+ getStats,
3952
4025
  isCompatLoaded: () => compatLoaded,
3953
4026
  getCacheSize: () => cache.size,
3954
4027
  getInsertedRuleCount: () => insertedRules.size