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.
- package/dist/{chunk-ACAKUHH5.js → chunk-PBBPAHMV.js} +170 -164
- package/dist/contract/index.d.ts +21 -18
- package/dist/contract/index.js +2 -2
- package/dist/lit/index.d.ts +26 -23
- package/dist/lit/index.js +45 -45
- package/dist/{merge-refs-DxjWMq3U.d.ts → merge-refs-CfAbwCKz.d.ts} +28 -19
- package/dist/preact/index.d.ts +28 -21
- package/dist/preact/index.js +40 -40
- package/dist/react/index.d.ts +8 -10
- package/dist/react/index.js +2 -6
- package/dist/react/legacy.d.ts +7 -7
- package/dist/react/legacy.js +3 -1
- package/dist/solid/index.d.ts +29 -22
- package/dist/solid/index.js +40 -40
- package/dist/svelte/index.d.ts +33 -30
- package/dist/svelte/index.js +38 -38
- package/dist/tailwind/index.js +23 -23
- package/dist/vite-plugin/index.d.ts +76 -50
- package/dist/vite-plugin/index.js +146 -41
- package/dist/vue/index.d.ts +28 -21
- package/dist/vue/index.js +40 -40
- package/dist/web/index.d.ts +26 -23
- package/dist/web/index.js +43 -43
- package/package.json +1 -1
|
@@ -332,11 +332,13 @@ function processVariableStatement(node, calleeNames, out) {
|
|
|
332
332
|
}
|
|
333
333
|
}
|
|
334
334
|
if (rules.length === 0 && !hasAriaRules && !defaultTag) continue;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 ${
|
|
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
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
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
|
-
|
|
637
|
+
c = ONE;
|
|
578
638
|
}
|
|
639
|
+
if (!c) return void 0;
|
|
640
|
+
min += c.min;
|
|
641
|
+
max += c.max;
|
|
579
642
|
}
|
|
580
|
-
return
|
|
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 =
|
|
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 =
|
|
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 ${
|
|
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 ${
|
|
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
|
|
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
|
|
1178
|
+
import ts9 from "typescript";
|
|
1092
1179
|
function collectStringValues(node, out) {
|
|
1093
1180
|
if (!node) return;
|
|
1094
|
-
if (
|
|
1181
|
+
if (ts9.isStringLiteral(node)) {
|
|
1095
1182
|
if (node.text.trim()) out.push(node.text);
|
|
1096
1183
|
return;
|
|
1097
1184
|
}
|
|
1098
|
-
if (
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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
|
-
|
|
1140
|
-
if (!
|
|
1226
|
+
ts9.forEachChild(source, (stmt) => {
|
|
1227
|
+
if (!ts9.isVariableStatement(stmt)) return;
|
|
1141
1228
|
for (const decl of stmt.declarationList.declarations) {
|
|
1142
|
-
if (!decl.initializer || !
|
|
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 =
|
|
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 [
|
|
1239
|
-
if (!importedTagsInUse.has(
|
|
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(
|
|
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
|
-
|
|
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
|
|
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,
|
package/dist/vue/index.d.ts
CHANGED
|
@@ -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]?:
|
|
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
|
|
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
|
|
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
|
|
130
|
+
type RecipeOf<T extends PolymorphicGenerics> = T['preset'];
|
|
124
131
|
|
|
125
|
-
type
|
|
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,
|
|
138
|
+
type ClassPipelineFn = (tag: unknown, props: AnyRecord, className?: ClassName, recipe?: string) => string;
|
|
132
139
|
|
|
133
|
-
interface
|
|
134
|
-
|
|
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 &
|
|
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
|
|
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<
|
|
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,
|
|
231
|
-
type FactoryOptions<TDefault extends ElementType = ElementType, Props extends AnyRecord = EmptyRecord, V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends
|
|
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
|
|
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
|
-
|
|
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
|
|
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 };
|