clava 0.4.1 → 0.5.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,4 +1,92 @@
1
1
  import clsx from "clsx";
2
+ //#region src/refine-warning.ts
3
+ function captureCreationFrame(skipFn) {
4
+ if (process.env.NODE_ENV === "production") return void 0;
5
+ if (typeof Error.captureStackTrace === "function") {
6
+ const holder = {};
7
+ Error.captureStackTrace(holder, skipFn);
8
+ return holder;
9
+ }
10
+ return /* @__PURE__ */ new Error();
11
+ }
12
+ function formatCreationStack(frame) {
13
+ let stack = frame.stack;
14
+ if (!stack) return void 0;
15
+ const newlineIdx = stack.indexOf("\n");
16
+ if (newlineIdx > 0) {
17
+ const firstLine = stack.slice(0, newlineIdx);
18
+ if (firstLine === "Error" || firstLine.startsWith("Error:")) stack = stack.slice(newlineIdx + 1);
19
+ }
20
+ const frames = stack.split("\n");
21
+ for (let i = 0; i < frames.length; i++) {
22
+ const line = frames[i]?.trim();
23
+ if (!line) continue;
24
+ if (isInternalCreationFrame(line)) continue;
25
+ if (line.includes("/node_modules/")) continue;
26
+ if (line.includes("\\node_modules\\")) continue;
27
+ if (line.includes("node:internal")) continue;
28
+ return ` ${line}`;
29
+ }
30
+ }
31
+ function isInternalCreationFrame(line) {
32
+ if (line.includes("captureCreationFrame")) return true;
33
+ if (line.startsWith("at cv ")) return true;
34
+ if (line.startsWith("at cv(")) return true;
35
+ if (line.startsWith("cv@")) return true;
36
+ return false;
37
+ }
38
+ function formatVariantValue(value) {
39
+ if (typeof value === "string") return JSON.stringify(value);
40
+ if (typeof value === "number") {
41
+ if (Number.isNaN(value)) return "NaN";
42
+ return String(value);
43
+ }
44
+ if (typeof value === "bigint") return `${value}n`;
45
+ if (value === void 0) return "undefined";
46
+ if (value === null) return "null";
47
+ if (typeof value === "boolean") return String(value);
48
+ if (typeof value === "symbol") return String(value);
49
+ if (typeof value === "function") return "[function]";
50
+ return "[object]";
51
+ }
52
+ function setVariantChange(into, key, from, to) {
53
+ into.set(key, {
54
+ from,
55
+ to
56
+ });
57
+ }
58
+ function accumulateUnstableVariantChanges(into, prev, next) {
59
+ for (const key in next) {
60
+ if (!Object.hasOwn(next, key)) continue;
61
+ if (!Object.is(prev[key], next[key])) setVariantChange(into, key, prev[key], next[key]);
62
+ }
63
+ for (const key in prev) {
64
+ if (!Object.hasOwn(prev, key)) continue;
65
+ if (Object.hasOwn(next, key)) continue;
66
+ setVariantChange(into, key, prev[key], void 0);
67
+ }
68
+ }
69
+ function formatVariantChanges(changes) {
70
+ return Array.from(changes).map(([key, { from, to }]) => {
71
+ return `${key}: ${formatVariantValue(from)} -> ${formatVariantValue(to)}`;
72
+ }).join(", ");
73
+ }
74
+ function warnRefineLimit({ runState, creationFrame, unstableChanges }) {
75
+ if (process.env.NODE_ENV === "production") return;
76
+ if (runState.warned) return;
77
+ runState.warned = true;
78
+ let message = "Clava: Maximum refine iterations exceeded. This can happen when a computed default variant or refine callback changes one of the variants on every run.";
79
+ if (unstableChanges && unstableChanges.size > 0) {
80
+ message += `\nVariant(s) that did not stabilize: ${Array.from(unstableChanges.keys()).join(", ")}.`;
81
+ message += `\nLatest variant changes before warning: ${formatVariantChanges(unstableChanges)}.`;
82
+ }
83
+ if (creationFrame) {
84
+ const creationStack = formatCreationStack(creationFrame);
85
+ if (creationStack) message += `\nComponent created at:\n${creationStack}`;
86
+ }
87
+ console.warn(message);
88
+ }
89
+ //#endregion
2
90
  //#region src/utils.ts
3
91
  const hasOwn = Object.prototype.hasOwnProperty;
4
92
  function isAsciiLetter(code) {
@@ -224,7 +312,6 @@ function isHTMLObjStyle(style) {
224
312
  const META_KEY = "__meta";
225
313
  const EMPTY_DEFAULTS = Object.freeze({});
226
314
  const MAX_REFINE_RUNS = 50;
227
- const REFINE_UNSTABLE_TRACKING_WINDOW = 10;
228
315
  function areVariantsEqual(a, b) {
229
316
  for (const key in a) {
230
317
  if (!Object.hasOwn(a, key)) continue;
@@ -236,48 +323,6 @@ function areVariantsEqual(a, b) {
236
323
  }
237
324
  return true;
238
325
  }
239
- function captureCreationFrame(skipFn) {
240
- if (process.env.NODE_ENV === "production") return void 0;
241
- if (typeof Error.captureStackTrace === "function") {
242
- const holder = {};
243
- Error.captureStackTrace(holder, skipFn);
244
- return holder;
245
- }
246
- return /* @__PURE__ */ new Error();
247
- }
248
- function formatCreationStack(frame) {
249
- let stack = frame.stack;
250
- if (!stack) return void 0;
251
- const newlineIdx = stack.indexOf("\n");
252
- if (newlineIdx > 0) {
253
- const firstLine = stack.slice(0, newlineIdx);
254
- if (firstLine === "Error" || firstLine.startsWith("Error:")) stack = stack.slice(newlineIdx + 1);
255
- }
256
- return stack;
257
- }
258
- function accumulateUnstableVariantKeys(into, prev, next) {
259
- for (const key in next) {
260
- if (!Object.hasOwn(next, key)) continue;
261
- if (!Object.is(prev[key], next[key])) into.add(key);
262
- }
263
- for (const key in prev) {
264
- if (!Object.hasOwn(prev, key)) continue;
265
- if (Object.hasOwn(next, key)) continue;
266
- into.add(key);
267
- }
268
- }
269
- function warnRefineLimit(runState, creationFrame, unstableKeys) {
270
- if (process.env.NODE_ENV === "production") return;
271
- if (runState.warned) return;
272
- runState.warned = true;
273
- let message = "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.";
274
- if (unstableKeys && unstableKeys.size > 0) message += `\nVariant(s) that did not stabilize: ${Array.from(unstableKeys).join(", ")}.`;
275
- if (creationFrame) {
276
- const creationStack = formatCreationStack(creationFrame);
277
- if (creationStack) message += `\nComponent created at:\n${creationStack}`;
278
- }
279
- console.warn(message);
280
- }
281
326
  function getExtUserVariantProps(userVariantProps, protectedVariants, changedVariants) {
282
327
  const extUserVariantProps = {};
283
328
  Object.assign(extUserVariantProps, userVariantProps);
@@ -305,6 +350,23 @@ function mergeVariants(target, source, skipKeys) {
305
350
  }
306
351
  return changed;
307
352
  }
353
+ function mergeProtectedIntoBase(baseResolved, protectedVariants) {
354
+ if (!protectedVariants) return baseResolved;
355
+ let hasProtected = false;
356
+ for (const key in protectedVariants) {
357
+ if (!Object.hasOwn(protectedVariants, key)) continue;
358
+ hasProtected = true;
359
+ break;
360
+ }
361
+ if (!hasProtected) return baseResolved;
362
+ const resolved = {};
363
+ Object.assign(resolved, baseResolved);
364
+ for (const key in protectedVariants) {
365
+ if (!Object.hasOwn(protectedVariants, key)) continue;
366
+ resolved[key] = protectedVariants[key];
367
+ }
368
+ return resolved;
369
+ }
308
370
  function getComponentMeta(component) {
309
371
  return component[META_KEY];
310
372
  }
@@ -374,21 +436,11 @@ function collectVariantKeys(config) {
374
436
  }
375
437
  return Array.from(keys);
376
438
  }
377
- function isVariantDisabled(config, key) {
378
- return config.variants?.[key] === null;
379
- }
380
439
  function getVariantValueKey(value) {
381
440
  if (typeof value === "string") return value;
382
441
  if (typeof value === "number") return String(value);
383
442
  if (typeof value === "boolean") return String(value);
384
443
  }
385
- function isVariantValueDisabled(config, key, value) {
386
- const valueKey = getVariantValueKey(value);
387
- if (valueKey == null) return false;
388
- const variant = config.variants?.[key];
389
- if (!isRecordObject(variant)) return false;
390
- return variant[valueKey] === null;
391
- }
392
444
  function collectDisabledVariantKeys(config) {
393
445
  const keys = /* @__PURE__ */ new Set();
394
446
  if (!config.variants) return keys;
@@ -569,6 +621,9 @@ function create({ transformClass = (className) => className } = {}) {
569
621
  }
570
622
  const variantEntryCount = variantEntryNames.length;
571
623
  const functionVariantCount = functionVariantNames.length;
624
+ const computedDefaultNames = [];
625
+ const computedDefaultFns = [];
626
+ const defaultVariants = config.defaultVariants;
572
627
  const staticDefaults = {};
573
628
  if (extend) for (const ext of extend) {
574
629
  const meta = getComponentMeta(ext);
@@ -580,7 +635,21 @@ function create({ transformClass = (className) => className } = {}) {
580
635
  if (!isRecordObject(variantDef)) continue;
581
636
  if (Object.hasOwn(variantDef, "false") && staticDefaults[name] === void 0) staticDefaults[name] = false;
582
637
  }
583
- if (config.defaultVariants) Object.assign(staticDefaults, config.defaultVariants);
638
+ if (defaultVariants) for (const name in defaultVariants) {
639
+ if (!Object.hasOwn(defaultVariants, name)) continue;
640
+ const value = defaultVariants[name];
641
+ if (typeof value === "function") {
642
+ computedDefaultNames.push(name);
643
+ computedDefaultFns.push(value);
644
+ continue;
645
+ }
646
+ if (value === void 0) {
647
+ Reflect.deleteProperty(staticDefaults, name);
648
+ continue;
649
+ }
650
+ staticDefaults[name] = value;
651
+ }
652
+ const computedDefaultCount = computedDefaultNames.length;
584
653
  if (hasAnyDisabled) for (const key in staticDefaults) {
585
654
  if (!Object.hasOwn(staticDefaults, key)) continue;
586
655
  if (disabledVariantKeys.has(key)) {
@@ -609,14 +678,19 @@ function create({ transformClass = (className) => className } = {}) {
609
678
  } else extBaseClassesArr.push(meta.baseClass);
610
679
  }
611
680
  const extCount = extMetas.length;
681
+ const inheritedComputedDefaultKeys = /* @__PURE__ */ new Set();
682
+ for (let i = 0; i < extCount; i++) {
683
+ const keys = extMetas[i].computedDefaultKeys;
684
+ for (const key of keys) inheritedComputedDefaultKeys.add(key);
685
+ }
612
686
  const extMetasWithRefine = [];
613
687
  for (let i = 0; i < extCount; i++) {
614
688
  const meta = extMetas[i];
615
- if (meta.resolveDefaults) extMetasWithRefine.push(meta);
689
+ if (meta.resolveRefine) extMetasWithRefine.push(meta);
616
690
  }
617
691
  const extMetasWithRefineCount = extMetasWithRefine.length;
618
692
  const shouldCollectChangedVariants = extMetasWithRefineCount > 0;
619
- const creationFrame = !!refine || extMetasWithRefineCount > 0 ? captureCreationFrame(cv) : void 0;
693
+ const creationFrame = !!refine || computedDefaultCount > 0 || extMetasWithRefineCount > 0 ? captureCreationFrame(cv) : void 0;
620
694
  const functionVariantKeys = /* @__PURE__ */ new Set();
621
695
  for (let i = 0; i < extCount; i++) {
622
696
  const fnKeys = extMetas[i].functionVariantKeys;
@@ -627,6 +701,8 @@ function create({ transformClass = (className) => className } = {}) {
627
701
  }
628
702
  for (let i = 0; i < functionVariantCount; i++) functionVariantKeys.add(functionVariantNames[i]);
629
703
  for (let i = 0; i < variantEntryCount; i++) functionVariantKeys.delete(variantEntryNames[i]);
704
+ const computedDefaultKeys = new Set(inheritedComputedDefaultKeys);
705
+ for (let i = 0; i < computedDefaultCount; i++) computedDefaultKeys.add(computedDefaultNames[i]);
630
706
  let staticVariantsOverridingExtFn = null;
631
707
  if (variantEntryCount > 0 && extCount > 0) for (let i = 0; i < variantEntryCount; i++) {
632
708
  const name = variantEntryNames[i];
@@ -660,64 +736,42 @@ function create({ transformClass = (className) => className } = {}) {
660
736
  out[key] = value;
661
737
  }
662
738
  }
663
- const resolveDefaultsFn = refine || extMetasWithRefineCount > 0 ? (childDefaults, userProps = EMPTY_DEFAULTS) => {
664
- const resolvedVariants = {};
665
- Object.assign(resolvedVariants, staticDefaults);
666
- for (const key in childDefaults) {
667
- if (!Object.hasOwn(childDefaults, key)) continue;
668
- const v = childDefaults[key];
669
- if (v === void 0) continue;
670
- resolvedVariants[key] = v;
671
- }
672
- for (const key in userProps) {
673
- if (!Object.hasOwn(userProps, key)) continue;
674
- const v = userProps[key];
675
- if (v === void 0) continue;
676
- resolvedVariants[key] = v;
739
+ const isOwnDisabledValue = (key, value) => {
740
+ if (disabledVariantKeys.has(key)) return true;
741
+ if (hasDisabledVariantValues) {
742
+ const valueKey = getVariantValueKey(value);
743
+ if (valueKey != null && disabledVariantValues[key]?.has(valueKey)) return true;
677
744
  }
678
- const refineDefaults = {};
679
- for (let i = 0; i < extMetasWithRefineCount; i++) {
680
- const extDefaults = extMetasWithRefine[i].resolveDefaults(childDefaults, userProps);
681
- for (const k in extDefaults) {
682
- if (!Object.hasOwn(extDefaults, k)) continue;
683
- refineDefaults[k] = extDefaults[k];
745
+ return false;
746
+ };
747
+ const filterOwnDisabledVariants = (input, fallback) => {
748
+ if (!hasAnyDisabled) return input;
749
+ let hasOwnDisabledValue = false;
750
+ for (const key in input) {
751
+ if (!Object.hasOwn(input, key)) continue;
752
+ const value = input[key];
753
+ if (isOwnDisabledValue(key, value)) {
754
+ hasOwnDisabledValue = true;
755
+ break;
684
756
  }
685
757
  }
686
- if (refine) {
687
- const ownVariants = {};
688
- for (let i = 0; i < variantKeysLength; i++) {
689
- const k = variantKeys[i];
690
- if (Object.hasOwn(resolvedVariants, k)) ownVariants[k] = resolvedVariants[k];
758
+ if (!hasOwnDisabledValue) return input;
759
+ const filtered = {};
760
+ for (const key in input) {
761
+ if (!Object.hasOwn(input, key)) continue;
762
+ const value = input[key];
763
+ if (!isOwnDisabledValue(key, value)) {
764
+ filtered[key] = value;
765
+ continue;
691
766
  }
692
- refine({
693
- variants: ownVariants,
694
- setVariants: noop,
695
- setDefaultVariants: (newDefaults) => {
696
- for (const key in newDefaults) {
697
- if (!Object.hasOwn(newDefaults, key)) continue;
698
- const value = newDefaults[key];
699
- if (userProps[key] !== void 0) continue;
700
- if (isVariantDisabled(config, key)) continue;
701
- if (isVariantValueDisabled(config, key, value)) continue;
702
- refineDefaults[key] = value;
703
- }
704
- },
705
- addClass: noop,
706
- addStyle: noop
707
- });
767
+ const fallbackValue = fallback[key];
768
+ if (fallbackValue !== void 0 && !isOwnDisabledValue(key, fallbackValue)) filtered[key] = fallbackValue;
708
769
  }
709
- return refineDefaults;
710
- } : null;
770
+ return filtered;
771
+ };
711
772
  function resolveVariantsHot(propsVariants) {
712
773
  const defaults = {};
713
774
  Object.assign(defaults, staticDefaults);
714
- for (let i = 0; i < extMetasWithRefineCount; i++) {
715
- const extDefaults = extMetasWithRefine[i].resolveDefaults(defaults, propsVariants);
716
- for (const k in extDefaults) {
717
- if (!Object.hasOwn(extDefaults, k)) continue;
718
- defaults[k] = extDefaults[k];
719
- }
720
- }
721
775
  for (const k in propsVariants) {
722
776
  if (!Object.hasOwn(propsVariants, k)) continue;
723
777
  const v = propsVariants[k];
@@ -729,7 +783,70 @@ function create({ transformClass = (className) => className } = {}) {
729
783
  filterDisabledInto(defaults, result);
730
784
  return result;
731
785
  }
732
- const runRefineContext = (resolved, userVariantProps, filterOwnVariants, collectOutput, protectedVariants, pendingProtectedVariants, protectedVariantKeys) => {
786
+ const runComputedDefaults = (resolved, defaultResolved, userVariantProps, filterOwnVariants, protectedVariantKeys) => {
787
+ if (computedDefaultCount === 0) return {
788
+ workingResolved: resolved,
789
+ changedVariants: null
790
+ };
791
+ let ownVariants = filterOwnVariants ? null : resolved;
792
+ const getOwnVariants = () => {
793
+ if (ownVariants) return ownVariants;
794
+ const filteredVariants = {};
795
+ for (let i = 0; i < variantKeysLength; i++) {
796
+ const key = variantKeys[i];
797
+ if (Object.hasOwn(resolved, key)) filteredVariants[key] = resolved[key];
798
+ }
799
+ ownVariants = filteredVariants;
800
+ return filteredVariants;
801
+ };
802
+ let updatedVariants = null;
803
+ let changedVariants = null;
804
+ const ensureUpdated = () => {
805
+ if (updatedVariants) return updatedVariants;
806
+ const updated = {};
807
+ Object.assign(updated, resolved);
808
+ updatedVariants = updated;
809
+ return updated;
810
+ };
811
+ for (let i = 0; i < computedDefaultCount; i++) {
812
+ const key = computedDefaultNames[i];
813
+ if (Object.hasOwn(userVariantProps, key)) {
814
+ if (userVariantProps[key] !== void 0) continue;
815
+ }
816
+ if (protectedVariantKeys?.has(key)) continue;
817
+ const variantSnapshot = getOwnVariants();
818
+ const defaultValue = inheritedComputedDefaultKeys.has(key) ? variantSnapshot[key] : defaultResolved[key];
819
+ const value = computedDefaultFns[i]({
820
+ defaultValue,
821
+ variants: variantSnapshot
822
+ });
823
+ if (hasAnyDisabled) {
824
+ if (disabledVariantKeys.has(key)) continue;
825
+ const valueKey = getVariantValueKey(value);
826
+ if (valueKey != null && disabledVariantValues[key]?.has(valueKey)) continue;
827
+ }
828
+ if (value === void 0) {
829
+ if (!Object.hasOwn(variantSnapshot, key)) continue;
830
+ if (shouldCollectChangedVariants) {
831
+ changedVariants ??= {};
832
+ changedVariants[key] = value;
833
+ }
834
+ Reflect.deleteProperty(ensureUpdated(), key);
835
+ continue;
836
+ }
837
+ if (Object.is(variantSnapshot[key], value)) continue;
838
+ if (shouldCollectChangedVariants) {
839
+ changedVariants ??= {};
840
+ changedVariants[key] = value;
841
+ }
842
+ ensureUpdated()[key] = value;
843
+ }
844
+ return {
845
+ workingResolved: updatedVariants ?? resolved,
846
+ changedVariants
847
+ };
848
+ };
849
+ const runRefineContext = (resolved, userVariantProps, filterOwnVariants, collectOutput, applyVariantUpdates, protectedVariants, pendingProtectedVariants, protectedVariantKeys) => {
733
850
  let workingResolved = resolved;
734
851
  let cClasses = null;
735
852
  let cStyle = null;
@@ -770,12 +887,13 @@ function create({ transformClass = (className) => className } = {}) {
770
887
  const result = refine({
771
888
  variants: ownVariants,
772
889
  setVariants: (newVariants) => {
890
+ if (!applyVariantUpdates) return;
773
891
  if (!hasAnyDisabled) {
774
892
  for (const key in newVariants) {
775
893
  if (!Object.hasOwn(newVariants, key)) continue;
776
894
  const value = newVariants[key];
777
895
  setChangedVariant(key, value, true);
778
- if (getCurrentVariantValue(key) === value) continue;
896
+ if (Object.is(getCurrentVariantValue(key), value)) continue;
779
897
  ensureUpdated()[key] = value;
780
898
  }
781
899
  return;
@@ -789,24 +907,7 @@ function create({ transformClass = (className) => className } = {}) {
789
907
  if (valueKey != null && disabledVariantValues[key]?.has(valueKey)) continue;
790
908
  }
791
909
  setChangedVariant(key, value, true);
792
- if (getCurrentVariantValue(key) === value) continue;
793
- ensureUpdated()[key] = value;
794
- }
795
- },
796
- setDefaultVariants: (newDefaults) => {
797
- for (const key in newDefaults) {
798
- if (!Object.hasOwn(newDefaults, key)) continue;
799
- if (userVariantProps[key] !== void 0) continue;
800
- if (protectedVariantKeys?.has(key)) continue;
801
- const value = newDefaults[key];
802
- if (hasAnyDisabled) {
803
- if (disabledVariantKeys.has(key)) continue;
804
- const valueKey = getVariantValueKey(value);
805
- if (valueKey != null && disabledVariantValues[key]?.has(valueKey)) continue;
806
- }
807
- setChangedVariant(key, value);
808
- if (pendingProtectedVariants) pendingProtectedVariants[key] = value;
809
- if (getCurrentVariantValue(key) === value) continue;
910
+ if (Object.is(getCurrentVariantValue(key), value)) continue;
810
911
  ensureUpdated()[key] = value;
811
912
  }
812
913
  },
@@ -847,18 +948,11 @@ function create({ transformClass = (className) => className } = {}) {
847
948
  style: cStyle
848
949
  };
849
950
  };
850
- const computeOnce = (resolved, userVariantProps, skipKeys, skipValues, classesOut, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys) => {
951
+ const computeOnce = (resolved, userVariantProps, skipKeys, skipValues, classesOut, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys, defaultResolved = resolved, renderOnly = false) => {
851
952
  let workingResolved = resolved;
852
953
  let cClasses = null;
853
954
  let cStyle = null;
854
955
  let changedVariants = null;
855
- if (refine) {
856
- const refineResult = runRefineContext(resolved, userVariantProps, true, true, protectedVariants, pendingProtectedVariants, protectedVariantKeys);
857
- workingResolved = refineResult.workingResolved;
858
- cClasses = refineResult.classes;
859
- cStyle = refineResult.style;
860
- changedVariants = refineResult.changedVariants;
861
- }
862
956
  if (hasExtend) {
863
957
  let extSkipKeys;
864
958
  if (skipKeys === null) extSkipKeys = staticExtSkipKeys;
@@ -886,15 +980,31 @@ function create({ transformClass = (className) => className } = {}) {
886
980
  for (let i = 0; i < extCount; i++) {
887
981
  if (hasIsolatedExt && extIsolated[i]) {
888
982
  const extClasses = [];
889
- workingResolved = extMetas[i].compute(workingResolved, extUserVariantProps, extSkipKeys, extSkipVals, extClasses, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys);
983
+ workingResolved = extMetas[i].compute(workingResolved, extUserVariantProps, extSkipKeys, extSkipVals, extClasses, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys, defaultResolved, renderOnly);
890
984
  if (extClasses.length > 0) {
891
985
  const joined = clsx(extClasses);
892
986
  if (joined.length > 0) classesOut.push(extMetas[i].transformClass(joined));
893
987
  }
894
- } else workingResolved = extMetas[i].compute(workingResolved, extUserVariantProps, extSkipKeys, extSkipVals, classesOut, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys);
988
+ } else workingResolved = extMetas[i].compute(workingResolved, extUserVariantProps, extSkipKeys, extSkipVals, classesOut, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys, defaultResolved, renderOnly);
989
+ workingResolved = filterOwnDisabledVariants(workingResolved, defaultResolved);
895
990
  if (protectedVariants && extMetasWithRefineCount > 0) Object.assign(extUserVariantProps, protectedVariants);
896
991
  }
897
992
  }
993
+ if (!renderOnly && computedDefaultCount > 0) {
994
+ const computedResult = runComputedDefaults(workingResolved, defaultResolved, userVariantProps, true, protectedVariantKeys);
995
+ workingResolved = computedResult.workingResolved;
996
+ changedVariants = computedResult.changedVariants;
997
+ }
998
+ if (refine) {
999
+ const refineResult = runRefineContext(workingResolved, userVariantProps, true, true, !renderOnly, protectedVariants, pendingProtectedVariants, protectedVariantKeys);
1000
+ workingResolved = refineResult.workingResolved;
1001
+ cClasses = refineResult.classes;
1002
+ cStyle = refineResult.style;
1003
+ if (refineResult.changedVariants) {
1004
+ changedVariants ??= {};
1005
+ Object.assign(changedVariants, refineResult.changedVariants);
1006
+ }
1007
+ }
898
1008
  if (hasBaseStyle) Object.assign(styleOut, baseStyle);
899
1009
  const ownSkipKeys = skipKeys;
900
1010
  const ownSkipValues = skipValues;
@@ -937,12 +1047,13 @@ function create({ transformClass = (className) => className } = {}) {
937
1047
  if (cStyle) Object.assign(styleOut, cStyle);
938
1048
  return workingResolved;
939
1049
  };
940
- const compute = !refine && extMetasWithRefineCount === 0 ? computeOnce : (resolved, userVariantProps, skipKeys, skipValues, classesOut, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys) => {
1050
+ const compute = !refine && computedDefaultCount === 0 && extMetasWithRefineCount === 0 ? computeOnce : (resolved, userVariantProps, skipKeys, skipValues, classesOut, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys, incomingDefaultResolved = resolved, renderOnly = false) => {
1051
+ if (renderOnly) return computeOnce(resolved, userVariantProps, skipKeys, skipValues, classesOut, styleOut, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys, incomingDefaultResolved, true);
941
1052
  runState ??= { remaining: MAX_REFINE_RUNS };
942
1053
  protectedVariants ??= {};
943
1054
  protectedVariantKeys ??= /* @__PURE__ */ new Set();
944
1055
  let workingResolved = resolved;
945
- let unstableKeys = null;
1056
+ let unstableChanges = null;
946
1057
  let lastClasses = [];
947
1058
  let lastStyle = {};
948
1059
  let isFirstRun = true;
@@ -959,23 +1070,34 @@ function create({ transformClass = (className) => className } = {}) {
959
1070
  const nextPendingProtectedVariants = {};
960
1071
  const nextClasses = useDirectOutput ? classesOut : [];
961
1072
  const nextStyle = useDirectOutput ? styleOut : {};
962
- const nextResolved = computeOnce(workingResolved, userVariantProps, skipKeys, skipValues, nextClasses, nextStyle, runState, protectedVariants, nextPendingProtectedVariants, protectedVariantKeys);
1073
+ const defaultResolved = mergeProtectedIntoBase(incomingDefaultResolved, protectedVariants);
1074
+ const nextResolved = computeOnce(workingResolved, userVariantProps, skipKeys, skipValues, nextClasses, nextStyle, runState, protectedVariants, nextPendingProtectedVariants, protectedVariantKeys, defaultResolved);
963
1075
  let protectedChanged;
964
1076
  if (pendingProtectedVariants) protectedChanged = mergeVariants(pendingProtectedVariants, nextPendingProtectedVariants, protectedVariantKeys);
965
1077
  else protectedChanged = mergeVariants(protectedVariants, nextPendingProtectedVariants, protectedVariantKeys);
966
1078
  if (!protectedChanged && (nextResolved === workingResolved || areVariantsEqual(workingResolved, nextResolved))) {
967
- if (!useDirectOutput) {
1079
+ if (nextResolved !== workingResolved) {
1080
+ if (useDirectOutput) {
1081
+ classesOut.length = classCount;
1082
+ for (const key in styleOut) if (Object.hasOwn(styleOut, key)) Reflect.deleteProperty(styleOut, key);
1083
+ }
1084
+ computeOnce(nextResolved, userVariantProps, skipKeys, skipValues, classesOut, styleOut, runState, protectedVariants, null, protectedVariantKeys, defaultResolved, true);
1085
+ } else if (!useDirectOutput) {
968
1086
  for (let i = 0; i < nextClasses.length; i++) classesOut.push(nextClasses[i]);
969
1087
  Object.assign(styleOut, nextStyle);
970
1088
  }
971
1089
  return nextResolved;
972
1090
  }
973
- if (process.env.NODE_ENV !== "production" && runState.remaining < REFINE_UNSTABLE_TRACKING_WINDOW) {
974
- if (!unstableKeys) unstableKeys = /* @__PURE__ */ new Set();
975
- accumulateUnstableVariantKeys(unstableKeys, workingResolved, nextResolved);
1091
+ if (process.env.NODE_ENV !== "production" && runState.remaining < 10) {
1092
+ if (!unstableChanges) unstableChanges = /* @__PURE__ */ new Map();
1093
+ accumulateUnstableVariantChanges(unstableChanges, workingResolved, nextResolved);
976
1094
  }
977
1095
  if (useDirectOutput && runState.remaining === 0) {
978
- warnRefineLimit(runState, creationFrame, unstableKeys);
1096
+ warnRefineLimit({
1097
+ runState,
1098
+ creationFrame,
1099
+ unstableChanges
1100
+ });
979
1101
  return nextResolved;
980
1102
  }
981
1103
  if (useDirectOutput) {
@@ -988,41 +1110,55 @@ function create({ transformClass = (className) => className } = {}) {
988
1110
  workingResolved = nextResolved;
989
1111
  isFirstRun = false;
990
1112
  }
991
- warnRefineLimit(runState, creationFrame, unstableKeys);
1113
+ warnRefineLimit({
1114
+ runState,
1115
+ creationFrame,
1116
+ unstableChanges
1117
+ });
992
1118
  for (let i = 0; i < lastClasses.length; i++) classesOut.push(lastClasses[i]);
993
1119
  Object.assign(styleOut, lastStyle);
994
1120
  return workingResolved;
995
1121
  };
996
- const resolveRefineOnce = (resolved, userVariantProps, filterOwnVariants = true, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys) => {
1122
+ const resolveRefineOnce = (resolved, userVariantProps, filterOwnVariants = true, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys, defaultResolved = resolved) => {
997
1123
  let workingResolved = resolved;
998
1124
  let changedVariants = null;
999
- if (refine) {
1000
- const refineResult = runRefineContext(resolved, userVariantProps, filterOwnVariants, false, protectedVariants, pendingProtectedVariants, protectedVariantKeys);
1001
- workingResolved = refineResult.workingResolved;
1002
- changedVariants = refineResult.changedVariants;
1003
- }
1004
1125
  if (extMetasWithRefineCount > 0) {
1005
1126
  const extUserVariantProps = getExtUserVariantProps(userVariantProps, protectedVariants ?? null, changedVariants);
1006
1127
  for (let i = 0; i < extMetasWithRefineCount; i++) {
1007
1128
  const resolveRefine = extMetasWithRefine[i].resolveRefine;
1008
1129
  if (!resolveRefine) continue;
1009
- workingResolved = resolveRefine(workingResolved, extUserVariantProps, true, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys);
1130
+ workingResolved = resolveRefine(workingResolved, extUserVariantProps, true, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys, defaultResolved);
1131
+ workingResolved = filterOwnDisabledVariants(workingResolved, defaultResolved);
1010
1132
  if (protectedVariants) Object.assign(extUserVariantProps, protectedVariants);
1011
1133
  }
1012
1134
  }
1135
+ if (computedDefaultCount > 0) {
1136
+ const computedResult = runComputedDefaults(workingResolved, defaultResolved, userVariantProps, filterOwnVariants, protectedVariantKeys);
1137
+ workingResolved = computedResult.workingResolved;
1138
+ changedVariants = computedResult.changedVariants;
1139
+ }
1140
+ if (refine) {
1141
+ const refineResult = runRefineContext(workingResolved, userVariantProps, filterOwnVariants, false, true, protectedVariants, pendingProtectedVariants, protectedVariantKeys);
1142
+ workingResolved = refineResult.workingResolved;
1143
+ if (refineResult.changedVariants) {
1144
+ changedVariants ??= {};
1145
+ Object.assign(changedVariants, refineResult.changedVariants);
1146
+ }
1147
+ }
1013
1148
  return workingResolved;
1014
1149
  };
1015
- const resolveRefine = refine || extMetasWithRefineCount > 0 ? (resolved, userVariantProps, filterOwnVariants = true, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys) => {
1150
+ const resolveRefine = refine || computedDefaultCount > 0 || extMetasWithRefineCount > 0 ? (resolved, userVariantProps, filterOwnVariants = true, runState, protectedVariants, pendingProtectedVariants, protectedVariantKeys, incomingDefaultResolved = resolved) => {
1016
1151
  runState ??= { remaining: MAX_REFINE_RUNS };
1017
1152
  protectedVariants ??= {};
1018
1153
  protectedVariantKeys ??= /* @__PURE__ */ new Set();
1019
1154
  let workingResolved = resolved;
1020
- let unstableKeys = null;
1155
+ let unstableChanges = null;
1021
1156
  let reachedLimit = true;
1022
1157
  while (runState.remaining > 0) {
1023
1158
  runState.remaining -= 1;
1024
1159
  const nextPendingProtectedVariants = {};
1025
- const nextResolved = resolveRefineOnce(workingResolved, userVariantProps, filterOwnVariants, runState, protectedVariants, nextPendingProtectedVariants, protectedVariantKeys);
1160
+ const defaultResolved = mergeProtectedIntoBase(incomingDefaultResolved, protectedVariants);
1161
+ const nextResolved = resolveRefineOnce(workingResolved, userVariantProps, filterOwnVariants, runState, protectedVariants, nextPendingProtectedVariants, protectedVariantKeys, defaultResolved);
1026
1162
  let protectedChanged;
1027
1163
  if (pendingProtectedVariants) protectedChanged = mergeVariants(pendingProtectedVariants, nextPendingProtectedVariants, protectedVariantKeys);
1028
1164
  else protectedChanged = mergeVariants(protectedVariants, nextPendingProtectedVariants, protectedVariantKeys);
@@ -1031,13 +1167,17 @@ function create({ transformClass = (className) => className } = {}) {
1031
1167
  reachedLimit = false;
1032
1168
  break;
1033
1169
  }
1034
- if (process.env.NODE_ENV !== "production" && runState.remaining < REFINE_UNSTABLE_TRACKING_WINDOW) {
1035
- if (!unstableKeys) unstableKeys = /* @__PURE__ */ new Set();
1036
- accumulateUnstableVariantKeys(unstableKeys, workingResolved, nextResolved);
1170
+ if (process.env.NODE_ENV !== "production" && runState.remaining < 10) {
1171
+ if (!unstableChanges) unstableChanges = /* @__PURE__ */ new Map();
1172
+ accumulateUnstableVariantChanges(unstableChanges, workingResolved, nextResolved);
1037
1173
  }
1038
1174
  workingResolved = nextResolved;
1039
1175
  }
1040
- if (reachedLimit) warnRefineLimit(runState, creationFrame, unstableKeys);
1176
+ if (reachedLimit) warnRefineLimit({
1177
+ runState,
1178
+ creationFrame,
1179
+ unstableChanges
1180
+ });
1041
1181
  return workingResolved;
1042
1182
  } : null;
1043
1183
  const computeResult = (props = EMPTY_DEFAULTS) => {
@@ -1045,19 +1185,12 @@ function create({ transformClass = (className) => className } = {}) {
1045
1185
  let resolved = {};
1046
1186
  Object.assign(resolved, staticDefaults);
1047
1187
  let userVariantProps;
1048
- if (extMetasWithRefineCount > 0) {
1188
+ if (refine || computedDefaultCount > 0 || extMetasWithRefineCount > 0) {
1049
1189
  const variantProps = {};
1050
1190
  for (let i = 0; i < variantKeysLength; i++) {
1051
1191
  const key = variantKeys[i];
1052
1192
  if (Object.hasOwn(propsRecord, key)) variantProps[key] = propsRecord[key];
1053
1193
  }
1054
- for (let i = 0; i < extMetasWithRefineCount; i++) {
1055
- const extDefaults = extMetasWithRefine[i].resolveDefaults(resolved, variantProps);
1056
- for (const k in extDefaults) {
1057
- if (!Object.hasOwn(extDefaults, k)) continue;
1058
- resolved[k] = extDefaults[k];
1059
- }
1060
- }
1061
1194
  for (const k in variantProps) {
1062
1195
  if (!Object.hasOwn(variantProps, k)) continue;
1063
1196
  const v = variantProps[k];
@@ -1116,11 +1249,11 @@ function create({ transformClass = (className) => className } = {}) {
1116
1249
  const meta = {
1117
1250
  baseClass: computedBaseClass,
1118
1251
  staticDefaults,
1119
- resolveDefaults: resolveDefaultsFn,
1120
1252
  compute,
1121
1253
  resolveRefine,
1122
1254
  transformClass,
1123
- functionVariantKeys
1255
+ functionVariantKeys,
1256
+ computedDefaultKeys
1124
1257
  };
1125
1258
  const initComponent = (c, propKeys, style) => {
1126
1259
  c.class = classFn;
@@ -1187,7 +1320,6 @@ function create({ transformClass = (className) => className } = {}) {
1187
1320
  cx
1188
1321
  };
1189
1322
  }
1190
- function noop() {}
1191
1323
  const { cv, cx } = create();
1192
1324
  //#endregion
1193
1325
  export { create, cv, cx, splitProps };