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
package/dist/svelte/index.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ../../lib/adapter-utils/src/define-component.ts
|
|
2
|
+
function defineContractComponent(options) {
|
|
3
|
+
return (factory) => factory(options);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// ../core/dist/chunk-KKSHJDE7.js
|
|
2
7
|
function makeResolveTag(defaultTag) {
|
|
3
8
|
return function tag(as) {
|
|
4
9
|
return as ?? defaultTag;
|
|
@@ -67,7 +72,7 @@ function resolveFactoryOptions(options = {}) {
|
|
|
67
72
|
...whenDefined("defaultProps", options.defaults),
|
|
68
73
|
...whenDefined("baseClassName", styling?.base),
|
|
69
74
|
...whenDefined("tagMap", styling?.tags),
|
|
70
|
-
...whenDefined("
|
|
75
|
+
...whenDefined("recipeMap", styling?.presets),
|
|
71
76
|
...whenDefined("variants", styling?.variants),
|
|
72
77
|
...whenDefined("defaultVariants", styling?.defaults),
|
|
73
78
|
...whenDefined("compoundVariants", styling?.compounds),
|
|
@@ -108,10 +113,10 @@ function validateFactoryOptions(resolved) {
|
|
|
108
113
|
}
|
|
109
114
|
}
|
|
110
115
|
};
|
|
111
|
-
const {
|
|
112
|
-
if (
|
|
113
|
-
for (const
|
|
114
|
-
checkSelection(`preset "${
|
|
116
|
+
const { recipeMap } = resolved;
|
|
117
|
+
if (recipeMap) {
|
|
118
|
+
for (const recipeKey in recipeMap) {
|
|
119
|
+
checkSelection(`preset "${recipeKey}"`, recipeMap[recipeKey]);
|
|
115
120
|
}
|
|
116
121
|
}
|
|
117
122
|
if (resolved.defaultVariants) checkSelection("defaults", resolved.defaultVariants);
|
|
@@ -147,12 +152,12 @@ function report2(strict, message) {
|
|
|
147
152
|
function label(name) {
|
|
148
153
|
return name ? `[${name}]` : "[createContractComponent]";
|
|
149
154
|
}
|
|
150
|
-
function validateRenderProps(options, props,
|
|
151
|
-
const { strict,
|
|
155
|
+
function validateRenderProps(options, props, recipeKey) {
|
|
156
|
+
const { strict, recipeMap, variants, displayName } = options;
|
|
152
157
|
if (!strict) return;
|
|
153
158
|
const tag = label(displayName);
|
|
154
|
-
if (
|
|
155
|
-
report2(strict, `${tag} Unknown
|
|
159
|
+
if (recipeKey !== void 0 && (!recipeMap || !Object.hasOwn(recipeMap, recipeKey))) {
|
|
160
|
+
report2(strict, `${tag} Unknown recipeKey "${recipeKey}" \u2014 no preset with that name exists.`);
|
|
156
161
|
}
|
|
157
162
|
if (variants) {
|
|
158
163
|
for (const key in variants) {
|
|
@@ -190,8 +195,8 @@ function assertPluginShape(result) {
|
|
|
190
195
|
}
|
|
191
196
|
function guardPipeline(pipeline) {
|
|
192
197
|
if (process.env.NODE_ENV === "production") return pipeline;
|
|
193
|
-
return function guardedPipeline(tag, props, className,
|
|
194
|
-
const result = pipeline(tag, props, className,
|
|
198
|
+
return function guardedPipeline(tag, props, className, recipe) {
|
|
199
|
+
const result = pipeline(tag, props, className, recipe);
|
|
195
200
|
if (typeof result !== "string")
|
|
196
201
|
panic(`[praxis-kit] Plugin pipeline must return a string. Got: ${describe(result)}.`);
|
|
197
202
|
return result;
|
|
@@ -216,11 +221,11 @@ function createRuntimeMethods(resolved, classPipeline, engine) {
|
|
|
216
221
|
resolveProps(props) {
|
|
217
222
|
return mergeProps(resolved.defaultProps, props);
|
|
218
223
|
},
|
|
219
|
-
resolveClasses(tag, props, className,
|
|
224
|
+
resolveClasses(tag, props, className, recipe) {
|
|
220
225
|
if (process.env.NODE_ENV !== "production") {
|
|
221
|
-
validateRenderProps(resolved, props,
|
|
226
|
+
validateRenderProps(resolved, props, recipe);
|
|
222
227
|
}
|
|
223
|
-
return classPipeline(tag, props, className,
|
|
228
|
+
return classPipeline(tag, props, className, recipe);
|
|
224
229
|
},
|
|
225
230
|
resolveAria(tag, props) {
|
|
226
231
|
if (!engine) return { props };
|
|
@@ -566,7 +571,7 @@ function isStandaloneTag(tag) {
|
|
|
566
571
|
return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
|
|
567
572
|
}
|
|
568
573
|
|
|
569
|
-
// ../core/dist/chunk-
|
|
574
|
+
// ../core/dist/chunk-BNVYTMYV.js
|
|
570
575
|
var IMPLICIT_ROLE_RECORD2 = {
|
|
571
576
|
article: "article",
|
|
572
577
|
aside: "complementary",
|
|
@@ -1501,7 +1506,7 @@ function getHtmlPropNormalizers(tag) {
|
|
|
1501
1506
|
return typeof tag === "string" ? HTML_FORM_NORMALIZERS.get(tag) : void 0;
|
|
1502
1507
|
}
|
|
1503
1508
|
|
|
1504
|
-
// ../core/dist/chunk-
|
|
1509
|
+
// ../core/dist/chunk-3T4EM5FG.js
|
|
1505
1510
|
var falsyToString = (value) => typeof value === "boolean" ? `${value}` : value === 0 ? "0" : value;
|
|
1506
1511
|
var cx = clsx;
|
|
1507
1512
|
var cva = (base, config) => (props) => {
|
|
@@ -1578,18 +1583,18 @@ var StaticClassResolver = class {
|
|
|
1578
1583
|
};
|
|
1579
1584
|
var VariantClassResolver = class _VariantClassResolver {
|
|
1580
1585
|
#cvaFn;
|
|
1581
|
-
#
|
|
1586
|
+
#recipeMap;
|
|
1582
1587
|
#variantKeys;
|
|
1583
1588
|
#precomputedClasses;
|
|
1584
1589
|
#cache = /* @__PURE__ */ new Map();
|
|
1585
|
-
constructor(cvaFn,
|
|
1590
|
+
constructor(cvaFn, recipeMap, variantKeys, precomputedClasses) {
|
|
1586
1591
|
this.#cvaFn = cvaFn ?? null;
|
|
1587
|
-
this.#
|
|
1592
|
+
this.#recipeMap = Object.freeze(recipeMap ?? {});
|
|
1588
1593
|
this.#variantKeys = variantKeys ?? null;
|
|
1589
1594
|
this.#precomputedClasses = precomputedClasses ?? null;
|
|
1590
1595
|
}
|
|
1591
|
-
resolve({ props,
|
|
1592
|
-
const normalizedKey =
|
|
1596
|
+
resolve({ props, recipe }) {
|
|
1597
|
+
const normalizedKey = recipe ?? "__none__";
|
|
1593
1598
|
const cacheKey = this.#createCacheKey(props, normalizedKey);
|
|
1594
1599
|
if (this.#precomputedClasses !== null) {
|
|
1595
1600
|
const precomputed = this.#precomputedClasses[cacheKey];
|
|
@@ -1601,7 +1606,7 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
1601
1606
|
this.#cache.set(cacheKey, cached);
|
|
1602
1607
|
return cached;
|
|
1603
1608
|
}
|
|
1604
|
-
const result = this.#compute(props,
|
|
1609
|
+
const result = this.#compute(props, recipe);
|
|
1605
1610
|
this.#cache.set(cacheKey, result);
|
|
1606
1611
|
if (this.#cache.size > 1e3) {
|
|
1607
1612
|
const lru = this.#cache.keys().next().value;
|
|
@@ -1609,10 +1614,10 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
1609
1614
|
}
|
|
1610
1615
|
return result;
|
|
1611
1616
|
}
|
|
1612
|
-
#compute(props,
|
|
1617
|
+
#compute(props, recipe) {
|
|
1613
1618
|
if (!this.#cvaFn) return "";
|
|
1614
|
-
if (!
|
|
1615
|
-
const preset = this.#
|
|
1619
|
+
if (!recipe) return this.#cvaFn(props);
|
|
1620
|
+
const preset = this.#recipeMap[recipe];
|
|
1616
1621
|
if (!preset) return this.#cvaFn(props);
|
|
1617
1622
|
return this.#cvaFn({ ...preset, ...props });
|
|
1618
1623
|
}
|
|
@@ -1620,15 +1625,15 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
1620
1625
|
// props (className, id, etc.) produce identical CVA output and must not fragment the cache.
|
|
1621
1626
|
// Iterating #variantKeys directly (fixed Set insertion order) avoids Object.keys + filter + sort.
|
|
1622
1627
|
// String is built incrementally to avoid a parts[] array allocation on every render.
|
|
1623
|
-
#createCacheKey(props,
|
|
1628
|
+
#createCacheKey(props, recipe) {
|
|
1624
1629
|
if (this.#variantKeys !== null) {
|
|
1625
|
-
let key2 =
|
|
1630
|
+
let key2 = recipe;
|
|
1626
1631
|
for (const k of this.#variantKeys) {
|
|
1627
1632
|
if (k in props) key2 += `|${k}:${_VariantClassResolver.#serializeValue(props[k])}`;
|
|
1628
1633
|
}
|
|
1629
1634
|
return key2;
|
|
1630
1635
|
}
|
|
1631
|
-
let key =
|
|
1636
|
+
let key = recipe;
|
|
1632
1637
|
for (const k of Object.keys(props).sort()) {
|
|
1633
1638
|
key += `|${k}:${_VariantClassResolver.#serializeValue(props[k])}`;
|
|
1634
1639
|
}
|
|
@@ -1653,13 +1658,13 @@ function createClassPipeline(resolved) {
|
|
|
1653
1658
|
const staticResolver = new StaticClassResolver(baseClass, resolved.tagMap);
|
|
1654
1659
|
const variantResolver = new VariantClassResolver(
|
|
1655
1660
|
cvaFn,
|
|
1656
|
-
resolved.
|
|
1661
|
+
resolved.recipeMap,
|
|
1657
1662
|
variantKeys,
|
|
1658
1663
|
resolved.precomputedClasses
|
|
1659
1664
|
);
|
|
1660
|
-
return function resolveClasses(tag, props, className,
|
|
1661
|
-
const staticClasses = staticResolver.resolve(tag,
|
|
1662
|
-
const variantClasses = variantResolver.resolve({ props,
|
|
1665
|
+
return function resolveClasses(tag, props, className, recipe) {
|
|
1666
|
+
const staticClasses = staticResolver.resolve(tag, recipe !== void 0);
|
|
1667
|
+
const variantClasses = variantResolver.resolve({ props, recipe });
|
|
1663
1668
|
if (!className)
|
|
1664
1669
|
return staticClasses && variantClasses ? `${staticClasses} ${variantClasses}` : staticClasses || variantClasses;
|
|
1665
1670
|
return cn(staticClasses, variantClasses, className);
|
|
@@ -1759,11 +1764,6 @@ function createContractComponent(options) {
|
|
|
1759
1764
|
options
|
|
1760
1765
|
);
|
|
1761
1766
|
}
|
|
1762
|
-
|
|
1763
|
-
// ../../adapters/svelte/src/define-contract-component.ts
|
|
1764
|
-
function defineContractComponent(options) {
|
|
1765
|
-
return (factory) => factory(options);
|
|
1766
|
-
}
|
|
1767
1767
|
export {
|
|
1768
1768
|
createContractComponent,
|
|
1769
1769
|
defineContractComponent
|
package/dist/tailwind/index.js
CHANGED
|
@@ -98,18 +98,18 @@ var StaticClassResolver = class {
|
|
|
98
98
|
// ../../lib/styling/src/variant-class-resolver.ts
|
|
99
99
|
var VariantClassResolver = class _VariantClassResolver {
|
|
100
100
|
#cvaFn;
|
|
101
|
-
#
|
|
101
|
+
#recipeMap;
|
|
102
102
|
#variantKeys;
|
|
103
103
|
#precomputedClasses;
|
|
104
104
|
#cache = /* @__PURE__ */ new Map();
|
|
105
|
-
constructor(cvaFn,
|
|
105
|
+
constructor(cvaFn, recipeMap, variantKeys, precomputedClasses) {
|
|
106
106
|
this.#cvaFn = cvaFn ?? null;
|
|
107
|
-
this.#
|
|
107
|
+
this.#recipeMap = Object.freeze(recipeMap ?? {});
|
|
108
108
|
this.#variantKeys = variantKeys ?? null;
|
|
109
109
|
this.#precomputedClasses = precomputedClasses ?? null;
|
|
110
110
|
}
|
|
111
|
-
resolve({ props,
|
|
112
|
-
const normalizedKey =
|
|
111
|
+
resolve({ props, recipe }) {
|
|
112
|
+
const normalizedKey = recipe ?? "__none__";
|
|
113
113
|
const cacheKey = this.#createCacheKey(props, normalizedKey);
|
|
114
114
|
if (this.#precomputedClasses !== null) {
|
|
115
115
|
const precomputed = this.#precomputedClasses[cacheKey];
|
|
@@ -121,7 +121,7 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
121
121
|
this.#cache.set(cacheKey, cached);
|
|
122
122
|
return cached;
|
|
123
123
|
}
|
|
124
|
-
const result = this.#compute(props,
|
|
124
|
+
const result = this.#compute(props, recipe);
|
|
125
125
|
this.#cache.set(cacheKey, result);
|
|
126
126
|
if (this.#cache.size > 1e3) {
|
|
127
127
|
const lru = this.#cache.keys().next().value;
|
|
@@ -129,10 +129,10 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
129
129
|
}
|
|
130
130
|
return result;
|
|
131
131
|
}
|
|
132
|
-
#compute(props,
|
|
132
|
+
#compute(props, recipe) {
|
|
133
133
|
if (!this.#cvaFn) return "";
|
|
134
|
-
if (!
|
|
135
|
-
const preset = this.#
|
|
134
|
+
if (!recipe) return this.#cvaFn(props);
|
|
135
|
+
const preset = this.#recipeMap[recipe];
|
|
136
136
|
if (!preset) return this.#cvaFn(props);
|
|
137
137
|
return this.#cvaFn({ ...preset, ...props });
|
|
138
138
|
}
|
|
@@ -140,15 +140,15 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
140
140
|
// props (className, id, etc.) produce identical CVA output and must not fragment the cache.
|
|
141
141
|
// Iterating #variantKeys directly (fixed Set insertion order) avoids Object.keys + filter + sort.
|
|
142
142
|
// String is built incrementally to avoid a parts[] array allocation on every render.
|
|
143
|
-
#createCacheKey(props,
|
|
143
|
+
#createCacheKey(props, recipe) {
|
|
144
144
|
if (this.#variantKeys !== null) {
|
|
145
|
-
let key2 =
|
|
145
|
+
let key2 = recipe;
|
|
146
146
|
for (const k of this.#variantKeys) {
|
|
147
147
|
if (k in props) key2 += `|${k}:${_VariantClassResolver.#serializeValue(props[k])}`;
|
|
148
148
|
}
|
|
149
149
|
return key2;
|
|
150
150
|
}
|
|
151
|
-
let key =
|
|
151
|
+
let key = recipe;
|
|
152
152
|
for (const k of Object.keys(props).sort()) {
|
|
153
153
|
key += `|${k}:${_VariantClassResolver.#serializeValue(props[k])}`;
|
|
154
154
|
}
|
|
@@ -175,13 +175,13 @@ function createClassPipeline(resolved) {
|
|
|
175
175
|
const staticResolver = new StaticClassResolver(baseClass, resolved.tagMap);
|
|
176
176
|
const variantResolver = new VariantClassResolver(
|
|
177
177
|
cvaFn,
|
|
178
|
-
resolved.
|
|
178
|
+
resolved.recipeMap,
|
|
179
179
|
variantKeys,
|
|
180
180
|
resolved.precomputedClasses
|
|
181
181
|
);
|
|
182
|
-
return function resolveClasses(tag, props, className,
|
|
183
|
-
const staticClasses = staticResolver.resolve(tag,
|
|
184
|
-
const variantClasses = variantResolver.resolve({ props,
|
|
182
|
+
return function resolveClasses(tag, props, className, recipe) {
|
|
183
|
+
const staticClasses = staticResolver.resolve(tag, recipe !== void 0);
|
|
184
|
+
const variantClasses = variantResolver.resolve({ props, recipe });
|
|
185
185
|
if (!className)
|
|
186
186
|
return staticClasses && variantClasses ? `${staticClasses} ${variantClasses}` : staticClasses || variantClasses;
|
|
187
187
|
return cn(staticClasses, variantClasses, className);
|
|
@@ -446,8 +446,8 @@ function compoundDimensions(compounds) {
|
|
|
446
446
|
function getDefaultVariants(options) {
|
|
447
447
|
return options.defaultVariants;
|
|
448
448
|
}
|
|
449
|
-
function resolveActiveSelection(options, variants, props,
|
|
450
|
-
const preset =
|
|
449
|
+
function resolveActiveSelection(options, variants, props, recipe) {
|
|
450
|
+
const preset = recipe ? options.recipeMap?.[recipe] : void 0;
|
|
451
451
|
const defaults = getDefaultVariants(options);
|
|
452
452
|
const selection = {};
|
|
453
453
|
for (const dim in variants) {
|
|
@@ -456,11 +456,11 @@ function resolveActiveSelection(options, variants, props, variantKey) {
|
|
|
456
456
|
}
|
|
457
457
|
return selection;
|
|
458
458
|
}
|
|
459
|
-
function warnDeadVariants(strict, options, compoundDims, props,
|
|
459
|
+
function warnDeadVariants(strict, options, compoundDims, props, recipe, state) {
|
|
460
460
|
if (!strict) return;
|
|
461
461
|
const variants = getVariantConfig(options);
|
|
462
462
|
if (!variants) return;
|
|
463
|
-
const selection = resolveActiveSelection(options, variants, props,
|
|
463
|
+
const selection = resolveActiveSelection(options, variants, props, recipe);
|
|
464
464
|
for (const dim in selection) {
|
|
465
465
|
if (compoundDims.has(dim)) continue;
|
|
466
466
|
const value = selection[dim];
|
|
@@ -482,14 +482,14 @@ function createTailwindPipeline(options, strict) {
|
|
|
482
482
|
const compoundDims = compoundDimensions(getCompoundVariants(options));
|
|
483
483
|
return {
|
|
484
484
|
ownedKeys: LAYOUT_OWNED_KEYS,
|
|
485
|
-
pipeline(tag, props, className,
|
|
485
|
+
pipeline(tag, props, className, recipe) {
|
|
486
486
|
const mode = resolveLayout(props);
|
|
487
|
-
const raw = pipeline(tag, props, className,
|
|
487
|
+
const raw = pipeline(tag, props, className, recipe);
|
|
488
488
|
const tokens = classifyTokens(raw);
|
|
489
489
|
const state = new LayoutState(mode);
|
|
490
490
|
if (DEV) {
|
|
491
491
|
warnReservedLayoutLiterals(strict, tokens);
|
|
492
|
-
warnDeadVariants(strict, options, compoundDims, props,
|
|
492
|
+
warnDeadVariants(strict, options, compoundDims, props, recipe, state);
|
|
493
493
|
}
|
|
494
494
|
const filtered = tokens.filter((token) => evaluator.evaluate(token, state));
|
|
495
495
|
const built = builder.build(filtered);
|
|
@@ -108,6 +108,74 @@ type DesignTokensOptions = {
|
|
|
108
108
|
*/
|
|
109
109
|
declare function designTokensPlugin(options?: DesignTokensOptions): Plugin;
|
|
110
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Compile-time static composition transform.
|
|
113
|
+
*
|
|
114
|
+
* For factory calls that have `precomputedClasses` injected (by classExtractPlugin),
|
|
115
|
+
* replaces static JSX usage sites with direct element creation — bypassing the
|
|
116
|
+
* runtime render pipeline entirely.
|
|
117
|
+
*
|
|
118
|
+
* Example:
|
|
119
|
+
* // Source (same file defines Button and uses it)
|
|
120
|
+
* const Button = createContractComponent({ tag: 'button', styling: { precomputedClasses: {...} } })
|
|
121
|
+
* <Button size="lg">Click</Button>
|
|
122
|
+
*
|
|
123
|
+
* // Output
|
|
124
|
+
* const Button = createContractComponent({ ... }) // unchanged — still exported
|
|
125
|
+
* <button className="btn btn-lg">Click</button> // inlined!
|
|
126
|
+
*
|
|
127
|
+
* **Eligibility conditions** — a usage site is inlined only when:
|
|
128
|
+
* 1. The component is defined in the same file or imported from a file already
|
|
129
|
+
* transformed by this plugin, with `precomputedClasses` injected
|
|
130
|
+
* 2. No `as`, `asChild`, `render`, or spread attributes at the usage site
|
|
131
|
+
* 3. All variant props are static string literals
|
|
132
|
+
* 4. `className` is absent or a static string literal
|
|
133
|
+
* 5. The factory config has no top-level `defaults` and no `enforcement`
|
|
134
|
+
* (either would require runtime prop normalization that inlining skips)
|
|
135
|
+
*
|
|
136
|
+
* The factory call itself is intentionally left in the output so the component
|
|
137
|
+
* remains exportable for cross-file consumption that falls back to the runtime
|
|
138
|
+
* path. Dead-code elimination at the bundler level can remove it when no
|
|
139
|
+
* runtime path remains.
|
|
140
|
+
*
|
|
141
|
+
* **Cross-file known limitations:**
|
|
142
|
+
* - Barrel re-exports are not resolved (import from index.ts re-exporting ./Button)
|
|
143
|
+
* - Aliased imports are not matched (`export { Btn as Button }` won't be found)
|
|
144
|
+
* - Dev-mode ordering: definition file may not yet be transformed when consumer runs
|
|
145
|
+
* All three degrade gracefully to the runtime path — no error, no broken output.
|
|
146
|
+
*/
|
|
147
|
+
|
|
148
|
+
type StaticComponent = {
|
|
149
|
+
readonly defaultTag: string;
|
|
150
|
+
readonly variantKeys: ReadonlySet<string>;
|
|
151
|
+
readonly precomputedClasses: Readonly<Record<string, string>>;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Walks the source file and extracts metadata for each same-file factory call
|
|
155
|
+
* that is eligible for static composition.
|
|
156
|
+
*/
|
|
157
|
+
declare function extractStaticComponents(source: ts.SourceFile, calleeNames: ReadonlySet<string>): Map<string, StaticComponent>;
|
|
158
|
+
/**
|
|
159
|
+
* Applies the static composition transform to the given source file.
|
|
160
|
+
*
|
|
161
|
+
* `importedComponents` contains cross-file metadata resolved by the plugin
|
|
162
|
+
* registry — components defined in other files that were already transformed.
|
|
163
|
+
* When empty (dev mode ordering race or barrel re-export), same-file components
|
|
164
|
+
* still inline normally; cross-file sites fall through to the runtime path.
|
|
165
|
+
*
|
|
166
|
+
* Returns null when:
|
|
167
|
+
* - No eligible factory calls or imported components are present
|
|
168
|
+
* - No eligible usage sites are found after analysis
|
|
169
|
+
*/
|
|
170
|
+
declare function composeStatically(source: ts.SourceFile, calleeNames: ReadonlySet<string>, importedComponents?: ReadonlyMap<string, StaticComponent>): string | null;
|
|
171
|
+
|
|
172
|
+
type ImportBinding = {
|
|
173
|
+
/** The exported name in the source module (the name before `as`, if any). */
|
|
174
|
+
readonly importedName: string;
|
|
175
|
+
/** The module specifier string (e.g. `'./Button'`). */
|
|
176
|
+
readonly specifier: string;
|
|
177
|
+
};
|
|
178
|
+
|
|
111
179
|
/**
|
|
112
180
|
* Pure analysis entry point. Parses `code` as TypeScript/TSX, extracts
|
|
113
181
|
* enforcement.children constraints from factory calls, and validates JSX usage
|
|
@@ -220,49 +288,6 @@ declare function buildPrecomputedClasses(stylingObj: ts.ObjectLiteralExpression)
|
|
|
220
288
|
*/
|
|
221
289
|
declare function injectPrecomputedClasses(source: ts.SourceFile, calleeNames: ReadonlySet<string>): string | null;
|
|
222
290
|
|
|
223
|
-
/**
|
|
224
|
-
* Compile-time static composition transform.
|
|
225
|
-
*
|
|
226
|
-
* For same-file factory calls that have `precomputedClasses` injected (by
|
|
227
|
-
* classExtractPlugin), replaces static JSX usage sites with direct element
|
|
228
|
-
* creation — bypassing the runtime render pipeline entirely.
|
|
229
|
-
*
|
|
230
|
-
* Example:
|
|
231
|
-
* // Source (same file defines Button and uses it)
|
|
232
|
-
* const Button = createContractComponent({ tag: 'button', styling: { precomputedClasses: {...} } })
|
|
233
|
-
* <Button size="lg">Click</Button>
|
|
234
|
-
*
|
|
235
|
-
* // Output
|
|
236
|
-
* const Button = createContractComponent({ ... }) // unchanged — still exported
|
|
237
|
-
* <button className="btn btn-lg">Click</button> // inlined!
|
|
238
|
-
*
|
|
239
|
-
* **Eligibility conditions** — a usage site is inlined only when:
|
|
240
|
-
* 1. The component is defined in the same file via a factory call with
|
|
241
|
-
* `precomputedClasses` (classExtractPlugin must run first in the chain)
|
|
242
|
-
* 2. No `as`, `asChild`, `render`, or spread attributes at the usage site
|
|
243
|
-
* 3. All variant props are static string literals
|
|
244
|
-
* 4. `className` is absent or a static string literal
|
|
245
|
-
* 5. The factory config has no top-level `defaults` and no `enforcement`
|
|
246
|
-
* (either would require runtime prop normalization that inlining skips)
|
|
247
|
-
*
|
|
248
|
-
* The factory call itself is intentionally left in the output so the component
|
|
249
|
-
* remains exportable for cross-file consumption that falls back to the runtime
|
|
250
|
-
* path. Dead-code elimination at the bundler level can remove it when no
|
|
251
|
-
* runtime path remains.
|
|
252
|
-
*
|
|
253
|
-
* **Deferred:** cross-file inlining (component defined in one module, used in
|
|
254
|
-
* another) requires Vite module-graph traversal and is not yet implemented.
|
|
255
|
-
*/
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Applies the static composition transform to the given source file.
|
|
259
|
-
*
|
|
260
|
-
* Returns null when:
|
|
261
|
-
* - No eligible factory calls are found in the file
|
|
262
|
-
* - No eligible usage sites are found after analysis
|
|
263
|
-
*/
|
|
264
|
-
declare function composeStatically(source: ts.SourceFile, calleeNames: ReadonlySet<string>): string | null;
|
|
265
|
-
|
|
266
291
|
/**
|
|
267
292
|
* Vite plugin that performs static enforcement.children cardinality checks at
|
|
268
293
|
* build time for components created with createContractComponent.
|
|
@@ -345,23 +370,24 @@ declare function classExtractPlugin(options?: Pick<PluginOptions, 'calleeNames'>
|
|
|
345
370
|
*/
|
|
346
371
|
declare function slotTransformPlugin(): Plugin;
|
|
347
372
|
/**
|
|
348
|
-
* Vite plugin that replaces
|
|
349
|
-
*
|
|
350
|
-
*
|
|
373
|
+
* Vite plugin that replaces polymorphic component usage sites with direct
|
|
374
|
+
* element creation at build time, eliminating the runtime render pipeline for
|
|
375
|
+
* statically-analyzable usages.
|
|
351
376
|
*
|
|
352
377
|
* **Requires classExtractPlugin to run first** so that `precomputedClasses` is
|
|
353
378
|
* present in the factory call before this plugin reads it. Place after
|
|
354
379
|
* `classExtractPlugin` in the plugins array.
|
|
355
380
|
*
|
|
356
381
|
* A usage site is inlined when:
|
|
357
|
-
* - The component is defined in the same file
|
|
382
|
+
* - The component is defined in the same file or imported from a file already
|
|
383
|
+
* transformed by this plugin, with `precomputedClasses` injected
|
|
358
384
|
* - No `as`, `asChild`, `render`, or spread attributes at the site
|
|
359
385
|
* - All variant props are static string literals
|
|
360
386
|
* - `className` is absent or a static string literal
|
|
361
387
|
* - The factory config has no `defaults` or `enforcement`
|
|
362
388
|
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
389
|
+
* Cross-file inlining degrades gracefully when the definition file has not yet
|
|
390
|
+
* been transformed (dev mode ordering, barrel re-exports, aliased imports).
|
|
365
391
|
*
|
|
366
392
|
* @example
|
|
367
393
|
* // vite.config.ts
|
|
@@ -392,4 +418,4 @@ declare function staticCompositionPlugin(options?: Pick<PluginOptions, 'calleeNa
|
|
|
392
418
|
*/
|
|
393
419
|
declare function ssrOptimizePlugin(options?: Pick<PluginOptions, 'calleeNames'>): Plugin[];
|
|
394
420
|
|
|
395
|
-
export { type ComponentConstraint, type ComponentTokens, type DesignTokenManifest, type DesignTokensOptions, type Diagnostic, type PluginOptions, type StaticBound, analyze, buildManifest, buildPrecomputedClasses, classExtractPlugin, collectFileTokens, composeStatically, compoundPrunePlugin, contractPlugin, designTokensPlugin, injectPrecomputedClasses, pruneDeadCompounds, slotTransformPlugin, ssrOptimizePlugin, staticCompositionPlugin, transformAsChild };
|
|
421
|
+
export { type ComponentConstraint, type ComponentTokens, type DesignTokenManifest, type DesignTokensOptions, type Diagnostic, type ImportBinding, type PluginOptions, type StaticBound, type StaticComponent, analyze, buildManifest, buildPrecomputedClasses, classExtractPlugin, collectFileTokens, composeStatically, compoundPrunePlugin, contractPlugin, designTokensPlugin, extractStaticComponents, injectPrecomputedClasses, pruneDeadCompounds, slotTransformPlugin, ssrOptimizePlugin, staticCompositionPlugin, transformAsChild };
|