@animus-ui/system 0.1.0-next.v7 → 0.1.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/README.md +148 -0
- package/dist/Animus.d.ts +36 -30
- package/dist/Animus.d.ts.map +1 -1
- package/dist/AnimusExtended.d.ts +32 -27
- package/dist/AnimusExtended.d.ts.map +1 -1
- package/dist/SystemBuilder.d.ts +38 -32
- package/dist/SystemBuilder.d.ts.map +1 -1
- package/dist/compose.d.ts +24 -0
- package/dist/compose.d.ts.map +1 -0
- package/dist/compose.js +36 -0
- package/dist/composeWithContext.d.ts +30 -0
- package/dist/composeWithContext.d.ts.map +1 -0
- package/dist/composeWithContext.js +79 -0
- package/dist/createComposedFamily-BsyI6rBc.js +230 -0
- package/dist/groups/index.d.ts +455 -359
- package/dist/groups/index.d.ts.map +1 -1
- package/dist/groups/index.js +139 -55
- package/dist/index.d.ts +14 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +708 -102
- package/dist/keyframes.d.ts +45 -0
- package/dist/keyframes.d.ts.map +1 -0
- package/dist/runtime/createClassResolver.d.ts +10 -0
- package/dist/runtime/createClassResolver.d.ts.map +1 -0
- package/dist/runtime/createComposedFamily.d.ts +16 -0
- package/dist/runtime/createComposedFamily.d.ts.map +1 -0
- package/dist/runtime/index.d.ts +26 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/resolveClasses.d.ts +59 -0
- package/dist/runtime/resolveClasses.d.ts.map +1 -0
- package/dist/runtime-entry.d.ts +10 -0
- package/dist/runtime-entry.d.ts.map +1 -0
- package/dist/runtime-entry.js +2 -0
- package/dist/selectors.d.ts +40 -0
- package/dist/selectors.d.ts.map +1 -0
- package/dist/size-CusLCguT.js +97 -0
- package/dist/theme/createTheme.d.ts +59 -0
- package/dist/theme/createTheme.d.ts.map +1 -0
- package/dist/theme/flattenScale.d.ts +21 -0
- package/dist/theme/flattenScale.d.ts.map +1 -0
- package/dist/theme/index.d.ts +5 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/serializeTokens.d.ts +8 -0
- package/dist/theme/serializeTokens.d.ts.map +1 -0
- package/dist/theme/types.d.ts +42 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/utils.d.ts +28 -0
- package/dist/theme/utils.d.ts.map +1 -0
- package/dist/transforms/border.d.ts +4 -0
- package/dist/transforms/border.d.ts.map +1 -1
- package/dist/transforms/createTransform.d.ts +3 -1
- package/dist/transforms/createTransform.d.ts.map +1 -1
- package/dist/transforms/grid.d.ts +12 -2
- package/dist/transforms/grid.d.ts.map +1 -1
- package/dist/transforms/index.d.ts +0 -1
- package/dist/transforms/index.d.ts.map +1 -1
- package/dist/transforms/size.d.ts +8 -0
- package/dist/transforms/size.d.ts.map +1 -1
- package/dist/types/component.d.ts +148 -24
- package/dist/types/component.d.ts.map +1 -1
- package/dist/types/config.d.ts +54 -7
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/properties.d.ts +5 -7
- package/dist/types/properties.d.ts.map +1 -1
- package/dist/types/props.d.ts +13 -25
- package/dist/types/props.d.ts.map +1 -1
- package/dist/types/shared.d.ts +0 -1
- package/dist/types/shared.d.ts.map +1 -1
- package/dist/types/theme.d.ts +77 -11
- package/dist/types/theme.d.ts.map +1 -1
- package/dist/utils/deepMerge.d.ts +5 -0
- package/dist/utils/deepMerge.d.ts.map +1 -0
- package/package.json +46 -17
- package/dist/PropertyBuilder.d.ts +0 -11
- package/dist/PropertyBuilder.d.ts.map +0 -1
- package/dist/size-Dge_rsuz.js +0 -70
- package/dist/transforms/utils.d.ts +0 -3
- package/dist/transforms/utils.d.ts.map +0 -1
package/dist/compose.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createElement, forwardRef } from "react";
|
|
2
|
+
//#region src/compose.ts
|
|
3
|
+
/**
|
|
4
|
+
* Compose independently-authored Animus components into a sealed,
|
|
5
|
+
* namespaced component family with shared variant propagation via
|
|
6
|
+
* CSS cascade.
|
|
7
|
+
*
|
|
8
|
+
* - **Enforce**: TypeScript ensures shared keys exist on Root (the
|
|
9
|
+
* cascade source). Non-Root slots that have the key consume it from
|
|
10
|
+
* CSS inheritance; slots without the key are unaffected.
|
|
11
|
+
* - **Wire**: The extraction pipeline emits composed variant CSS
|
|
12
|
+
* rules — two per shared variant option per child (inheritance +
|
|
13
|
+
* override) within @layer variants.
|
|
14
|
+
* - **Seal**: Output components are plain ForwardRefExoticComponent —
|
|
15
|
+
* no `.extend()`, no builder methods. One-way door from builder-land
|
|
16
|
+
* to component-land.
|
|
17
|
+
*
|
|
18
|
+
* For React context propagation (portal-crossing), use
|
|
19
|
+
* `composeWithContext` from `@animus-ui/system/compose-with-context`.
|
|
20
|
+
*/
|
|
21
|
+
function compose(slots, options) {
|
|
22
|
+
const familyName = options.name ?? "Composed";
|
|
23
|
+
const result = {};
|
|
24
|
+
for (const [name, SourceComponent] of Object.entries(slots)) {
|
|
25
|
+
const Wrapper = forwardRef((props, ref) => createElement(SourceComponent, {
|
|
26
|
+
...props,
|
|
27
|
+
ref
|
|
28
|
+
}, props.children));
|
|
29
|
+
Wrapper.displayName = `${familyName}.${name}`;
|
|
30
|
+
result[name] = Wrapper;
|
|
31
|
+
}
|
|
32
|
+
if (!("Root" in result)) throw new Error("compose(): No \"Root\" slot found. The root slot key must be exactly \"Root\" (PascalCase).");
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { compose };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type ForwardRefExoticComponent } from 'react';
|
|
2
|
+
import type { AnyBrandedComponent, ComposedFamily, SharedConfig } from './types/component';
|
|
3
|
+
/**
|
|
4
|
+
* Compose components into a sealed family with shared variant propagation
|
|
5
|
+
* via React context. Use this when children may be rendered in portals
|
|
6
|
+
* or other React subtrees that escape the DOM hierarchy (where CSS
|
|
7
|
+
* descendant selectors cannot reach).
|
|
8
|
+
*
|
|
9
|
+
* This function uses `createContext` and `useContext` — it is client-only.
|
|
10
|
+
* For CSS-only propagation (RSC-safe), use `compose` from the barrel or
|
|
11
|
+
* `@animus-ui/system/compose`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function composeWithContext<Slots extends Record<string, AnyBrandedComponent>, const Shared extends SharedConfig<Slots>>(slots: Slots, options: {
|
|
14
|
+
shared: Shared;
|
|
15
|
+
name?: string;
|
|
16
|
+
}): ComposedFamily<Slots>;
|
|
17
|
+
/**
|
|
18
|
+
* createComposedFamilyWithContext — extraction-time replacement for composeWithContext().
|
|
19
|
+
*
|
|
20
|
+
* The transform emitter replaces `composeWithContext({ Root, Body }, { shared, name })`
|
|
21
|
+
* with `createComposedFamilyWithContext({ Root, Body }, { name, sharedKeys })`.
|
|
22
|
+
*
|
|
23
|
+
* Client-only: uses createContext and useContext. Files containing this function
|
|
24
|
+
* receive a 'use client' directive from the transform emitter.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createComposedFamilyWithContext(slots: Record<string, ForwardRefExoticComponent<any>>, config: {
|
|
27
|
+
name: string;
|
|
28
|
+
sharedKeys: string[];
|
|
29
|
+
}): Record<string, ForwardRefExoticComponent<any>>;
|
|
30
|
+
//# sourceMappingURL=composeWithContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composeWithContext.d.ts","sourceRoot":"","sources":["../src/composeWithContext.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,yBAAyB,EAI/B,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,YAAY,EACb,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,EACjD,KAAK,CAAC,MAAM,SAAS,YAAY,CAAC,KAAK,CAAC,EAExC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACzC,cAAc,CAAC,KAAK,CAAC,CA8CvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,GAAG,CAAC,CAAC,EACrD,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,GAC7C,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,GAAG,CAAC,CAAC,CAqChD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, createElement, forwardRef, useContext } from "react";
|
|
3
|
+
//#region src/composeWithContext.ts
|
|
4
|
+
/**
|
|
5
|
+
* Compose components into a sealed family with shared variant propagation
|
|
6
|
+
* via React context. Use this when children may be rendered in portals
|
|
7
|
+
* or other React subtrees that escape the DOM hierarchy (where CSS
|
|
8
|
+
* descendant selectors cannot reach).
|
|
9
|
+
*
|
|
10
|
+
* This function uses `createContext` and `useContext` — it is client-only.
|
|
11
|
+
* For CSS-only propagation (RSC-safe), use `compose` from the barrel or
|
|
12
|
+
* `@animus-ui/system/compose`.
|
|
13
|
+
*/
|
|
14
|
+
function composeWithContext(slots, options) {
|
|
15
|
+
const familyName = options.name ?? "Composed";
|
|
16
|
+
const sharedKeySet = new Set(Object.keys(options.shared));
|
|
17
|
+
const FamilyCtx = createContext({});
|
|
18
|
+
const result = {};
|
|
19
|
+
for (const [name, SourceComponent] of Object.entries(slots)) {
|
|
20
|
+
let Wrapper;
|
|
21
|
+
if (name === "Root") Wrapper = forwardRef((props, ref) => {
|
|
22
|
+
const shared = {};
|
|
23
|
+
for (const key of sharedKeySet) if (key in props) shared[key] = props[key];
|
|
24
|
+
return createElement(SourceComponent, {
|
|
25
|
+
...props,
|
|
26
|
+
ref
|
|
27
|
+
}, createElement(FamilyCtx.Provider, { value: shared }, props.children));
|
|
28
|
+
});
|
|
29
|
+
else Wrapper = forwardRef((props, ref) => {
|
|
30
|
+
return createElement(SourceComponent, {
|
|
31
|
+
...useContext(FamilyCtx),
|
|
32
|
+
...props,
|
|
33
|
+
ref
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
Wrapper.displayName = `${familyName}.${name}`;
|
|
37
|
+
result[name] = Wrapper;
|
|
38
|
+
}
|
|
39
|
+
if (!("Root" in result)) throw new Error("composeWithContext(): No \"Root\" slot found. The root slot key must be exactly \"Root\" (PascalCase).");
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* createComposedFamilyWithContext — extraction-time replacement for composeWithContext().
|
|
44
|
+
*
|
|
45
|
+
* The transform emitter replaces `composeWithContext({ Root, Body }, { shared, name })`
|
|
46
|
+
* with `createComposedFamilyWithContext({ Root, Body }, { name, sharedKeys })`.
|
|
47
|
+
*
|
|
48
|
+
* Client-only: uses createContext and useContext. Files containing this function
|
|
49
|
+
* receive a 'use client' directive from the transform emitter.
|
|
50
|
+
*/
|
|
51
|
+
function createComposedFamilyWithContext(slots, config) {
|
|
52
|
+
const { name, sharedKeys } = config;
|
|
53
|
+
const Ctx = createContext({});
|
|
54
|
+
const keySet = new Set(sharedKeys);
|
|
55
|
+
const result = {};
|
|
56
|
+
for (const [slotName, SourceComponent] of Object.entries(slots)) {
|
|
57
|
+
let Wrapper;
|
|
58
|
+
if (slotName === "Root") Wrapper = forwardRef((props, ref) => {
|
|
59
|
+
const shared = {};
|
|
60
|
+
for (const key of keySet) if (key in props) shared[key] = props[key];
|
|
61
|
+
return createElement(SourceComponent, {
|
|
62
|
+
...props,
|
|
63
|
+
ref
|
|
64
|
+
}, createElement(Ctx.Provider, { value: shared }, props.children));
|
|
65
|
+
});
|
|
66
|
+
else Wrapper = forwardRef((props, ref) => {
|
|
67
|
+
return createElement(SourceComponent, {
|
|
68
|
+
...useContext(Ctx),
|
|
69
|
+
...props,
|
|
70
|
+
ref
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
Wrapper.displayName = `${name}.${slotName}`;
|
|
74
|
+
result[slotName] = Wrapper;
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
//#endregion
|
|
79
|
+
export { composeWithContext, createComposedFamilyWithContext };
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { Children, cloneElement, createElement, forwardRef, isValidElement } from "react";
|
|
2
|
+
import { UNITLESS_PROPERTIES } from "@animus-ui/properties";
|
|
3
|
+
//#region src/runtime/resolveClasses.ts
|
|
4
|
+
/**
|
|
5
|
+
* Apply unit fallback to a value for a given CSS property.
|
|
6
|
+
*/
|
|
7
|
+
function applyUnitFallback(value, cssProperty) {
|
|
8
|
+
if (typeof value === "number") {
|
|
9
|
+
if (UNITLESS_PROPERTIES.has(cssProperty)) return String(value);
|
|
10
|
+
return `${value}px`;
|
|
11
|
+
}
|
|
12
|
+
return String(value);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Serialize a system prop value to a lookup key matching the Rust
|
|
16
|
+
* css_generator's serialize_value_key output format.
|
|
17
|
+
*/
|
|
18
|
+
function serializeValueKey(value) {
|
|
19
|
+
if (typeof value === "number" || typeof value === "string") return String(value);
|
|
20
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) return Object.keys(value).sort().map((k) => `${k}:${value[k]}`).join("|");
|
|
21
|
+
return String(value);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a dynamic prop value through scale lookup → transform → unit fallback.
|
|
25
|
+
*/
|
|
26
|
+
function resolveValue(value, dc) {
|
|
27
|
+
const key = String(value);
|
|
28
|
+
const scaleResolved = dc.scaleValues?.[key];
|
|
29
|
+
if (scaleResolved != null) {
|
|
30
|
+
const transformed = dc.transform ? dc.transform(scaleResolved) : scaleResolved;
|
|
31
|
+
return String(transformed);
|
|
32
|
+
}
|
|
33
|
+
return applyUnitFallback(dc.transform ? dc.transform(value) : value, dc.varName);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve className parts from props, using extracted configuration.
|
|
37
|
+
* This is the shared logic between createComponent and createClassResolver.
|
|
38
|
+
*/
|
|
39
|
+
function resolveClasses(baseClassName, props, config, systemPropMap, dynamicPropConfig) {
|
|
40
|
+
const classes = [baseClassName];
|
|
41
|
+
let dynStyle;
|
|
42
|
+
if (config.variants) for (const [prop, vc] of Object.entries(config.variants)) {
|
|
43
|
+
const value = props[prop] ?? vc.default;
|
|
44
|
+
if (value != null) {
|
|
45
|
+
const isDefault = !(prop in props) && vc.default != null;
|
|
46
|
+
classes.push(`${baseClassName}--${prop}-${isDefault ? "default" : value}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (config.compounds) for (const compound of config.compounds) {
|
|
50
|
+
let match = true;
|
|
51
|
+
for (const [prop, expected] of Object.entries(compound.conditions)) {
|
|
52
|
+
const current = props[prop] ?? config.variants?.[prop]?.default;
|
|
53
|
+
if (Array.isArray(expected) ? !expected.includes(current) : current !== expected) {
|
|
54
|
+
match = false;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (match) classes.push(compound.className);
|
|
59
|
+
}
|
|
60
|
+
const activeStates = [];
|
|
61
|
+
if (config.states) {
|
|
62
|
+
for (const state of config.states) if (props[state]) {
|
|
63
|
+
classes.push(`${baseClassName}--${state}`);
|
|
64
|
+
activeStates.push(state);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const systemPropNames = config.systemPropNames || [];
|
|
68
|
+
if (systemPropNames.length > 0) {
|
|
69
|
+
const { customPropMap, customDynamicConfig } = config;
|
|
70
|
+
for (const propName of systemPropNames) {
|
|
71
|
+
if (!(propName in props)) continue;
|
|
72
|
+
const propValue = props[propName];
|
|
73
|
+
if (propValue == null) continue;
|
|
74
|
+
const key = serializeValueKey(propValue);
|
|
75
|
+
const cls = customPropMap?.[propName]?.[key] ?? systemPropMap?.[propName]?.[key];
|
|
76
|
+
if (cls) classes.push(cls);
|
|
77
|
+
else {
|
|
78
|
+
const dc = customDynamicConfig?.[propName] ?? dynamicPropConfig?.[propName];
|
|
79
|
+
if (dc) {
|
|
80
|
+
if (!dynStyle) dynStyle = {};
|
|
81
|
+
if (typeof propValue === "object" && propValue !== null && !Array.isArray(propValue)) for (const [bp, bpVal] of Object.entries(propValue)) {
|
|
82
|
+
if (bpVal == null) continue;
|
|
83
|
+
if (bp === "_") {
|
|
84
|
+
classes.push(dc.slotClass);
|
|
85
|
+
const finalVal = resolveValue(bpVal, dc);
|
|
86
|
+
dynStyle[dc.varName] = finalVal;
|
|
87
|
+
} else {
|
|
88
|
+
classes.push(`${dc.slotClass}-${bp}`);
|
|
89
|
+
const varName = `${dc.varName}-${bp}`;
|
|
90
|
+
const finalVal = resolveValue(bpVal, dc);
|
|
91
|
+
dynStyle[varName] = finalVal;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
classes.push(dc.slotClass);
|
|
96
|
+
const finalVal = resolveValue(propValue, dc);
|
|
97
|
+
dynStyle[dc.varName] = finalVal;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
classes,
|
|
105
|
+
dynamicStyle: dynStyle,
|
|
106
|
+
activeStates
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/runtime/index.ts
|
|
111
|
+
/**
|
|
112
|
+
* Merge multiple refs (callback or object) into a single callback ref.
|
|
113
|
+
* Creates a new callback on each call — no memoization possible in a
|
|
114
|
+
* hook-free runtime (RSC compatibility). Matches @radix-ui/react-compose-refs.
|
|
115
|
+
*/
|
|
116
|
+
function composeRefs(...refs) {
|
|
117
|
+
return (node) => {
|
|
118
|
+
for (const ref of refs) if (typeof ref === "function") ref(node);
|
|
119
|
+
else if (ref) ref.current = node;
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Create a lightweight component that applies extracted CSS class names.
|
|
124
|
+
* Replaces Emotion's styled() for extracted components.
|
|
125
|
+
*
|
|
126
|
+
* The element parameter accepts either an HTML tag string (e.g. 'button') or
|
|
127
|
+
* a React component reference (e.g. NextLink). When a component reference is
|
|
128
|
+
* used, prop forwarding skips the HTML-attribute validity check — all
|
|
129
|
+
* non-filtered props are forwarded to the component.
|
|
130
|
+
*
|
|
131
|
+
* The optional systemPropMap parameter provides the shared prop→value→className
|
|
132
|
+
* lookup table, served as a virtual module by the Vite plugin.
|
|
133
|
+
*
|
|
134
|
+
* The optional dynamicPropConfig parameter provides CSS variable fallback
|
|
135
|
+
* metadata for props with detected dynamic usage.
|
|
136
|
+
*/
|
|
137
|
+
function createComponent(element, className, config, systemPropMap, dynamicPropConfig) {
|
|
138
|
+
const variantProps = config.variants ? Object.keys(config.variants) : [];
|
|
139
|
+
const stateProps = config.states || [];
|
|
140
|
+
const systemPropNames = config.systemPropNames || [];
|
|
141
|
+
const filterProps = new Set([
|
|
142
|
+
"as",
|
|
143
|
+
"asChild",
|
|
144
|
+
...variantProps,
|
|
145
|
+
...stateProps,
|
|
146
|
+
...systemPropNames
|
|
147
|
+
]);
|
|
148
|
+
const Component = forwardRef((props, ref) => {
|
|
149
|
+
const { classes, dynamicStyle } = resolveClasses(className, props, config, systemPropMap, dynamicPropConfig);
|
|
150
|
+
if (props.className) classes.push(props.className);
|
|
151
|
+
if (props.asChild) {
|
|
152
|
+
const child = Children.only(props.children);
|
|
153
|
+
if (!isValidElement(child)) throw new Error(`${className}: asChild requires a single React element as children`);
|
|
154
|
+
const childRef = child.ref;
|
|
155
|
+
const mergedClassName = [classes.join(" "), child.props.className].filter(Boolean).join(" ");
|
|
156
|
+
const mergedStyle = dynamicStyle || props.style || child.props.style ? {
|
|
157
|
+
...props.style,
|
|
158
|
+
...child.props.style,
|
|
159
|
+
...dynamicStyle
|
|
160
|
+
} : void 0;
|
|
161
|
+
return cloneElement(child, {
|
|
162
|
+
ref: composeRefs(ref, childRef),
|
|
163
|
+
className: mergedClassName,
|
|
164
|
+
...mergedStyle ? { style: mergedStyle } : {}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
const renderElement = props.as || element;
|
|
168
|
+
const isComponentElement = typeof renderElement !== "string";
|
|
169
|
+
const domProps = {
|
|
170
|
+
ref,
|
|
171
|
+
className: classes.join(" ")
|
|
172
|
+
};
|
|
173
|
+
for (const [key, value] of Object.entries(props)) {
|
|
174
|
+
if (key === "className") continue;
|
|
175
|
+
if (!(key.startsWith("data-") || key.startsWith("aria-")) && filterProps.has(key)) continue;
|
|
176
|
+
if (!isComponentElement) {}
|
|
177
|
+
domProps[key] = value;
|
|
178
|
+
}
|
|
179
|
+
if (dynamicStyle) domProps.style = props.style ? {
|
|
180
|
+
...props.style,
|
|
181
|
+
...dynamicStyle
|
|
182
|
+
} : dynamicStyle;
|
|
183
|
+
return createElement(renderElement, domProps);
|
|
184
|
+
});
|
|
185
|
+
Component.displayName = className;
|
|
186
|
+
return Object.assign(Component, { extend: () => {
|
|
187
|
+
throw new Error(`Cannot extend extracted component "${className}" at runtime. Extensions must be authored in source code using the builder API (e.g. import the original component and call .extend() there) so the extraction pipeline can resolve them at build time.`);
|
|
188
|
+
} });
|
|
189
|
+
}
|
|
190
|
+
//#endregion
|
|
191
|
+
//#region src/runtime/createClassResolver.ts
|
|
192
|
+
/**
|
|
193
|
+
* createClassResolver — framework-agnostic className resolution.
|
|
194
|
+
*
|
|
195
|
+
* Produced by .asClass() terminal. Same resolution logic as createComponent
|
|
196
|
+
* (variants, states, compounds, system props) but returns a className string
|
|
197
|
+
* instead of a React element.
|
|
198
|
+
*/
|
|
199
|
+
function createClassResolver(className, config, systemPropMap, dynamicPropConfig) {
|
|
200
|
+
return (props) => {
|
|
201
|
+
const { classes } = resolveClasses(className, props || {}, config, systemPropMap, dynamicPropConfig);
|
|
202
|
+
return classes.join(" ");
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
//#endregion
|
|
206
|
+
//#region src/runtime/createComposedFamily.ts
|
|
207
|
+
/**
|
|
208
|
+
* createComposedFamily — extraction-time replacement for compose().
|
|
209
|
+
*
|
|
210
|
+
* The transform emitter replaces `compose({ Root, Body }, { shared, name })`
|
|
211
|
+
* with `createComposedFamily({ Root, Body }, { name })`.
|
|
212
|
+
*
|
|
213
|
+
* RSC-safe: uses only forwardRef and createElement — no createContext,
|
|
214
|
+
* no useContext, no hooks.
|
|
215
|
+
*/
|
|
216
|
+
function createComposedFamily(slots, config) {
|
|
217
|
+
const { name } = config;
|
|
218
|
+
const result = {};
|
|
219
|
+
for (const [slotName, SourceComponent] of Object.entries(slots)) {
|
|
220
|
+
const Wrapper = forwardRef((props, ref) => createElement(SourceComponent, {
|
|
221
|
+
...props,
|
|
222
|
+
ref
|
|
223
|
+
}, props.children));
|
|
224
|
+
Wrapper.displayName = `${name}.${slotName}`;
|
|
225
|
+
result[slotName] = Wrapper;
|
|
226
|
+
}
|
|
227
|
+
return result;
|
|
228
|
+
}
|
|
229
|
+
//#endregion
|
|
230
|
+
export { createClassResolver as n, createComponent as r, createComposedFamily as t };
|