clava 0.2.4 → 0.4.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/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import clsx from "clsx";
2
2
  //#region src/utils.ts
3
- const hasOwn$1 = Object.prototype.hasOwnProperty;
3
+ const hasOwn = Object.prototype.hasOwnProperty;
4
4
  function isAsciiLetter(code) {
5
5
  if (code >= 65 && code <= 90) return true;
6
6
  return code >= 97 && code <= 122;
@@ -137,7 +137,7 @@ function htmlStyleToStyleValue(styleString) {
137
137
  function htmlObjStyleToStyleValue(style) {
138
138
  const result = {};
139
139
  for (const key in style) {
140
- if (!hasOwn$1.call(style, key)) continue;
140
+ if (!hasOwn.call(style, key)) continue;
141
141
  const value = style[key];
142
142
  if (value == null) continue;
143
143
  result[hyphenToCamel(key)] = parseLengthValue(value);
@@ -153,7 +153,7 @@ function htmlObjStyleToStyleValue(style) {
153
153
  function jsxStyleToStyleValue(style) {
154
154
  const result = {};
155
155
  for (const key in style) {
156
- if (!hasOwn$1.call(style, key)) continue;
156
+ if (!hasOwn.call(style, key)) continue;
157
157
  const value = style[key];
158
158
  if (value == null) continue;
159
159
  result[key] = parseLengthValue(value);
@@ -169,7 +169,7 @@ function jsxStyleToStyleValue(style) {
169
169
  function styleValueToHTMLStyle(style) {
170
170
  let result = "";
171
171
  for (const key in style) {
172
- if (!hasOwn$1.call(style, key)) continue;
172
+ if (!hasOwn.call(style, key)) continue;
173
173
  const value = style[key];
174
174
  if (value == null) continue;
175
175
  if (result) result += "; ";
@@ -189,7 +189,7 @@ function styleValueToHTMLStyle(style) {
189
189
  function styleValueToHTMLObjStyle(style) {
190
190
  const result = {};
191
191
  for (const key in style) {
192
- if (!hasOwn$1.call(style, key)) continue;
192
+ if (!hasOwn.call(style, key)) continue;
193
193
  const value = style[key];
194
194
  if (value == null) continue;
195
195
  result[camelToHyphen(key)] = value;
@@ -213,7 +213,7 @@ function styleValueToJSXStyle(style) {
213
213
  */
214
214
  function isHTMLObjStyle(style) {
215
215
  for (const key in style) {
216
- if (!hasOwn$1.call(style, key)) continue;
216
+ if (!hasOwn.call(style, key)) continue;
217
217
  if (key.length >= 2 && key.charCodeAt(0) === 45 && key.charCodeAt(1) === 45) continue;
218
218
  if (key.indexOf("-") !== -1) return true;
219
219
  }
@@ -222,8 +222,51 @@ function isHTMLObjStyle(style) {
222
222
  //#endregion
223
223
  //#region src/index.ts
224
224
  const META_KEY = "__meta";
225
- const hasOwn = Object.prototype.hasOwnProperty;
226
225
  const EMPTY_DEFAULTS = Object.freeze({});
226
+ const MAX_REFINE_RUNS = 50;
227
+ function areVariantsEqual(a, b) {
228
+ for (const key in a) {
229
+ if (!Object.hasOwn(a, key)) continue;
230
+ if (!Object.is(a[key], b[key])) return false;
231
+ }
232
+ for (const key in b) {
233
+ if (!Object.hasOwn(b, key)) continue;
234
+ if (!Object.hasOwn(a, key)) return false;
235
+ }
236
+ return true;
237
+ }
238
+ function warnRefineLimit(runState) {
239
+ if (runState.warned) return;
240
+ runState.warned = true;
241
+ if (process.env.NODE_ENV !== "production") console.warn("Clava: Maximum refine iterations exceeded. This can happen when a refine callback calls setVariants or setDefaultVariants, but one of the variants changes on every run.");
242
+ }
243
+ function getExtUserVariantProps(userVariantProps, protectedVariants, changedVariants) {
244
+ const extUserVariantProps = {};
245
+ Object.assign(extUserVariantProps, userVariantProps);
246
+ if (protectedVariants) Object.assign(extUserVariantProps, protectedVariants);
247
+ if (changedVariants) Object.assign(extUserVariantProps, changedVariants);
248
+ return extUserVariantProps;
249
+ }
250
+ function mergeVariants(target, source, skipKeys) {
251
+ let changed = false;
252
+ if (!skipKeys || skipKeys.size === 0) {
253
+ for (const key in source) {
254
+ if (!Object.hasOwn(source, key)) continue;
255
+ const value = source[key];
256
+ if (!Object.is(target[key], value)) changed = true;
257
+ target[key] = value;
258
+ }
259
+ return changed;
260
+ }
261
+ for (const key in source) {
262
+ if (!Object.hasOwn(source, key)) continue;
263
+ if (skipKeys.has(key)) continue;
264
+ const value = source[key];
265
+ if (!Object.is(target[key], value)) changed = true;
266
+ target[key] = value;
267
+ }
268
+ return changed;
269
+ }
227
270
  function getComponentMeta(component) {
228
271
  return component[META_KEY];
229
272
  }
@@ -284,17 +327,13 @@ function collectVariantKeys(config) {
284
327
  for (let i = 0; i < extKeys.length; i++) keys.add(extKeys[i]);
285
328
  }
286
329
  if (config.variants) for (const key in config.variants) {
287
- if (!hasOwn.call(config.variants, key)) continue;
330
+ if (!Object.hasOwn(config.variants, key)) continue;
288
331
  if (config.variants[key] === null) {
289
332
  keys.delete(key);
290
333
  continue;
291
334
  }
292
335
  keys.add(key);
293
336
  }
294
- if (config.computedVariants) for (const key in config.computedVariants) {
295
- if (!hasOwn.call(config.computedVariants, key)) continue;
296
- keys.add(key);
297
- }
298
337
  return Array.from(keys);
299
338
  }
300
339
  function isVariantDisabled(config, key) {
@@ -316,7 +355,7 @@ function collectDisabledVariantKeys(config) {
316
355
  const keys = /* @__PURE__ */ new Set();
317
356
  if (!config.variants) return keys;
318
357
  for (const key in config.variants) {
319
- if (!hasOwn.call(config.variants, key)) continue;
358
+ if (!Object.hasOwn(config.variants, key)) continue;
320
359
  if (config.variants[key] === null) keys.add(key);
321
360
  }
322
361
  return keys;
@@ -325,12 +364,12 @@ function collectDisabledVariantValues(config) {
325
364
  const values = {};
326
365
  if (!config.variants) return values;
327
366
  for (const key in config.variants) {
328
- if (!hasOwn.call(config.variants, key)) continue;
367
+ if (!Object.hasOwn(config.variants, key)) continue;
329
368
  const variant = config.variants[key];
330
369
  if (!isRecordObject(variant)) continue;
331
370
  let bucket;
332
371
  for (const variantValue in variant) {
333
- if (!hasOwn.call(variant, variantValue)) continue;
372
+ if (!Object.hasOwn(variant, variantValue)) continue;
334
373
  if (variant[variantValue] !== null) continue;
335
374
  if (!bucket) {
336
375
  bucket = /* @__PURE__ */ new Set();
@@ -342,23 +381,24 @@ function collectDisabledVariantValues(config) {
342
381
  return values;
343
382
  }
344
383
  const EMPTY_SOURCE = {
345
- keys: [],
384
+ propKeys: [],
346
385
  variantKeys: [],
347
386
  isComponent: false
348
387
  };
349
388
  function normalizeKeySource(source) {
350
389
  if (Array.isArray(source)) return {
351
- keys: source,
390
+ propKeys: source,
352
391
  variantKeys: source,
353
392
  isComponent: false
354
393
  };
355
394
  if (!source) return EMPTY_SOURCE;
356
395
  if (typeof source !== "object" && typeof source !== "function") return EMPTY_SOURCE;
357
- if (!("keys" in source)) return EMPTY_SOURCE;
358
- if (!("variantKeys" in source)) return EMPTY_SOURCE;
359
396
  const typed = source;
397
+ if (typeof typed.getVariants !== "function") return EMPTY_SOURCE;
398
+ if (!Array.isArray(typed.propKeys)) return EMPTY_SOURCE;
399
+ if (!Array.isArray(typed.variantKeys)) return EMPTY_SOURCE;
360
400
  return {
361
- keys: typed.keys,
401
+ propKeys: typed.propKeys,
362
402
  variantKeys: typed.variantKeys,
363
403
  isComponent: true
364
404
  };
@@ -384,7 +424,7 @@ function splitPropsImpl(selfKeys, selfIsComponent, props, sources) {
384
424
  for (let s = 0; s < sourcesLength; s++) {
385
425
  const source = normalizeKeySource(sources[s]);
386
426
  const sourceResult = {};
387
- const effectiveKeys = source.isComponent && stylingClaimed ? source.variantKeys : source.keys;
427
+ const effectiveKeys = source.isComponent && stylingClaimed ? source.variantKeys : source.propKeys;
388
428
  const effectiveKeysLength = effectiveKeys.length;
389
429
  for (let i = 0; i < effectiveKeysLength; i++) {
390
430
  const key = effectiveKeys[i];
@@ -422,7 +462,7 @@ function splitPropsImpl(selfKeys, selfIsComponent, props, sources) {
422
462
  */
423
463
  const splitProps = ((props, source1, ...sources) => {
424
464
  const normalizedSource1 = normalizeKeySource(source1);
425
- return splitPropsImpl(normalizedSource1.keys, normalizedSource1.isComponent, props, sources);
465
+ return splitPropsImpl(normalizedSource1.propKeys, normalizedSource1.isComponent, props, sources);
426
466
  });
427
467
  function buildPrebuiltVariant(variantDef) {
428
468
  if (!isRecordObject(variantDef)) return {
@@ -433,7 +473,7 @@ function buildPrebuiltVariant(variantDef) {
433
473
  const values = {};
434
474
  let disabledValues = null;
435
475
  for (const key in variantDef) {
436
- if (!hasOwn.call(variantDef, key)) continue;
476
+ if (!Object.hasOwn(variantDef, key)) continue;
437
477
  const value = variantDef[key];
438
478
  if (value === null) {
439
479
  if (!disabledValues) disabledValues = /* @__PURE__ */ new Set();
@@ -470,42 +510,41 @@ function create({ transformClass = (className) => className } = {}) {
470
510
  const extend = config.extend;
471
511
  const hasExtend = !!extend && extend.length > 0;
472
512
  const variants = config.variants;
473
- const computedVariantsCfg = config.computedVariants;
474
- const computed = config.computed;
513
+ const refine = config.refine;
475
514
  const baseStyle = config.style;
476
515
  const hasBaseStyle = !!baseStyle;
477
516
  const variantEntryNames = [];
478
517
  const variantEntryDefs = [];
518
+ const functionVariantNames = [];
519
+ const functionVariantFns = [];
479
520
  if (variants) for (const name in variants) {
480
- if (!hasOwn.call(variants, name)) continue;
521
+ if (!Object.hasOwn(variants, name)) continue;
481
522
  const variant = variants[name];
482
523
  if (variant === null) continue;
524
+ if (typeof variant === "function") {
525
+ functionVariantNames.push(name);
526
+ functionVariantFns.push(variant);
527
+ continue;
528
+ }
483
529
  variantEntryNames.push(name);
484
530
  variantEntryDefs.push(buildPrebuiltVariant(variant));
485
531
  }
486
532
  const variantEntryCount = variantEntryNames.length;
487
- const computedVariantNames = [];
488
- const computedVariantFns = [];
489
- if (computedVariantsCfg) for (const name in computedVariantsCfg) {
490
- if (!hasOwn.call(computedVariantsCfg, name)) continue;
491
- computedVariantNames.push(name);
492
- computedVariantFns.push(computedVariantsCfg[name]);
493
- }
494
- const computedVariantCount = computedVariantNames.length;
533
+ const functionVariantCount = functionVariantNames.length;
495
534
  const staticDefaults = {};
496
535
  if (extend) for (const ext of extend) {
497
536
  const meta = getComponentMeta(ext);
498
537
  if (meta) Object.assign(staticDefaults, meta.staticDefaults);
499
538
  }
500
539
  if (variants) for (const name in variants) {
501
- if (!hasOwn.call(variants, name)) continue;
540
+ if (!Object.hasOwn(variants, name)) continue;
502
541
  const variantDef = variants[name];
503
542
  if (!isRecordObject(variantDef)) continue;
504
- if (hasOwn.call(variantDef, "false") && staticDefaults[name] === void 0) staticDefaults[name] = false;
543
+ if (Object.hasOwn(variantDef, "false") && staticDefaults[name] === void 0) staticDefaults[name] = false;
505
544
  }
506
545
  if (config.defaultVariants) Object.assign(staticDefaults, config.defaultVariants);
507
546
  if (hasAnyDisabled) for (const key in staticDefaults) {
508
- if (!hasOwn.call(staticDefaults, key)) continue;
547
+ if (!Object.hasOwn(staticDefaults, key)) continue;
509
548
  if (disabledVariantKeys.has(key)) {
510
549
  delete staticDefaults[key];
511
550
  continue;
@@ -520,7 +559,7 @@ function create({ transformClass = (className) => className } = {}) {
520
559
  const extBaseClassesArr = [];
521
560
  const extIsolated = [];
522
561
  let hasIsolatedExt = false;
523
- if (extend) for (const ext of extend) {
562
+ if (hasExtend) for (const ext of extend) {
524
563
  const meta = getComponentMeta(ext);
525
564
  if (!meta) continue;
526
565
  extMetas.push(meta);
@@ -532,23 +571,47 @@ function create({ transformClass = (className) => className } = {}) {
532
571
  } else extBaseClassesArr.push(meta.baseClass);
533
572
  }
534
573
  const extCount = extMetas.length;
535
- const extMetasWithResolveDefaults = [];
536
- for (let i = 0; i < extCount; i++) if (extMetas[i].resolveDefaults) extMetasWithResolveDefaults.push(extMetas[i]);
537
- const extMetasWithResolveDefaultsCount = extMetasWithResolveDefaults.length;
574
+ const extMetasWithRefine = [];
575
+ for (let i = 0; i < extCount; i++) {
576
+ const meta = extMetas[i];
577
+ if (meta.resolveDefaults) extMetasWithRefine.push(meta);
578
+ }
579
+ const extMetasWithRefineCount = extMetasWithRefine.length;
580
+ const shouldCollectChangedVariants = extMetasWithRefineCount > 0;
581
+ const functionVariantKeys = /* @__PURE__ */ new Set();
582
+ for (let i = 0; i < extCount; i++) {
583
+ const fnKeys = extMetas[i].functionVariantKeys;
584
+ for (const k of fnKeys) {
585
+ if (disabledVariantKeys.has(k)) continue;
586
+ functionVariantKeys.add(k);
587
+ }
588
+ }
589
+ for (let i = 0; i < functionVariantCount; i++) functionVariantKeys.add(functionVariantNames[i]);
590
+ for (let i = 0; i < variantEntryCount; i++) functionVariantKeys.delete(variantEntryNames[i]);
591
+ let staticVariantsOverridingExtFn = null;
592
+ if (variantEntryCount > 0 && extCount > 0) for (let i = 0; i < variantEntryCount; i++) {
593
+ const name = variantEntryNames[i];
594
+ for (let j = 0; j < extCount; j++) if (extMetas[j].functionVariantKeys.has(name)) {
595
+ if (!staticVariantsOverridingExtFn) staticVariantsOverridingExtFn = [];
596
+ staticVariantsOverridingExtFn.push(name);
597
+ break;
598
+ }
599
+ }
538
600
  let staticExtSkipKeys = null;
539
- if (hasDisabledVariantKeys || computedVariantCount > 0) {
601
+ if (hasDisabledVariantKeys || functionVariantCount > 0 || staticVariantsOverridingExtFn !== null) {
540
602
  staticExtSkipKeys = /* @__PURE__ */ new Set();
541
603
  for (const k of disabledVariantKeys) staticExtSkipKeys.add(k);
542
- for (let i = 0; i < computedVariantCount; i++) staticExtSkipKeys.add(computedVariantNames[i]);
604
+ for (let i = 0; i < functionVariantCount; i++) staticExtSkipKeys.add(functionVariantNames[i]);
605
+ if (staticVariantsOverridingExtFn) for (const k of staticVariantsOverridingExtFn) staticExtSkipKeys.add(k);
543
606
  }
544
607
  const staticExtSkipValues = hasDisabledVariantValues ? disabledVariantValues : null;
545
608
  function filterDisabledInto(input, out) {
546
609
  if (!hasAnyDisabled) {
547
- for (const key in input) if (hasOwn.call(input, key)) out[key] = input[key];
610
+ for (const key in input) if (Object.hasOwn(input, key)) out[key] = input[key];
548
611
  return;
549
612
  }
550
613
  for (const key in input) {
551
- if (!hasOwn.call(input, key)) continue;
614
+ if (!Object.hasOwn(input, key)) continue;
552
615
  if (disabledVariantKeys.has(key)) continue;
553
616
  const value = input[key];
554
617
  if (hasDisabledVariantValues) {
@@ -558,66 +621,66 @@ function create({ transformClass = (className) => className } = {}) {
558
621
  out[key] = value;
559
622
  }
560
623
  }
561
- const resolveDefaultsFn = computed || extMetasWithResolveDefaultsCount > 0 ? (childDefaults, userProps = EMPTY_DEFAULTS) => {
624
+ const resolveDefaultsFn = refine || extMetasWithRefineCount > 0 ? (childDefaults, userProps = EMPTY_DEFAULTS) => {
562
625
  const resolvedVariants = {};
563
626
  Object.assign(resolvedVariants, staticDefaults);
564
627
  for (const key in childDefaults) {
565
- if (!hasOwn.call(childDefaults, key)) continue;
628
+ if (!Object.hasOwn(childDefaults, key)) continue;
566
629
  const v = childDefaults[key];
567
630
  if (v === void 0) continue;
568
631
  resolvedVariants[key] = v;
569
632
  }
570
633
  for (const key in userProps) {
571
- if (!hasOwn.call(userProps, key)) continue;
634
+ if (!Object.hasOwn(userProps, key)) continue;
572
635
  const v = userProps[key];
573
636
  if (v === void 0) continue;
574
637
  resolvedVariants[key] = v;
575
638
  }
576
- const computedDefaults = {};
577
- for (let i = 0; i < extMetasWithResolveDefaultsCount; i++) {
578
- const extDefaults = extMetasWithResolveDefaults[i].resolveDefaults(childDefaults, userProps);
639
+ const refineDefaults = {};
640
+ for (let i = 0; i < extMetasWithRefineCount; i++) {
641
+ const extDefaults = extMetasWithRefine[i].resolveDefaults(childDefaults, userProps);
579
642
  for (const k in extDefaults) {
580
- if (!hasOwn.call(extDefaults, k)) continue;
581
- computedDefaults[k] = extDefaults[k];
643
+ if (!Object.hasOwn(extDefaults, k)) continue;
644
+ refineDefaults[k] = extDefaults[k];
582
645
  }
583
646
  }
584
- if (computed) {
647
+ if (refine) {
585
648
  const ownVariants = {};
586
649
  for (let i = 0; i < variantKeysLength; i++) {
587
650
  const k = variantKeys[i];
588
- if (hasOwn.call(resolvedVariants, k)) ownVariants[k] = resolvedVariants[k];
651
+ if (Object.hasOwn(resolvedVariants, k)) ownVariants[k] = resolvedVariants[k];
589
652
  }
590
- computed({
653
+ refine({
591
654
  variants: ownVariants,
592
655
  setVariants: noop,
593
656
  setDefaultVariants: (newDefaults) => {
594
657
  for (const key in newDefaults) {
595
- if (!hasOwn.call(newDefaults, key)) continue;
658
+ if (!Object.hasOwn(newDefaults, key)) continue;
596
659
  const value = newDefaults[key];
597
660
  if (userProps[key] !== void 0) continue;
598
661
  if (isVariantDisabled(config, key)) continue;
599
662
  if (isVariantValueDisabled(config, key, value)) continue;
600
- computedDefaults[key] = value;
663
+ refineDefaults[key] = value;
601
664
  }
602
665
  },
603
666
  addClass: noop,
604
667
  addStyle: noop
605
668
  });
606
669
  }
607
- return computedDefaults;
670
+ return refineDefaults;
608
671
  } : null;
609
672
  function resolveVariantsHot(propsVariants) {
610
673
  const defaults = {};
611
674
  Object.assign(defaults, staticDefaults);
612
- for (let i = 0; i < extMetasWithResolveDefaultsCount; i++) {
613
- const extComputed = extMetasWithResolveDefaults[i].resolveDefaults(defaults, propsVariants);
614
- for (const k in extComputed) {
615
- if (!hasOwn.call(extComputed, k)) continue;
616
- defaults[k] = extComputed[k];
675
+ for (let i = 0; i < extMetasWithRefineCount; i++) {
676
+ const extDefaults = extMetasWithRefine[i].resolveDefaults(defaults, propsVariants);
677
+ for (const k in extDefaults) {
678
+ if (!Object.hasOwn(extDefaults, k)) continue;
679
+ defaults[k] = extDefaults[k];
617
680
  }
618
681
  }
619
682
  for (const k in propsVariants) {
620
- if (!hasOwn.call(propsVariants, k)) continue;
683
+ if (!Object.hasOwn(propsVariants, k)) continue;
621
684
  const v = propsVariants[k];
622
685
  if (v === void 0) continue;
623
686
  defaults[k] = v;
@@ -627,18 +690,23 @@ function create({ transformClass = (className) => className } = {}) {
627
690
  filterDisabledInto(defaults, result);
628
691
  return result;
629
692
  }
630
- const compute = (resolved, userVariantProps, skipKeys, skipValues, classesOut, styleOut) => {
693
+ const runRefineContext = (resolved, userVariantProps, filterOwnVariants, collectOutput, protectedVariants, pendingProtectedVariants, protectedVariantKeys) => {
631
694
  let workingResolved = resolved;
632
695
  let cClasses = null;
633
696
  let cStyle = null;
634
- if (computed) {
635
- const ownVariants = {};
636
- for (let i = 0; i < variantKeysLength; i++) {
637
- const k = variantKeys[i];
638
- if (hasOwn.call(resolved, k)) ownVariants[k] = resolved[k];
697
+ let changedVariants = null;
698
+ if (refine) {
699
+ let ownVariants = resolved;
700
+ if (filterOwnVariants) {
701
+ const filteredVariants = {};
702
+ for (let i = 0; i < variantKeysLength; i++) {
703
+ const k = variantKeys[i];
704
+ if (Object.hasOwn(resolved, k)) filteredVariants[k] = resolved[k];
705
+ }
706
+ ownVariants = filteredVariants;
639
707
  }
640
708
  let updatedVariants = null;
641
- const localCClasses = [];
709
+ const localCClasses = collectOutput ? [] : null;
642
710
  let localCStyle = null;
643
711
  const ensureUpdated = () => {
644
712
  if (updatedVariants) return updatedVariants;
@@ -647,48 +715,74 @@ function create({ transformClass = (className) => className } = {}) {
647
715
  updatedVariants = u;
648
716
  return u;
649
717
  };
650
- const result = computed({
718
+ const setChangedVariant = (key, value, protect = false) => {
719
+ if (shouldCollectChangedVariants) {
720
+ if (!changedVariants) changedVariants = {};
721
+ changedVariants[key] = value;
722
+ }
723
+ if (protect && protectedVariants) {
724
+ protectedVariants[key] = value;
725
+ protectedVariantKeys?.add(key);
726
+ }
727
+ };
728
+ const getCurrentVariantValue = (key) => {
729
+ return updatedVariants ? updatedVariants[key] : ownVariants[key];
730
+ };
731
+ const result = refine({
651
732
  variants: ownVariants,
652
733
  setVariants: (newVariants) => {
653
734
  if (!hasAnyDisabled) {
654
- Object.assign(ensureUpdated(), newVariants);
735
+ for (const key in newVariants) {
736
+ if (!Object.hasOwn(newVariants, key)) continue;
737
+ const value = newVariants[key];
738
+ setChangedVariant(key, value, true);
739
+ if (getCurrentVariantValue(key) === value) continue;
740
+ ensureUpdated()[key] = value;
741
+ }
655
742
  return;
656
743
  }
657
744
  for (const key in newVariants) {
658
- if (!hasOwn.call(newVariants, key)) continue;
745
+ if (!Object.hasOwn(newVariants, key)) continue;
659
746
  if (disabledVariantKeys.has(key)) continue;
660
747
  const value = newVariants[key];
661
748
  if (hasDisabledVariantValues) {
662
749
  const valueKey = getVariantValueKey(value);
663
750
  if (valueKey != null && disabledVariantValues[key]?.has(valueKey)) continue;
664
751
  }
752
+ setChangedVariant(key, value, true);
753
+ if (getCurrentVariantValue(key) === value) continue;
665
754
  ensureUpdated()[key] = value;
666
755
  }
667
756
  },
668
757
  setDefaultVariants: (newDefaults) => {
669
758
  for (const key in newDefaults) {
670
- if (!hasOwn.call(newDefaults, key)) continue;
759
+ if (!Object.hasOwn(newDefaults, key)) continue;
671
760
  if (userVariantProps[key] !== void 0) continue;
761
+ if (protectedVariantKeys?.has(key)) continue;
672
762
  const value = newDefaults[key];
673
763
  if (hasAnyDisabled) {
674
764
  if (disabledVariantKeys.has(key)) continue;
675
765
  const valueKey = getVariantValueKey(value);
676
766
  if (valueKey != null && disabledVariantValues[key]?.has(valueKey)) continue;
677
767
  }
768
+ setChangedVariant(key, value);
769
+ if (pendingProtectedVariants) pendingProtectedVariants[key] = value;
770
+ if (getCurrentVariantValue(key) === value) continue;
678
771
  ensureUpdated()[key] = value;
679
772
  }
680
773
  },
681
774
  addClass: (className) => {
682
- localCClasses.push(className);
775
+ localCClasses?.push(className);
683
776
  },
684
777
  addStyle: (newStyle) => {
778
+ if (!collectOutput) return;
685
779
  if (!localCStyle) localCStyle = {};
686
780
  Object.assign(localCStyle, newStyle);
687
781
  }
688
782
  });
689
- if (result != null) {
783
+ if (collectOutput && result != null) {
690
784
  const r = extractClassAndStylePrebuilt(result);
691
- if (r.class != null) localCClasses.push(r.class);
785
+ if (r.class != null) localCClasses?.push(r.class);
692
786
  if (r.style) {
693
787
  if (!localCStyle) localCStyle = {};
694
788
  Object.assign(localCStyle, r.style);
@@ -696,42 +790,72 @@ function create({ transformClass = (className) => className } = {}) {
696
790
  }
697
791
  cClasses = localCClasses;
698
792
  cStyle = localCStyle;
699
- if (updatedVariants) if (hasAnyDisabled) {
700
- const filteredUpdated = {};
701
- filterDisabledInto(updatedVariants, filteredUpdated);
702
- workingResolved = filteredUpdated;
703
- } else workingResolved = updatedVariants;
793
+ if (updatedVariants) {
794
+ const nextResolved = {};
795
+ Object.assign(nextResolved, workingResolved);
796
+ if (hasAnyDisabled) {
797
+ const filteredUpdated = {};
798
+ filterDisabledInto(updatedVariants, filteredUpdated);
799
+ Object.assign(nextResolved, filteredUpdated);
800
+ } else Object.assign(nextResolved, updatedVariants);
801
+ workingResolved = nextResolved;
802
+ }
704
803
  }
705
- let extSkipKeys;
706
- if (skipKeys === null) extSkipKeys = staticExtSkipKeys;
707
- else if (staticExtSkipKeys === null) extSkipKeys = skipKeys;
708
- else {
709
- extSkipKeys = new Set(skipKeys);
710
- for (const k of staticExtSkipKeys) extSkipKeys.add(k);
804
+ return {
805
+ workingResolved,
806
+ changedVariants,
807
+ classes: cClasses,
808
+ style: cStyle
809
+ };
810
+ };
811
+ const computeOnce = (resolved, userVariantProps, skipKeys, skipValues, classesOut, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys) => {
812
+ let workingResolved = resolved;
813
+ let cClasses = null;
814
+ let cStyle = null;
815
+ let changedVariants = null;
816
+ if (refine) {
817
+ const refineResult = runRefineContext(resolved, userVariantProps, true, true, protectedVariants, pendingProtectedVariants, protectedVariantKeys);
818
+ workingResolved = refineResult.workingResolved;
819
+ cClasses = refineResult.classes;
820
+ cStyle = refineResult.style;
821
+ changedVariants = refineResult.changedVariants;
711
822
  }
712
- let extSkipVals;
713
- if (skipValues === null) extSkipVals = staticExtSkipValues;
714
- else if (staticExtSkipValues === null) extSkipVals = skipValues;
715
- else {
716
- extSkipVals = {};
717
- for (const k in skipValues) extSkipVals[k] = skipValues[k];
718
- for (const k in staticExtSkipValues) {
719
- const existing = extSkipVals[k];
720
- if (existing) {
721
- const merged = new Set(existing);
722
- for (const v of staticExtSkipValues[k]) merged.add(v);
723
- extSkipVals[k] = merged;
724
- } else extSkipVals[k] = staticExtSkipValues[k];
823
+ if (hasExtend) {
824
+ let extSkipKeys;
825
+ if (skipKeys === null) extSkipKeys = staticExtSkipKeys;
826
+ else if (staticExtSkipKeys === null) extSkipKeys = skipKeys;
827
+ else {
828
+ extSkipKeys = new Set(skipKeys);
829
+ for (const k of staticExtSkipKeys) extSkipKeys.add(k);
725
830
  }
726
- }
727
- if (hasExtend) for (let i = 0; i < extCount; i++) if (hasIsolatedExt && extIsolated[i]) {
728
- const extClasses = [];
729
- extMetas[i].compute(workingResolved, workingResolved, extSkipKeys, extSkipVals, extClasses, styleOut);
730
- if (extClasses.length > 0) {
731
- const joined = clsx(extClasses);
732
- if (joined.length > 0) classesOut.push(extMetas[i].transformClass(joined));
831
+ let extSkipVals;
832
+ if (skipValues === null) extSkipVals = staticExtSkipValues;
833
+ else if (staticExtSkipValues === null) extSkipVals = skipValues;
834
+ else {
835
+ extSkipVals = {};
836
+ for (const k in skipValues) extSkipVals[k] = skipValues[k];
837
+ for (const k in staticExtSkipValues) {
838
+ const existing = extSkipVals[k];
839
+ if (existing) {
840
+ const merged = new Set(existing);
841
+ for (const v of staticExtSkipValues[k]) merged.add(v);
842
+ extSkipVals[k] = merged;
843
+ } else extSkipVals[k] = staticExtSkipValues[k];
844
+ }
733
845
  }
734
- } else extMetas[i].compute(workingResolved, workingResolved, extSkipKeys, extSkipVals, classesOut, styleOut);
846
+ const extUserVariantProps = extMetasWithRefineCount > 0 ? getExtUserVariantProps(userVariantProps, protectedVariants ?? null, changedVariants) : userVariantProps;
847
+ for (let i = 0; i < extCount; i++) {
848
+ if (hasIsolatedExt && extIsolated[i]) {
849
+ const extClasses = [];
850
+ workingResolved = extMetas[i].compute(workingResolved, extUserVariantProps, extSkipKeys, extSkipVals, extClasses, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys);
851
+ if (extClasses.length > 0) {
852
+ const joined = clsx(extClasses);
853
+ if (joined.length > 0) classesOut.push(extMetas[i].transformClass(joined));
854
+ }
855
+ } else workingResolved = extMetas[i].compute(workingResolved, extUserVariantProps, extSkipKeys, extSkipVals, classesOut, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys);
856
+ if (protectedVariants && extMetasWithRefineCount > 0) Object.assign(extUserVariantProps, protectedVariants);
857
+ }
858
+ }
735
859
  if (hasBaseStyle) Object.assign(styleOut, baseStyle);
736
860
  const ownSkipKeys = skipKeys;
737
861
  const ownSkipValues = skipValues;
@@ -756,14 +880,14 @@ function create({ transformClass = (className) => className } = {}) {
756
880
  if (v.style) Object.assign(styleOut, v.style);
757
881
  }
758
882
  }
759
- for (let i = 0; i < computedVariantCount; i++) {
760
- const variantName = computedVariantNames[i];
883
+ for (let i = 0; i < functionVariantCount; i++) {
884
+ const variantName = functionVariantNames[i];
761
885
  if (ownSkipKeys && ownSkipKeys.has(variantName)) continue;
762
886
  const selectedValue = workingResolved[variantName];
763
887
  if (selectedValue === void 0) continue;
764
888
  const selectedKey = getVariantValueKey(selectedValue);
765
889
  if (ownSkipValues && selectedKey != null && ownSkipValues[variantName]?.has(selectedKey)) continue;
766
- const fn = computedVariantFns[i];
890
+ const fn = functionVariantFns[i];
767
891
  const computedResult = fn(selectedValue);
768
892
  if (computedResult == null) continue;
769
893
  const r = extractClassAndStylePrebuilt(computedResult);
@@ -772,27 +896,129 @@ function create({ transformClass = (className) => className } = {}) {
772
896
  }
773
897
  if (cClasses) for (let i = 0; i < cClasses.length; i++) classesOut.push(cClasses[i]);
774
898
  if (cStyle) Object.assign(styleOut, cStyle);
899
+ return workingResolved;
775
900
  };
901
+ const compute = !refine && extMetasWithRefineCount === 0 ? (resolved, userVariantProps, skipKeys, skipValues, classesOut, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys) => {
902
+ return computeOnce(resolved, userVariantProps, skipKeys, skipValues, classesOut, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys);
903
+ } : (resolved, userVariantProps, skipKeys, skipValues, classesOut, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys) => {
904
+ runState ??= {
905
+ remaining: MAX_REFINE_RUNS,
906
+ warned: false
907
+ };
908
+ protectedVariants ??= {};
909
+ protectedVariantKeys ??= /* @__PURE__ */ new Set();
910
+ let workingResolved = resolved;
911
+ let lastClasses = [];
912
+ let lastStyle = {};
913
+ let isFirstRun = true;
914
+ while (runState.remaining > 0) {
915
+ runState.remaining -= 1;
916
+ let useDirectOutput = isFirstRun;
917
+ if (useDirectOutput) {
918
+ for (const key in styleOut) if (Object.hasOwn(styleOut, key)) {
919
+ useDirectOutput = false;
920
+ break;
921
+ }
922
+ }
923
+ const classCount = classesOut.length;
924
+ const nextPendingProtectedVariants = {};
925
+ const nextClasses = useDirectOutput ? classesOut : [];
926
+ const nextStyle = useDirectOutput ? styleOut : {};
927
+ const nextResolved = computeOnce(workingResolved, userVariantProps, skipKeys, skipValues, nextClasses, nextStyle, runState, protectedVariants, nextPendingProtectedVariants, protectedVariantKeys);
928
+ let protectedChanged;
929
+ if (pendingProtectedVariants) protectedChanged = mergeVariants(pendingProtectedVariants, nextPendingProtectedVariants, protectedVariantKeys);
930
+ else protectedChanged = mergeVariants(protectedVariants, nextPendingProtectedVariants, protectedVariantKeys);
931
+ if (!protectedChanged && (nextResolved === workingResolved || areVariantsEqual(workingResolved, nextResolved))) {
932
+ if (!useDirectOutput) {
933
+ for (let i = 0; i < nextClasses.length; i++) classesOut.push(nextClasses[i]);
934
+ Object.assign(styleOut, nextStyle);
935
+ }
936
+ return nextResolved;
937
+ }
938
+ if (useDirectOutput && runState.remaining === 0) {
939
+ warnRefineLimit(runState);
940
+ return nextResolved;
941
+ }
942
+ if (useDirectOutput) {
943
+ classesOut.length = classCount;
944
+ for (const key in styleOut) if (Object.hasOwn(styleOut, key)) Reflect.deleteProperty(styleOut, key);
945
+ } else {
946
+ lastClasses = nextClasses;
947
+ lastStyle = nextStyle;
948
+ }
949
+ workingResolved = nextResolved;
950
+ isFirstRun = false;
951
+ }
952
+ warnRefineLimit(runState);
953
+ for (let i = 0; i < lastClasses.length; i++) classesOut.push(lastClasses[i]);
954
+ Object.assign(styleOut, lastStyle);
955
+ return workingResolved;
956
+ };
957
+ const resolveRefineOnce = (resolved, userVariantProps, filterOwnVariants = true, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys) => {
958
+ let workingResolved = resolved;
959
+ let changedVariants = null;
960
+ if (refine) {
961
+ const refineResult = runRefineContext(resolved, userVariantProps, filterOwnVariants, false, protectedVariants, pendingProtectedVariants, protectedVariantKeys);
962
+ workingResolved = refineResult.workingResolved;
963
+ changedVariants = refineResult.changedVariants;
964
+ }
965
+ if (extMetasWithRefineCount > 0) {
966
+ const extUserVariantProps = getExtUserVariantProps(userVariantProps, protectedVariants ?? null, changedVariants);
967
+ for (let i = 0; i < extMetasWithRefineCount; i++) {
968
+ const resolveRefine = extMetasWithRefine[i].resolveRefine;
969
+ if (!resolveRefine) continue;
970
+ workingResolved = resolveRefine(workingResolved, extUserVariantProps, true, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys);
971
+ if (protectedVariants) Object.assign(extUserVariantProps, protectedVariants);
972
+ }
973
+ }
974
+ return workingResolved;
975
+ };
976
+ const resolveRefine = refine || extMetasWithRefineCount > 0 ? (resolved, userVariantProps, filterOwnVariants = true, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys) => {
977
+ runState ??= {
978
+ remaining: MAX_REFINE_RUNS,
979
+ warned: false
980
+ };
981
+ protectedVariants ??= {};
982
+ protectedVariantKeys ??= /* @__PURE__ */ new Set();
983
+ let workingResolved = resolved;
984
+ let reachedLimit = true;
985
+ while (runState.remaining > 0) {
986
+ runState.remaining -= 1;
987
+ const nextPendingProtectedVariants = {};
988
+ const nextResolved = resolveRefineOnce(workingResolved, userVariantProps, filterOwnVariants, runState, protectedVariants, nextPendingProtectedVariants, protectedVariantKeys);
989
+ let protectedChanged;
990
+ if (pendingProtectedVariants) protectedChanged = mergeVariants(pendingProtectedVariants, nextPendingProtectedVariants, protectedVariantKeys);
991
+ else protectedChanged = mergeVariants(protectedVariants, nextPendingProtectedVariants, protectedVariantKeys);
992
+ if (!protectedChanged && (nextResolved === workingResolved || areVariantsEqual(workingResolved, nextResolved))) {
993
+ workingResolved = nextResolved;
994
+ reachedLimit = false;
995
+ break;
996
+ }
997
+ workingResolved = nextResolved;
998
+ }
999
+ if (reachedLimit) warnRefineLimit(runState);
1000
+ return workingResolved;
1001
+ } : null;
776
1002
  const computeResult = (props = EMPTY_DEFAULTS) => {
777
1003
  const propsRecord = props;
778
1004
  let resolved = {};
779
1005
  Object.assign(resolved, staticDefaults);
780
1006
  let userVariantProps;
781
- if (extMetasWithResolveDefaultsCount > 0) {
1007
+ if (extMetasWithRefineCount > 0) {
782
1008
  const variantProps = {};
783
1009
  for (let i = 0; i < variantKeysLength; i++) {
784
1010
  const key = variantKeys[i];
785
- if (hasOwn.call(propsRecord, key)) variantProps[key] = propsRecord[key];
1011
+ if (Object.hasOwn(propsRecord, key)) variantProps[key] = propsRecord[key];
786
1012
  }
787
- for (let i = 0; i < extMetasWithResolveDefaultsCount; i++) {
788
- const extComputed = extMetasWithResolveDefaults[i].resolveDefaults(resolved, variantProps);
789
- for (const k in extComputed) {
790
- if (!hasOwn.call(extComputed, k)) continue;
791
- resolved[k] = extComputed[k];
1013
+ for (let i = 0; i < extMetasWithRefineCount; i++) {
1014
+ const extDefaults = extMetasWithRefine[i].resolveDefaults(resolved, variantProps);
1015
+ for (const k in extDefaults) {
1016
+ if (!Object.hasOwn(extDefaults, k)) continue;
1017
+ resolved[k] = extDefaults[k];
792
1018
  }
793
1019
  }
794
1020
  for (const k in variantProps) {
795
- if (!hasOwn.call(variantProps, k)) continue;
1021
+ if (!Object.hasOwn(variantProps, k)) continue;
796
1022
  const v = variantProps[k];
797
1023
  if (v === void 0) continue;
798
1024
  resolved[k] = v;
@@ -801,7 +1027,7 @@ function create({ transformClass = (className) => className } = {}) {
801
1027
  } else {
802
1028
  for (let i = 0; i < variantKeysLength; i++) {
803
1029
  const key = variantKeys[i];
804
- if (!hasOwn.call(propsRecord, key)) continue;
1030
+ if (!Object.hasOwn(propsRecord, key)) continue;
805
1031
  const v = propsRecord[key];
806
1032
  if (v === void 0) continue;
807
1033
  resolved[key] = v;
@@ -839,52 +1065,10 @@ function create({ transformClass = (className) => className } = {}) {
839
1065
  const getVariants = (variants) => {
840
1066
  const variantProps = variants ?? EMPTY_DEFAULTS;
841
1067
  let resolvedVariants = resolveVariantsHot(variantProps);
842
- if (computed) {
843
- const updatedVariants = {};
844
- Object.assign(updatedVariants, resolvedVariants);
845
- computed({
846
- variants: resolvedVariants,
847
- setVariants: (newVariants) => {
848
- if (!hasAnyDisabled) {
849
- Object.assign(updatedVariants, newVariants);
850
- return;
851
- }
852
- for (const key in newVariants) {
853
- if (!hasOwn.call(newVariants, key)) continue;
854
- if (disabledVariantKeys.has(key)) continue;
855
- const value = newVariants[key];
856
- if (hasDisabledVariantValues) {
857
- const valueKey = getVariantValueKey(value);
858
- if (valueKey != null && disabledVariantValues[key]?.has(valueKey)) continue;
859
- }
860
- updatedVariants[key] = value;
861
- }
862
- },
863
- setDefaultVariants: (newDefaults) => {
864
- for (const key in newDefaults) {
865
- if (!hasOwn.call(newDefaults, key)) continue;
866
- if (variantProps[key] !== void 0) continue;
867
- const value = newDefaults[key];
868
- if (hasAnyDisabled) {
869
- if (disabledVariantKeys.has(key)) continue;
870
- const valueKey = getVariantValueKey(value);
871
- if (valueKey != null && disabledVariantValues[key]?.has(valueKey)) continue;
872
- }
873
- updatedVariants[key] = value;
874
- }
875
- },
876
- addClass: noop,
877
- addStyle: noop
878
- });
879
- if (hasAnyDisabled) {
880
- const filteredUpdated = {};
881
- filterDisabledInto(updatedVariants, filteredUpdated);
882
- resolvedVariants = filteredUpdated;
883
- } else resolvedVariants = updatedVariants;
884
- }
1068
+ if (resolveRefine) resolvedVariants = resolveRefine(resolvedVariants, variantProps, false);
885
1069
  return resolvedVariants;
886
1070
  };
887
- const computedBaseClass = clsx(...extBaseClassesArr, config.class);
1071
+ const computedBaseClass = hasExtend ? clsx(...extBaseClassesArr, config.class) : clsx(config.class);
888
1072
  const classFn = (props = {}) => {
889
1073
  return computeResult(props).className;
890
1074
  };
@@ -893,15 +1077,16 @@ function create({ transformClass = (className) => className } = {}) {
893
1077
  staticDefaults,
894
1078
  resolveDefaults: resolveDefaultsFn,
895
1079
  compute,
896
- transformClass
1080
+ resolveRefine,
1081
+ transformClass,
1082
+ functionVariantKeys
897
1083
  };
898
- const initComponent = (c, keys, style) => {
1084
+ const initComponent = (c, propKeys, style) => {
899
1085
  c.class = classFn;
900
1086
  c.style = style;
901
1087
  c.getVariants = getVariants;
902
- c.keys = keys;
903
1088
  c.variantKeys = variantKeys;
904
- c.propKeys = keys;
1089
+ c.propKeys = propKeys;
905
1090
  setComponentMeta(c, meta);
906
1091
  return c;
907
1092
  };