praxis-kit 2.0.1 → 3.0.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.
@@ -332,11 +332,13 @@ function processVariableStatement(node, calleeNames, out) {
332
332
  }
333
333
  }
334
334
  if (rules.length === 0 && !hasAriaRules && !defaultTag) continue;
335
- const totalMin = rules.reduce((s, r) => s + cardinalityMin(r.cardinality), 0);
336
- const totalMax = rules.reduce(
337
- (s, r) => s === Infinity ? Infinity : s + cardinalityMax(r.cardinality),
338
- 0
339
- );
335
+ let totalMin = 0;
336
+ let totalMax = 0;
337
+ for (const rule of rules) {
338
+ totalMin += cardinalityMin(rule.cardinality);
339
+ const max = cardinalityMax(rule.cardinality);
340
+ totalMax = totalMax === Infinity || max === Infinity ? Infinity : totalMax + max;
341
+ }
340
342
  const componentName = ts3.isIdentifier(decl.name) ? decl.name.text : void 0;
341
343
  if (!componentName) continue;
342
344
  out.push({
@@ -367,7 +369,13 @@ function collectFileDeclarations(source, calleeNames) {
367
369
  if (!ts3.isStringLiteral(spec)) return;
368
370
  const namedBindings = node.importClause?.namedBindings;
369
371
  if (!namedBindings || !ts3.isNamedImports(namedBindings)) return;
370
- for (const el of namedBindings.elements) importSpecifiers.set(el.name.text, spec.text);
372
+ const specifier = spec.text;
373
+ for (const el of namedBindings.elements) {
374
+ if (el.isTypeOnly) continue;
375
+ const localName = el.name.text;
376
+ const importedName = el.propertyName?.text ?? localName;
377
+ importSpecifiers.set(localName, { importedName, specifier });
378
+ }
371
379
  }
372
380
  });
373
381
  return { constraints, importSpecifiers };
@@ -512,23 +520,24 @@ function analyzeJsxSites(source, constraints, severity) {
512
520
  const opening = node.openingElement;
513
521
  tagName = ts5.isIdentifier(opening.tagName) ? opening.tagName.text : void 0;
514
522
  attributes = opening.attributes;
515
- count = countStaticChildren(node);
523
+ count = countJsxChildren(node.children);
516
524
  } else if (ts5.isJsxSelfClosingElement(node)) {
517
525
  tagName = ts5.isIdentifier(node.tagName) ? node.tagName.text : void 0;
518
526
  attributes = node.attributes;
519
- count = 0;
527
+ count = ZERO;
520
528
  }
521
529
  if (!tagName) return;
522
530
  let pos;
523
531
  const getPos = () => pos ??= source.getLineAndCharacterOfPosition(node.getStart(source));
524
532
  if (count !== void 0) {
525
533
  const c = byName.get(tagName);
526
- if (c && (count < c.totalMin || count > c.totalMax)) {
534
+ if (c && (count.max < c.totalMin || count.min > c.totalMax)) {
527
535
  const { line, character } = getPos();
528
536
  const { totalMin, totalMax, name } = c;
529
537
  const rangeText = totalMax === Infinity ? `at least ${totalMin}` : totalMin === totalMax ? `exactly ${totalMin}` : `${totalMin}\u2013${totalMax}`;
538
+ const receivedText = count.min === count.max ? `${count.min}` : `${count.min}\u2013${count.max}`;
530
539
  diagnostics.push({
531
- message: `<${name}> expects ${rangeText} ${totalMax === 1 && totalMin === 1 ? "child" : "children"} but received ${count}.`,
540
+ message: `<${name}> expects ${rangeText} ${totalMax === 1 && totalMin === 1 ? "child" : "children"} but received ${receivedText}.`,
532
541
  line: line + 1,
533
542
  col: character + 1,
534
543
  severity
@@ -567,17 +576,71 @@ function analyzeJsxSites(source, constraints, severity) {
567
576
  });
568
577
  return { diagnostics, usages };
569
578
  }
570
- function countStaticChildren(node) {
571
- let count = 0;
572
- for (const child of node.children) {
573
- if (ts5.isJsxExpression(child)) return void 0;
574
- if (ts5.isJsxText(child)) {
575
- if (child.text.trim().length > 0) count++;
579
+ var ZERO = { min: 0, max: 0 };
580
+ var ONE = { min: 1, max: 1 };
581
+ function countExpression(node) {
582
+ if (node.kind === ts5.SyntaxKind.NullKeyword) return ZERO;
583
+ if (node.kind === ts5.SyntaxKind.FalseKeyword) return ZERO;
584
+ if (ts5.isIdentifier(node) && node.text === "undefined") return ZERO;
585
+ if (ts5.isParenthesizedExpression(node)) return countExpression(node.expression);
586
+ if (ts5.isJsxElement(node) || ts5.isJsxSelfClosingElement(node)) return ONE;
587
+ if (ts5.isJsxFragment(node)) return countJsxChildren(node.children);
588
+ if (ts5.isArrayLiteralExpression(node)) {
589
+ let min = 0;
590
+ let max = 0;
591
+ for (const el of node.elements) {
592
+ if (ts5.isSpreadElement(el)) return void 0;
593
+ const c = countExpression(el);
594
+ if (!c) return void 0;
595
+ min += c.min;
596
+ max += c.max;
597
+ }
598
+ return { min, max };
599
+ }
600
+ if (ts5.isBinaryExpression(node)) {
601
+ const op = node.operatorToken.kind;
602
+ if (op === ts5.SyntaxKind.AmpersandAmpersandToken) {
603
+ const right = countExpression(node.right);
604
+ if (!right) return void 0;
605
+ return { min: 0, max: right.max };
606
+ }
607
+ if (op === ts5.SyntaxKind.BarBarToken || op === ts5.SyntaxKind.QuestionQuestionToken) {
608
+ const left = countExpression(node.left);
609
+ const right = countExpression(node.right);
610
+ if (!left || !right) return void 0;
611
+ return { min: Math.min(left.min, right.min), max: Math.max(left.max, right.max) };
612
+ }
613
+ }
614
+ if (ts5.isConditionalExpression(node)) {
615
+ const whenTrue = countExpression(node.whenTrue);
616
+ const whenFalse = countExpression(node.whenFalse);
617
+ if (!whenTrue || !whenFalse) return void 0;
618
+ return {
619
+ min: Math.min(whenTrue.min, whenFalse.min),
620
+ max: Math.max(whenTrue.max, whenFalse.max)
621
+ };
622
+ }
623
+ return void 0;
624
+ }
625
+ function countJsxChildren(children) {
626
+ let min = 0;
627
+ let max = 0;
628
+ for (const child of children) {
629
+ let c;
630
+ if (ts5.isJsxExpression(child)) {
631
+ c = child.expression === void 0 ? ZERO : countExpression(child.expression);
632
+ } else if (ts5.isJsxText(child)) {
633
+ c = child.text.trim().length > 0 ? ONE : ZERO;
634
+ } else if (ts5.isJsxFragment(child)) {
635
+ c = countJsxChildren(child.children);
576
636
  } else {
577
- count++;
637
+ c = ONE;
578
638
  }
639
+ if (!c) return void 0;
640
+ min += c.min;
641
+ max += c.max;
579
642
  }
580
- return count;
643
+ return { min, max };
581
644
  }
582
645
  function diagnoseUsages(source, constraints, severity) {
583
646
  if (constraints.length === 0) return [];
@@ -589,21 +652,22 @@ function diagnoseUsages(source, constraints, severity) {
589
652
  if (ts5.isJsxElement(node)) {
590
653
  const openTag = node.openingElement;
591
654
  tagName = ts5.isIdentifier(openTag.tagName) ? openTag.tagName.text : void 0;
592
- count = countStaticChildren(node);
655
+ count = countJsxChildren(node.children);
593
656
  } else if (ts5.isJsxSelfClosingElement(node)) {
594
657
  tagName = ts5.isIdentifier(node.tagName) ? node.tagName.text : void 0;
595
- count = 0;
658
+ count = ZERO;
596
659
  }
597
660
  if (!tagName) return;
598
661
  const constraint = byName.get(tagName);
599
662
  if (!constraint) return;
600
663
  if (count === void 0) return;
601
664
  const { totalMin, totalMax, name } = constraint;
602
- if (count < totalMin || count > totalMax) {
665
+ if (count.max < totalMin || count.min > totalMax) {
603
666
  const { line, character } = source.getLineAndCharacterOfPosition(node.getStart(source));
604
667
  const rangeText = totalMax === Infinity ? `at least ${totalMin}` : totalMin === totalMax ? `exactly ${totalMin}` : `${totalMin}\u2013${totalMax}`;
668
+ const receivedText = count.min === count.max ? `${count.min}` : `${count.min}\u2013${count.max}`;
605
669
  diagnostics.push({
606
- message: `<${name}> expects ${rangeText} ${totalMax === 1 && totalMin === 1 ? "child" : "children"} but received ${count}.`,
670
+ message: `<${name}> expects ${rangeText} ${totalMax === 1 && totalMin === 1 ? "child" : "children"} but received ${receivedText}.`,
607
671
  line: line + 1,
608
672
  col: character + 1,
609
673
  severity
@@ -650,12 +714,13 @@ var ConstraintRegistry = class {
650
714
  const constraint = this.resolveConstraint(fileId, usage.tagName);
651
715
  if (!constraint) continue;
652
716
  const { totalMin, totalMax, name } = constraint;
653
- if (usage.count >= totalMin && usage.count <= totalMax) continue;
717
+ if (usage.count.max >= totalMin && usage.count.min <= totalMax) continue;
654
718
  const rangeText = totalMax === Infinity ? `at least ${totalMin}` : totalMin === totalMax ? `exactly ${totalMin}` : `${totalMin}\u2013${totalMax}`;
655
719
  const childWord = totalMax === 1 && totalMin === 1 ? "child" : "children";
720
+ const receivedText = usage.count.min === usage.count.max ? `${usage.count.min}` : `${usage.count.min}\u2013${usage.count.max}`;
656
721
  result.push({
657
722
  fileId,
658
- message: `<${name}> expects ${rangeText} ${childWord} but received ${usage.count}.`,
723
+ message: `<${name}> expects ${rangeText} ${childWord} but received ${receivedText}.`,
659
724
  line: usage.line,
660
725
  col: usage.col,
661
726
  severity
@@ -1042,8 +1107,9 @@ function createStaticCompositionTransformer(factory, components, onInlined) {
1042
1107
  return (sourceFile) => ts7.visitEachChild(sourceFile, visit, context);
1043
1108
  };
1044
1109
  }
1045
- function composeStatically(source, calleeNames) {
1046
- const components = extractStaticComponents(source, calleeNames);
1110
+ function composeStatically(source, calleeNames, importedComponents = /* @__PURE__ */ new Map()) {
1111
+ const sameFile = extractStaticComponents(source, calleeNames);
1112
+ const components = importedComponents.size > 0 ? new Map([...importedComponents, ...sameFile]) : sameFile;
1047
1113
  if (components.size === 0) return null;
1048
1114
  const componentNames = new Set(components.keys());
1049
1115
  let hasEligibleTag = false;
@@ -1074,6 +1140,27 @@ function composeStatically(source, calleeNames) {
1074
1140
  return output;
1075
1141
  }
1076
1142
 
1143
+ // ../vite-plugin/src/imports.ts
1144
+ import ts8 from "typescript";
1145
+ function extractImportSpecifiers(source) {
1146
+ const result = /* @__PURE__ */ new Map();
1147
+ walk(source, (node) => {
1148
+ if (!ts8.isImportDeclaration(node)) return;
1149
+ const moduleSpecifier = node.moduleSpecifier;
1150
+ if (!ts8.isStringLiteral(moduleSpecifier)) return;
1151
+ const specifier = moduleSpecifier.text;
1152
+ const namedBindings = node.importClause?.namedBindings;
1153
+ if (!namedBindings || !ts8.isNamedImports(namedBindings)) return;
1154
+ for (const element of namedBindings.elements) {
1155
+ if (element.isTypeOnly) continue;
1156
+ const localName = element.name.text;
1157
+ const importedName = element.propertyName?.text ?? localName;
1158
+ result.set(localName, { importedName, specifier });
1159
+ }
1160
+ });
1161
+ return result;
1162
+ }
1163
+
1077
1164
  // ../vite-plugin/src/analyze.ts
1078
1165
  function analyze(code, filename, options) {
1079
1166
  const ext = filename.split(".").pop() ?? "";
@@ -1088,14 +1175,14 @@ function analyze(code, filename, options) {
1088
1175
  // ../vite-plugin/src/design-tokens.ts
1089
1176
  import { writeFileSync } from "fs";
1090
1177
  import { resolve } from "path";
1091
- import ts8 from "typescript";
1178
+ import ts9 from "typescript";
1092
1179
  function collectStringValues(node, out) {
1093
1180
  if (!node) return;
1094
- if (ts8.isStringLiteral(node)) {
1181
+ if (ts9.isStringLiteral(node)) {
1095
1182
  if (node.text.trim()) out.push(node.text);
1096
1183
  return;
1097
1184
  }
1098
- if (ts8.isArrayLiteralExpression(node)) {
1185
+ if (ts9.isArrayLiteralExpression(node)) {
1099
1186
  for (const elem of node.elements) collectStringValues(elem, out);
1100
1187
  }
1101
1188
  }
@@ -1108,11 +1195,11 @@ function extractStylingTokens(stylingObj) {
1108
1195
  const variantsObj = asObject(getProperty(stylingObj, "variants"));
1109
1196
  if (variantsObj) {
1110
1197
  for (const dimProp of variantsObj.properties) {
1111
- if (!ts8.isPropertyAssignment(dimProp)) continue;
1198
+ if (!ts9.isPropertyAssignment(dimProp)) continue;
1112
1199
  const valuesObj = asObject(dimProp.initializer);
1113
1200
  if (!valuesObj) continue;
1114
1201
  for (const vp of valuesObj.properties) {
1115
- if (!ts8.isPropertyAssignment(vp)) continue;
1202
+ if (!ts9.isPropertyAssignment(vp)) continue;
1116
1203
  collectStringValues(vp.initializer, variantClasses);
1117
1204
  }
1118
1205
  }
@@ -1128,7 +1215,7 @@ function extractStylingTokens(stylingObj) {
1128
1215
  const tagsObj = asObject(getProperty(stylingObj, "tags"));
1129
1216
  if (tagsObj) {
1130
1217
  for (const tp of tagsObj.properties) {
1131
- if (!ts8.isPropertyAssignment(tp)) continue;
1218
+ if (!ts9.isPropertyAssignment(tp)) continue;
1132
1219
  collectStringValues(tp.initializer, tagClasses);
1133
1220
  }
1134
1221
  }
@@ -1136,17 +1223,17 @@ function extractStylingTokens(stylingObj) {
1136
1223
  }
1137
1224
  function collectFileTokens(source, calleeNames) {
1138
1225
  const result = /* @__PURE__ */ new Map();
1139
- ts8.forEachChild(source, (stmt) => {
1140
- if (!ts8.isVariableStatement(stmt)) return;
1226
+ ts9.forEachChild(source, (stmt) => {
1227
+ if (!ts9.isVariableStatement(stmt)) return;
1141
1228
  for (const decl of stmt.declarationList.declarations) {
1142
- if (!decl.initializer || !ts8.isCallExpression(decl.initializer)) continue;
1229
+ if (!decl.initializer || !ts9.isCallExpression(decl.initializer)) continue;
1143
1230
  if (!isFactoryCall(decl.initializer, calleeNames)) continue;
1144
1231
  const arg = firstObjectArg(decl.initializer);
1145
1232
  if (!arg) continue;
1146
1233
  const stylingNode = getProperty(arg, "styling");
1147
1234
  const stylingObj = asObject(stylingNode);
1148
1235
  if (!stylingObj) continue;
1149
- const name = ts8.isIdentifier(decl.name) ? decl.name.text : void 0;
1236
+ const name = ts9.isIdentifier(decl.name) ? decl.name.text : void 0;
1150
1237
  if (!name) continue;
1151
1238
  result.set(name, extractStylingTokens(stylingObj));
1152
1239
  }
@@ -1235,10 +1322,10 @@ function contractPlugin(options) {
1235
1322
  );
1236
1323
  if (importedTagsInUse.size > 0) {
1237
1324
  const resolvedImports = /* @__PURE__ */ new Map();
1238
- for (const [name, specifier] of importSpecifiers) {
1239
- if (!importedTagsInUse.has(name)) continue;
1325
+ for (const [localName, { specifier }] of importSpecifiers) {
1326
+ if (!importedTagsInUse.has(localName)) continue;
1240
1327
  const resolved = await this.resolve(specifier, id);
1241
- if (resolved) resolvedImports.set(name, resolved.id);
1328
+ if (resolved) resolvedImports.set(localName, resolved.id);
1242
1329
  }
1243
1330
  registry.registerImports(id, resolvedImports);
1244
1331
  for (const usage of allUsages) {
@@ -1297,12 +1384,29 @@ function slotTransformPlugin() {
1297
1384
  }
1298
1385
  function staticCompositionPlugin(options) {
1299
1386
  const calleeNames = new Set(options?.calleeNames ?? DEFAULT_CALLEE_NAMES);
1387
+ const registry = /* @__PURE__ */ new Map();
1300
1388
  return {
1301
1389
  name: "praxis-kit:static-compose",
1302
- transform(code, id) {
1390
+ buildStart() {
1391
+ registry.clear();
1392
+ },
1393
+ async transform(code, id) {
1303
1394
  const ext = id.split(".").pop() ?? "";
1304
1395
  if (!JSX_EXTS.has(ext)) return null;
1305
- const result = composeStatically(parseSource(id, code), calleeNames);
1396
+ const source = parseSource(id, code);
1397
+ const sameFile = extractStaticComponents(source, calleeNames);
1398
+ if (sameFile.size > 0) registry.set(id, sameFile);
1399
+ const importedComponents = /* @__PURE__ */ new Map();
1400
+ const importSpecifiers = extractImportSpecifiers(source);
1401
+ for (const [localName, { importedName, specifier }] of importSpecifiers) {
1402
+ const resolved = await this.resolve(specifier, id);
1403
+ if (!resolved) continue;
1404
+ const entry = registry.get(resolved.id);
1405
+ if (!entry) continue;
1406
+ const component = entry.get(importedName);
1407
+ if (component) importedComponents.set(localName, component);
1408
+ }
1409
+ const result = composeStatically(source, calleeNames, importedComponents);
1306
1410
  return result !== null ? { code: result } : null;
1307
1411
  }
1308
1412
  };
@@ -1320,6 +1424,7 @@ export {
1320
1424
  compoundPrunePlugin,
1321
1425
  contractPlugin,
1322
1426
  designTokensPlugin,
1427
+ extractStaticComponents,
1323
1428
  injectPrecomputedClasses,
1324
1429
  pruneDeadCompounds,
1325
1430
  slotTransformPlugin,
@@ -13,6 +13,8 @@ type KnownAriaRole = (typeof KNOWN_ARIA_ROLES)[number];
13
13
 
14
14
  type AriaRole = KnownAriaRole | (string & {});
15
15
 
16
+ type Booleanish = boolean | 'true' | 'false';
17
+
16
18
  type ClassName = string | string[];
17
19
 
18
20
  type EmptyRecord = Record<never, never>;
@@ -23,6 +25,10 @@ type IntrinsicProps = AnyRecord & {
23
25
 
24
26
  type NonEmptyArray<T> = [T, ...T[]];
25
27
 
28
+ type Numberish = number | `${number}`;
29
+
30
+ type Primitive = string | number | boolean;
31
+
26
32
  type TagMap = Partial<Record<IntrinsicTag | (string & {}), ClassName>>;
27
33
 
28
34
  type StrictMode = boolean | 'warn' | 'async-warn' | 'throw';
@@ -55,9 +61,9 @@ type ValidResult = {
55
61
 
56
62
  type StringToBoolean<T> = T extends 'true' | 'false' ? boolean : T;
57
63
 
58
- type VariantValue = string | string[];
64
+ type VariantValue$1 = string | string[];
59
65
 
60
- type VariantStates<K extends string = string> = Record<K, VariantValue>;
66
+ type VariantStates<K extends string = string> = Record<K, VariantValue$1>;
61
67
 
62
68
  type VariantMap<V extends string = string, K extends string = string> = Record<V, VariantStates<K>>;
63
69
 
@@ -71,7 +77,7 @@ type CompoundVariantConditions<V extends VariantMap> = Simplify<{
71
77
  type CompoundVariantRequiredConditions<V extends VariantMap> = RequireAtLeastOneIfNotEmpty<CompoundVariantConditions<V>>;
72
78
  type CompoundVariantBase<V extends VariantMap> = keyof V extends never ? EmptyRecord : CompoundVariantRequiredConditions<V>;
73
79
  type CompoundVariant<V extends VariantMap> = CompoundVariantBase<V> & {
74
- class: VariantValue;
80
+ class: VariantValue$1;
75
81
  };
76
82
 
77
83
  interface CVACompounds<V extends VariantMap> {
@@ -82,8 +88,9 @@ interface CVACompounds<V extends VariantMap> {
82
88
  type VariantProps<V extends VariantMap> = {
83
89
  [K in keyof V]?: VariantKey<V, K>;
84
90
  };
91
+ type VariantValue<K extends string> = string extends K ? Primitive : K extends 'true' | 'false' ? Booleanish : K extends `${number}` ? Numberish : K;
85
92
  type DefaultVariants<V extends VariantMap> = {
86
- [K in keyof V]?: VariantKey<V, K>;
93
+ [K in keyof V]?: VariantValue<keyof V[K] & string>;
87
94
  };
88
95
 
89
96
  interface CVADefaults<V extends VariantMap> {
@@ -110,9 +117,9 @@ type VariantSelection<V extends VariantMap> = {
110
117
  * Presets are named bundles of variant props that callers activate by key,
111
118
  * avoiding the need to repeat variant combinations at each call site.
112
119
  */
113
- type PresetMap<V extends VariantMap = VariantMap> = Readonly<Record<string, VariantSelection<V>>>;
120
+ type RecipeMap<V extends VariantMap = VariantMap> = Readonly<Record<string, VariantSelection<V>>>;
114
121
 
115
- interface PolymorphicGenerics<TDefault extends ElementType = ElementType, Props extends AnyRecord = AnyRecord, Variants extends Readonly<VariantMap> = Readonly<VariantMap>, TPreset extends PresetMap<Variants> = Readonly<EmptyRecord>, TAllowed extends ElementType = ElementType> {
122
+ interface PolymorphicGenerics<TDefault extends ElementType = ElementType, Props extends AnyRecord = AnyRecord, Variants extends Readonly<VariantMap> = Readonly<VariantMap>, TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>, TAllowed extends ElementType = ElementType> {
116
123
  default: TDefault;
117
124
  props: Props;
118
125
  variants: Variants;
@@ -120,25 +127,25 @@ interface PolymorphicGenerics<TDefault extends ElementType = ElementType, Props
120
127
  allowed: TAllowed;
121
128
  }
122
129
  type VariantsOf<T extends PolymorphicGenerics> = T['variants'];
123
- type PresetOf<T extends PolymorphicGenerics> = T['preset'];
130
+ type RecipeOf<T extends PolymorphicGenerics> = T['preset'];
124
131
 
125
- type PresetTarget<TVariants extends VariantMap = VariantMap> = VariantSelection<TVariants>;
132
+ type RecipeTarget<TVariants extends VariantMap = VariantMap> = VariantSelection<TVariants>;
126
133
 
127
134
  interface BaseClassOptions {
128
135
  baseClassName?: ClassName;
129
136
  }
130
137
 
131
- type ClassPipelineFn = (tag: unknown, props: AnyRecord, className?: ClassName, variantKey?: string) => string;
138
+ type ClassPipelineFn = (tag: unknown, props: AnyRecord, className?: ClassName, recipe?: string) => string;
132
139
 
133
- interface PresetOptions<TVariants extends VariantMap = VariantMap> {
134
- presetMap?: Record<string, PresetTarget<TVariants>>;
140
+ interface RecipeOptions<TVariants extends VariantMap = VariantMap> {
141
+ recipeMap?: Record<string, RecipeTarget<TVariants>>;
135
142
  }
136
143
 
137
144
  interface TagMapOptions {
138
145
  tagMap?: TagMap;
139
146
  }
140
147
 
141
- type CompositionOptions<TVariants extends VariantMap = VariantMap> = Simplify<TagMapOptions & PresetOptions<TVariants>>;
148
+ type CompositionOptions<TVariants extends VariantMap = VariantMap> = Simplify<TagMapOptions & RecipeOptions<TVariants>>;
142
149
 
143
150
  type CVASystemOptions<TVariants extends VariantMap = VariantMap> = Simplify<CVAVariants<TVariants> & CVADefaults<TVariants> & CVACompounds<TVariants>>;
144
151
 
@@ -213,10 +220,10 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
213
220
  readonly allowedAs?: readonly TAllowed[];
214
221
  };
215
222
 
216
- type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends PresetMap<V> = Readonly<EmptyRecord>, TPluginProps extends AnyRecord = EmptyRecord> = {
223
+ type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>, TPluginProps extends AnyRecord = EmptyRecord> = {
217
224
  readonly base?: ClassName;
218
225
  readonly variants?: V;
219
- readonly defaults?: Partial<VariantProps<V>>;
226
+ readonly defaults?: Partial<DefaultVariants<V>>;
220
227
  readonly compounds?: readonly CompoundVariant<V>[];
221
228
  readonly presets?: TPreset;
222
229
  readonly tags?: Readonly<TagMap>;
@@ -227,8 +234,8 @@ type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPre
227
234
  type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
228
235
  normalize(props: Readonly<Props & IntrinsicProps>): Props & IntrinsicProps;
229
236
  }['normalize'];
230
- type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, PresetMap<VariantMap>, AnyRecord>;
231
- type FactoryOptions<TDefault extends ElementType = ElementType, Props extends AnyRecord = EmptyRecord, V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends PresetMap<V> = Readonly<EmptyRecord>, TPluginProps extends AnyRecord = EmptyRecord, TAllowed extends ElementType = ElementType> = {
237
+ type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, RecipeMap<VariantMap>, AnyRecord>;
238
+ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends AnyRecord = EmptyRecord, V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>, TPluginProps extends AnyRecord = EmptyRecord, TAllowed extends ElementType = ElementType> = {
232
239
  readonly tag?: TDefault;
233
240
  readonly name?: string;
234
241
  readonly defaults?: Partial<NoInfer<Props>>;
@@ -240,9 +247,11 @@ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends An
240
247
  type DefaultOf<T extends PolymorphicGenerics> = T['default'];
241
248
  type PropsOf<T extends PolymorphicGenerics> = T['props'];
242
249
 
250
+ declare function defineContractComponent<O extends FactoryOptions>(options: O): <R>(factory: (options: O) => R) => R;
251
+
243
252
  type UnknownProps = Record<string, unknown>;
244
253
 
245
- type VueFactoryOptions<TDefault extends ElementType, Props extends UnknownProps, Variants extends Readonly<VariantMap>, TPreset extends PresetMap<Variants> = Readonly<EmptyRecord>, TPluginProps extends AnyRecord = EmptyRecord> = FactoryOptions<TDefault, Props, Variants, TPreset, TPluginProps> & {
254
+ type VueFactoryOptions<TDefault extends ElementType, Props extends UnknownProps, Variants extends Readonly<VariantMap>, TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>, TPluginProps extends AnyRecord = EmptyRecord> = FactoryOptions<TDefault, Props, Variants, TPreset, TPluginProps> & {
246
255
  /**
247
256
  * Return true for any prop key that should be consumed but not forwarded to
248
257
  * the DOM. Variant keys are always stripped automatically.
@@ -264,7 +273,7 @@ declare const Slottable: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNod
264
273
  type ControlProps<G extends PolymorphicGenerics, TAs extends ElementType> = PropsOf<G> & VariantProps<VariantsOf<G>> & {
265
274
  as?: TAs;
266
275
  class?: ClassName;
267
- variantKey?: keyof PresetOf<G>;
276
+ recipe?: keyof RecipeOf<G>;
268
277
  };
269
278
  /**
270
279
  * Props for the normal (non-slot) render path. `asChild` is absent or `false`.
@@ -299,8 +308,6 @@ type PolymorphicComponent<G extends PolymorphicGenerics> = {
299
308
  displayName?: string;
300
309
  };
301
310
 
302
- declare function createContractComponent<TDefault extends ElementType, Props extends UnknownProps = EmptyRecord, Variants extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends PresetMap<Variants> = Readonly<EmptyRecord>, TPluginProps extends AnyRecord = EmptyRecord>(options: VueFactoryOptions<TDefault, Props, Variants, TPreset, TPluginProps>): PolymorphicComponent<PolymorphicGenerics<TDefault, Props & TPluginProps, Variants, TPreset>>;
303
-
304
- declare function defineContractComponent<O extends FactoryOptions>(options: O): <R>(factory: (options: O) => R) => R;
311
+ declare function createContractComponent<TDefault extends ElementType, Props extends UnknownProps = EmptyRecord, Variants extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>, TPluginProps extends AnyRecord = EmptyRecord>(options: VueFactoryOptions<TDefault, Props, Variants, TPreset, TPluginProps>): PolymorphicComponent<PolymorphicGenerics<TDefault, Props & TPluginProps, Variants, TPreset>>;
305
312
 
306
313
  export { type AnyFactoryOptions, type ElementType, type EmptyRecord, type PolymorphicComponent, type PolymorphicGenerics, type PolymorphicProps, type PolymorphicWithAsChild, Slottable, type SlottableProps, type VueFactoryOptions, createContractComponent, defineContractComponent };