@zeus-js/output-react-wrapper 0.1.0-beta.3 → 0.1.0-beta.5
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/output-react-wrapper.cjs.js +294 -141
- package/dist/output-react-wrapper.cjs.prod.js +294 -141
- package/dist/output-react-wrapper.d.ts +44 -2
- package/dist/output-react-wrapper.esm-bundler.js +294 -142
- package/dist/runtime/index.cjs.js +57 -0
- package/dist/runtime/index.cjs.prod.js +57 -0
- package/dist/runtime/index.d.ts +39 -0
- package/dist/runtime/index.js +53 -0
- package/dist/runtime/index.prod.js +53 -0
- package/package.json +20 -4
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* output-react-wrapper v0.1.0-beta.
|
|
2
|
+
* output-react-wrapper v0.1.0-beta.5
|
|
3
3
|
* (c) 2026 baicie
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
**/
|
|
6
6
|
import { resolvePluginDts } from "@zeus-js/bundler-plugin";
|
|
7
7
|
import { generateReactDts } from "@zeus-js/component-dts";
|
|
8
|
+
import { createComponent as createComponent$1 } from "@lit/react";
|
|
8
9
|
//#region packages/web-c/output-react-wrapper/src/generateReactIndex.ts
|
|
9
10
|
function generateReactIndex(components, options) {
|
|
10
11
|
const lines = [];
|
|
@@ -16,211 +17,362 @@ function generateReactIndex(components, options) {
|
|
|
16
17
|
return lines.join("\n");
|
|
17
18
|
}
|
|
18
19
|
//#endregion
|
|
19
|
-
//#region packages/web-c/output-react-wrapper/src/naming.ts
|
|
20
|
-
function toReactEventProp(eventName) {
|
|
21
|
-
return "on" + eventName.split("-").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
22
|
-
}
|
|
23
|
-
//#endregion
|
|
24
20
|
//#region packages/web-c/output-react-wrapper/src/generateReactWrapper.ts
|
|
25
21
|
function generateReactWrapper(input) {
|
|
26
|
-
|
|
27
|
-
if (mode === "minimal") return generateMinimalReactWrapper(input);
|
|
28
|
-
return generateEventBridgeReactWrapper(input);
|
|
29
|
-
}
|
|
30
|
-
function createBindings(names, prefix) {
|
|
31
|
-
return names.map((sourceName, index) => ({
|
|
32
|
-
sourceName,
|
|
33
|
-
localName: `${prefix}${index}`
|
|
34
|
-
}));
|
|
35
|
-
}
|
|
36
|
-
function createEventBindings(eventNames) {
|
|
37
|
-
return eventNames.map((eventName, index) => ({
|
|
38
|
-
eventName,
|
|
39
|
-
sourceName: toReactEventProp(eventName),
|
|
40
|
-
localName: `eventHandler${index}`
|
|
41
|
-
}));
|
|
42
|
-
}
|
|
43
|
-
function generateDestructuredBindings(bindings) {
|
|
44
|
-
if (!bindings.length) return "";
|
|
45
|
-
return bindings.map(({ sourceName, localName }) => {
|
|
46
|
-
return `${JSON.stringify(sourceName)}: ${localName},`;
|
|
47
|
-
}).join("\n ");
|
|
22
|
+
return input.mode === "runtime" ? generateRuntimeReactWrapper(input) : input.mode === "event-bridge" ? generateEventBridgeReactWrapper(input) : generateMinimalReactWrapper(input);
|
|
48
23
|
}
|
|
49
24
|
function generateMinimalReactWrapper(input) {
|
|
50
25
|
const { component, namedSlots, wcModuleId } = input;
|
|
51
26
|
const slotBindings = createBindings(getNamedSlots(component, namedSlots), "slotValue");
|
|
52
|
-
const
|
|
27
|
+
const omittedKeys = ["children", ...slotBindings.map(({ sourceName }) => sourceName)];
|
|
28
|
+
const slotAssignments = generatePropAssignments(slotBindings);
|
|
53
29
|
const namedSlotLines = generateMinimalNamedSlots(slotBindings);
|
|
30
|
+
const childSetup = slotBindings.length ? `${namedSlotLines}
|
|
31
|
+
const childArgs = [];
|
|
32
|
+
pushAll(childArgs, slotNodes);
|
|
33
|
+
if (children != null) childArgs.push(children);` : "";
|
|
34
|
+
const render = slotBindings.length ? `React.createElement.apply(
|
|
35
|
+
React,
|
|
36
|
+
[${JSON.stringify(component.tag)}, rest].concat(childArgs),
|
|
37
|
+
)` : `React.createElement(${JSON.stringify(component.tag)}, rest, children)`;
|
|
54
38
|
return `
|
|
55
39
|
import * as React from 'react';
|
|
56
40
|
|
|
57
41
|
import ${JSON.stringify(wcModuleId)};
|
|
58
42
|
|
|
43
|
+
const OMITTED_PROPS = new Set(${JSON.stringify(omittedKeys)});
|
|
44
|
+
|
|
59
45
|
export const ${component.name} = React.forwardRef(
|
|
60
|
-
function ${component.name}({
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
ref,
|
|
70
|
-
},
|
|
71
|
-
${namedSlotLines ? " ...slotNodes,\n" : ""} children,
|
|
72
|
-
);
|
|
46
|
+
function ${component.name}(inputProps, ref) {
|
|
47
|
+
const props = inputProps || {};
|
|
48
|
+
const children = props.children;
|
|
49
|
+
${slotAssignments}
|
|
50
|
+
const rest = omitProps(props);
|
|
51
|
+
rest.ref = ref;
|
|
52
|
+
${childSetup}
|
|
53
|
+
|
|
54
|
+
return ${render};
|
|
73
55
|
},
|
|
74
56
|
);
|
|
57
|
+
|
|
58
|
+
function omitProps(source) {
|
|
59
|
+
const output = {};
|
|
60
|
+
for (const key in source) {
|
|
61
|
+
if (hasOwn(source, key) && !OMITTED_PROPS.has(key)) {
|
|
62
|
+
output[key] = source[key];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return output;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function hasOwn(source, key) {
|
|
69
|
+
return Object.prototype.hasOwnProperty.call(source, key);
|
|
70
|
+
}
|
|
71
|
+
${slotBindings.length ? PUSH_ALL_HELPER : ""}
|
|
75
72
|
`.trimStart();
|
|
76
73
|
}
|
|
77
74
|
function generateEventBridgeReactWrapper(input) {
|
|
78
75
|
const { component, namedSlots, wcModuleId } = input;
|
|
79
76
|
const propBindings = createBindings(Object.keys(component.props), "propValue");
|
|
80
|
-
const eventBindings = createEventBindings(
|
|
77
|
+
const eventBindings = createEventBindings(component.events);
|
|
78
|
+
if (!propBindings.length && !eventBindings.length) return generateMinimalReactWrapper(input);
|
|
81
79
|
const slotBindings = createBindings(getNamedSlots(component, namedSlots), "slotValue");
|
|
82
|
-
const
|
|
80
|
+
const destructuredBindings = [
|
|
83
81
|
...propBindings,
|
|
84
82
|
...eventBindings,
|
|
85
83
|
...slotBindings
|
|
86
|
-
]
|
|
84
|
+
];
|
|
85
|
+
const omittedKeys = [
|
|
86
|
+
"children",
|
|
87
|
+
"className",
|
|
88
|
+
"style",
|
|
89
|
+
...destructuredBindings.map(({ sourceName }) => sourceName)
|
|
90
|
+
];
|
|
87
91
|
return `
|
|
88
92
|
import {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
${[
|
|
94
|
+
"createElement",
|
|
95
|
+
...slotBindings.length ? [
|
|
96
|
+
"cloneElement",
|
|
97
|
+
"Fragment",
|
|
98
|
+
"isValidElement"
|
|
99
|
+
] : [],
|
|
100
|
+
"forwardRef",
|
|
101
|
+
...propBindings.length || eventBindings.length ? ["useEffect"] : [],
|
|
102
|
+
"useImperativeHandle",
|
|
103
|
+
"useRef"
|
|
104
|
+
].join(",\n ")},
|
|
97
105
|
} from 'react';
|
|
98
106
|
|
|
99
107
|
import ${JSON.stringify(wcModuleId)};
|
|
100
108
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
children,
|
|
104
|
-
className,
|
|
105
|
-
style,
|
|
106
|
-
${destructuredProps}
|
|
107
|
-
...rest
|
|
108
|
-
} = props;
|
|
109
|
-
|
|
110
|
-
const innerRef = useRef(null);
|
|
111
|
-
const previousPropKeysRef = useRef(new Set());
|
|
112
|
-
|
|
113
|
-
useImperativeHandle(ref, () => innerRef.current);
|
|
114
|
-
|
|
115
|
-
${generatePropSyncLines(propBindings)}
|
|
116
|
-
|
|
117
|
-
${generateEventEffects(eventBindings)}
|
|
109
|
+
const OMITTED_PROPS = new Set(${JSON.stringify(omittedKeys)});
|
|
110
|
+
${eventBindings.length ? `const EVENT_NAMES = ${JSON.stringify(eventBindings.map((binding) => binding.eventName))};` : ""}
|
|
118
111
|
|
|
119
|
-
|
|
112
|
+
export const ${component.name} = forwardRef(function ${component.name}(inputProps, ref) {
|
|
113
|
+
const props = inputProps || {};
|
|
114
|
+
const children = props.children;
|
|
115
|
+
const className = props.className;
|
|
116
|
+
const style = props.style;
|
|
117
|
+
${generatePropAssignments(destructuredBindings)}
|
|
118
|
+
${generatePropPresenceAssignments(propBindings)}
|
|
119
|
+
const rest = omitProps(props);
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
const innerRef = useRef(null);
|
|
122
|
+
${generatePropRefs(propBindings)}
|
|
123
|
+
${generateEventRefs(eventBindings)}
|
|
124
|
+
useImperativeHandle(ref, () => innerRef.current, []);
|
|
122
125
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
+
${generatePropSyncEffect(propBindings)}
|
|
127
|
+
${generateEventEffect(eventBindings)}
|
|
128
|
+
${generateChildrenSetup(slotBindings)}
|
|
129
|
+
rest.ref = innerRef;
|
|
130
|
+
rest.className = className;
|
|
131
|
+
rest.style = style;
|
|
126
132
|
|
|
127
|
-
return
|
|
128
|
-
${JSON.stringify(component.tag)},
|
|
129
|
-
{
|
|
130
|
-
...rest,
|
|
131
|
-
ref: innerRef,
|
|
132
|
-
className,
|
|
133
|
-
style,
|
|
134
|
-
},
|
|
135
|
-
...slotChildren,
|
|
136
|
-
);
|
|
133
|
+
return ${generateReactRender(component.tag, slotBindings)};
|
|
137
134
|
});
|
|
138
|
-
|
|
139
|
-
function
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
) {
|
|
146
|
-
return cloneElement(value, { slot: name });
|
|
135
|
+
${slotBindings.length ? NAMED_SLOT_HELPER : ""}
|
|
136
|
+
function omitProps(source) {
|
|
137
|
+
const output = {};
|
|
138
|
+
for (const key in source) {
|
|
139
|
+
if (hasOwn(source, key) && !OMITTED_PROPS.has(key)) {
|
|
140
|
+
output[key] = source[key];
|
|
141
|
+
}
|
|
147
142
|
}
|
|
143
|
+
return output;
|
|
144
|
+
}
|
|
148
145
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
{
|
|
152
|
-
slot: name,
|
|
153
|
-
style: { display: 'contents' },
|
|
154
|
-
},
|
|
155
|
-
value,
|
|
156
|
-
);
|
|
146
|
+
function hasOwn(source, key) {
|
|
147
|
+
return Object.prototype.hasOwnProperty.call(source, key);
|
|
157
148
|
}
|
|
158
149
|
`.trimStart();
|
|
159
150
|
}
|
|
160
|
-
function
|
|
161
|
-
|
|
162
|
-
|
|
151
|
+
function createBindings(names, prefix) {
|
|
152
|
+
return names.map((sourceName, index) => ({
|
|
153
|
+
sourceName,
|
|
154
|
+
localName: `${prefix}${index}`
|
|
155
|
+
}));
|
|
156
|
+
}
|
|
157
|
+
function createEventBindings(events) {
|
|
158
|
+
return Object.entries(events).map(([key, event], index) => {
|
|
159
|
+
var _event$key, _event$name, _event$reactName;
|
|
160
|
+
const sourceEventName = (_event$key = event.key) !== null && _event$key !== void 0 ? _event$key : key;
|
|
161
|
+
return {
|
|
162
|
+
eventName: (_event$name = event.name) !== null && _event$name !== void 0 ? _event$name : toKebabCase(sourceEventName),
|
|
163
|
+
sourceName: (_event$reactName = event.reactName) !== null && _event$reactName !== void 0 ? _event$reactName : toReactEventProp(sourceEventName),
|
|
164
|
+
localName: `eventHandler${index}`
|
|
165
|
+
};
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function generatePropAssignments(bindings) {
|
|
169
|
+
return bindings.map(({ sourceName, localName }) => ` const ${localName} = props[${JSON.stringify(sourceName)}];`).join("\n");
|
|
170
|
+
}
|
|
171
|
+
function generatePropPresenceAssignments(bindings) {
|
|
172
|
+
return bindings.map(({ sourceName }, index) => ` const propPresent${index} = hasOwn(props, ${JSON.stringify(sourceName)});`).join("\n");
|
|
173
|
+
}
|
|
174
|
+
function generatePropRefs(bindings) {
|
|
175
|
+
if (!bindings.length) return "";
|
|
176
|
+
return ` const previousPropPresenceRef = useRef([]);
|
|
177
|
+
const previousPropValuesRef = useRef([]);`;
|
|
178
|
+
}
|
|
179
|
+
function generateEventRefs(bindings) {
|
|
180
|
+
if (!bindings.length) return "";
|
|
181
|
+
return ` const eventHandlersRef = useRef([]);
|
|
182
|
+
${bindings.map(({ localName }, index) => ` eventHandlersRef.current[${index}] = ${localName};`).join("\n")}`;
|
|
183
|
+
}
|
|
184
|
+
function generatePropSyncEffect(bindings) {
|
|
185
|
+
if (!bindings.length) return "";
|
|
186
|
+
return ` useEffect(() => {
|
|
163
187
|
const el = innerRef.current;
|
|
164
188
|
if (!el) return;
|
|
165
189
|
|
|
166
|
-
const
|
|
190
|
+
const previousPropPresence = previousPropPresenceRef.current;
|
|
191
|
+
const previousPropValues = previousPropValuesRef.current;
|
|
167
192
|
|
|
168
|
-
|
|
193
|
+
${bindings.map(({ sourceName, localName }, index) => {
|
|
169
194
|
const key = JSON.stringify(sourceName);
|
|
170
|
-
return `if (
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
195
|
+
return ` if (propPresent${index}) {
|
|
196
|
+
if (
|
|
197
|
+
!previousPropPresence[${index}] ||
|
|
198
|
+
!Object.is(previousPropValues[${index}], ${localName})
|
|
199
|
+
) {
|
|
200
|
+
el[${key}] = ${localName};
|
|
201
|
+
previousPropValues[${index}] = ${localName};
|
|
202
|
+
}
|
|
203
|
+
previousPropPresence[${index}] = true;
|
|
204
|
+
} else if (previousPropPresence[${index}]) {
|
|
174
205
|
el[${key}] = undefined;
|
|
175
|
-
|
|
206
|
+
previousPropPresence[${index}] = false;
|
|
207
|
+
previousPropValues[${index}] = undefined;
|
|
176
208
|
}`;
|
|
177
|
-
}).join("\n\n
|
|
178
|
-
}, [
|
|
209
|
+
}).join("\n\n")}
|
|
210
|
+
}, [${bindings.flatMap((binding, index) => [`propPresent${index}`, binding.localName]).join(", ")}]);
|
|
211
|
+
`;
|
|
179
212
|
}
|
|
180
|
-
function
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
useEffect(() => {
|
|
213
|
+
function generateEventEffect(bindings) {
|
|
214
|
+
if (!bindings.length) return "";
|
|
215
|
+
return ` useEffect(() => {
|
|
184
216
|
const el = innerRef.current;
|
|
185
|
-
if (!el
|
|
217
|
+
if (!el) return;
|
|
186
218
|
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
219
|
+
const listeners = EVENT_NAMES.map(
|
|
220
|
+
(_eventName, index) => event => {
|
|
221
|
+
const handler = eventHandlersRef.current[index];
|
|
222
|
+
if (handler) handler(event);
|
|
223
|
+
},
|
|
224
|
+
);
|
|
190
225
|
|
|
191
|
-
|
|
226
|
+
for (let index = 0; index < EVENT_NAMES.length; index += 1) {
|
|
227
|
+
el.addEventListener(EVENT_NAMES[index], listeners[index]);
|
|
228
|
+
}
|
|
192
229
|
|
|
193
230
|
return () => {
|
|
194
|
-
|
|
231
|
+
for (let index = 0; index < EVENT_NAMES.length; index += 1) {
|
|
232
|
+
el.removeEventListener(EVENT_NAMES[index], listeners[index]);
|
|
233
|
+
}
|
|
195
234
|
};
|
|
196
|
-
}, [
|
|
235
|
+
}, []);
|
|
197
236
|
`;
|
|
198
|
-
}).join("");
|
|
199
|
-
}
|
|
200
|
-
function getNamedSlots(component, namedSlots) {
|
|
201
|
-
if (namedSlots === "none") return [];
|
|
202
|
-
return Object.keys(component.slots).filter((name) => name !== "default");
|
|
203
237
|
}
|
|
204
|
-
function
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
{
|
|
238
|
+
function generateChildrenSetup(bindings) {
|
|
239
|
+
if (!bindings.length) return "";
|
|
240
|
+
return ` const slotChildren = [];
|
|
241
|
+
${bindings.map(({ sourceName, localName }) => ` {
|
|
208
242
|
const node = createNamedSlot(${JSON.stringify(sourceName)}, ${localName});
|
|
209
243
|
if (node != null) slotChildren.push(node);
|
|
210
|
-
}
|
|
244
|
+
}`).join("\n")}
|
|
245
|
+
if (children != null) slotChildren.push(children);
|
|
211
246
|
`;
|
|
212
|
-
|
|
247
|
+
}
|
|
248
|
+
function generateReactRender(tag, slotBindings) {
|
|
249
|
+
if (!slotBindings.length) return `createElement(${JSON.stringify(tag)}, rest, children)`;
|
|
250
|
+
return `createElement.apply(
|
|
251
|
+
null,
|
|
252
|
+
[${JSON.stringify(tag)}, rest].concat(slotChildren),
|
|
253
|
+
)`;
|
|
254
|
+
}
|
|
255
|
+
function getNamedSlots(component, namedSlots) {
|
|
256
|
+
return namedSlots === "none" ? [] : Object.keys(component.slots).filter((name) => name !== "default");
|
|
213
257
|
}
|
|
214
258
|
function generateMinimalNamedSlots(bindings) {
|
|
215
259
|
if (!bindings.length) return "";
|
|
216
|
-
return bindings.map(({ sourceName, localName }, index) => {
|
|
217
|
-
return ` const
|
|
260
|
+
return `${bindings.map(({ sourceName, localName }, index) => {
|
|
261
|
+
return ` const slotNode${index} = ${localName} != null && ${localName} !== false
|
|
218
262
|
? (React.isValidElement(${localName}) && ${localName}.type !== React.Fragment
|
|
219
263
|
? React.cloneElement(${localName}, { slot: ${JSON.stringify(sourceName)} })
|
|
220
264
|
: React.createElement('span', { slot: ${JSON.stringify(sourceName)}, style: { display: 'contents' } }, ${localName}))
|
|
221
|
-
: null
|
|
265
|
+
: null;`;
|
|
266
|
+
}).join("\n")}
|
|
267
|
+
const slotNodes = [${bindings.map((_, index) => `slotNode${index}`).join(", ")}].filter(Boolean);`;
|
|
268
|
+
}
|
|
269
|
+
function toKebabCase(value) {
|
|
270
|
+
return value.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
271
|
+
}
|
|
272
|
+
function toReactEventProp(value) {
|
|
273
|
+
return `on${value.split("-").filter(Boolean).map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`).join("")}`;
|
|
274
|
+
}
|
|
275
|
+
function generateRuntimeReactWrapper(input) {
|
|
276
|
+
const { component, namedSlots } = input;
|
|
277
|
+
const events = createRuntimeEventMap(component);
|
|
278
|
+
const slots = getNamedSlots(component, namedSlots);
|
|
279
|
+
return [
|
|
280
|
+
`import React from 'react'`,
|
|
281
|
+
`import { createComponent } from '@zeus-js/output-react-wrapper/runtime'`,
|
|
282
|
+
`import { defineCustomElement } from '../wc/loader.js'`,
|
|
283
|
+
``,
|
|
284
|
+
`export const ${component.name} = createComponent({`,
|
|
285
|
+
` react: React,`,
|
|
286
|
+
` tagName: ${JSON.stringify(component.tag)},`,
|
|
287
|
+
` defineCustomElement: () => defineCustomElement(${JSON.stringify(component.tag)}),`,
|
|
288
|
+
` events: ${formatEventObject(events)},`,
|
|
289
|
+
` slots: ${JSON.stringify(slots)},`,
|
|
290
|
+
` displayName: ${JSON.stringify(component.name)},`,
|
|
291
|
+
`})`,
|
|
292
|
+
``
|
|
293
|
+
].join("\n");
|
|
294
|
+
}
|
|
295
|
+
function createRuntimeEventMap(component) {
|
|
296
|
+
const events = {};
|
|
297
|
+
for (const [key, event] of Object.entries(component.events)) {
|
|
298
|
+
var _event$key2, _event$name2, _event$reactName2;
|
|
299
|
+
const sourceEventName = (_event$key2 = event.key) !== null && _event$key2 !== void 0 ? _event$key2 : key;
|
|
300
|
+
const domEventName = (_event$name2 = event.name) !== null && _event$name2 !== void 0 ? _event$name2 : toKebabCase(sourceEventName);
|
|
301
|
+
const reactPropName = (_event$reactName2 = event.reactName) !== null && _event$reactName2 !== void 0 ? _event$reactName2 : toReactEventProp(sourceEventName);
|
|
302
|
+
events[reactPropName] = domEventName;
|
|
303
|
+
}
|
|
304
|
+
return events;
|
|
305
|
+
}
|
|
306
|
+
function formatEventObject(value) {
|
|
307
|
+
const entries = Object.entries(value);
|
|
308
|
+
if (!entries.length) return "{}";
|
|
309
|
+
return `{\n${entries.map(([key, item]) => ` ${JSON.stringify(key)}: ${JSON.stringify(item)}`).join(",\n")}\n }`;
|
|
310
|
+
}
|
|
311
|
+
const PUSH_ALL_HELPER = `
|
|
312
|
+
function pushAll(target, values) {
|
|
313
|
+
for (const value of values) target.push(value);
|
|
314
|
+
}
|
|
315
|
+
`;
|
|
316
|
+
const NAMED_SLOT_HELPER = `
|
|
317
|
+
function createNamedSlot(name, value) {
|
|
318
|
+
if (value == null || value === false) return null;
|
|
319
|
+
|
|
320
|
+
if (isValidElement(value) && value.type !== Fragment) {
|
|
321
|
+
return cloneElement(value, { slot: name });
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return createElement(
|
|
325
|
+
'span',
|
|
326
|
+
{ slot: name, style: { display: 'contents' } },
|
|
327
|
+
value,
|
|
328
|
+
);
|
|
329
|
+
}
|
|
222
330
|
`;
|
|
223
|
-
|
|
331
|
+
//#endregion
|
|
332
|
+
//#region packages/web-c/output-react-wrapper/src/runtime/createComponent.ts
|
|
333
|
+
function createComponent(options) {
|
|
334
|
+
var _customElements$get;
|
|
335
|
+
const { defineCustomElement, react, tagName, transformTag, elementClass, events = {}, slots = [], displayName } = options;
|
|
336
|
+
const finalTagName = transformTag ? transformTag(tagName) : tagName;
|
|
337
|
+
defineCustomElement === null || defineCustomElement === void 0 || defineCustomElement();
|
|
338
|
+
const LitComponent = createComponent$1({
|
|
339
|
+
react,
|
|
340
|
+
tagName: finalTagName,
|
|
341
|
+
elementClass: elementClass !== null && elementClass !== void 0 ? elementClass : typeof customElements === "undefined" ? HTMLElement : (_customElements$get = customElements.get(finalTagName)) !== null && _customElements$get !== void 0 ? _customElements$get : HTMLElement,
|
|
342
|
+
events,
|
|
343
|
+
displayName
|
|
344
|
+
});
|
|
345
|
+
if (!slots.length) return LitComponent;
|
|
346
|
+
const slotSet = new Set(slots);
|
|
347
|
+
return react.forwardRef((inputProps, ref) => {
|
|
348
|
+
const rest = {};
|
|
349
|
+
const slottedChildren = [];
|
|
350
|
+
if (inputProps == null) {
|
|
351
|
+
rest.ref = ref;
|
|
352
|
+
return react.createElement(LitComponent, rest);
|
|
353
|
+
}
|
|
354
|
+
const props = inputProps;
|
|
355
|
+
for (const key in props) {
|
|
356
|
+
if (!Object.prototype.hasOwnProperty.call(props, key)) continue;
|
|
357
|
+
const value = props[key];
|
|
358
|
+
if (slotSet.has(key)) {
|
|
359
|
+
const child = createNamedSlot(react, key, value);
|
|
360
|
+
if (child != null) slottedChildren.push(child);
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
rest[key] = value;
|
|
364
|
+
}
|
|
365
|
+
rest.ref = ref;
|
|
366
|
+
if (props.children != null) slottedChildren.push(props.children);
|
|
367
|
+
return react.createElement(LitComponent, rest, ...slottedChildren);
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
function createNamedSlot(react, name, value) {
|
|
371
|
+
if (value == null || value === false) return null;
|
|
372
|
+
return react.createElement("span", {
|
|
373
|
+
slot: name,
|
|
374
|
+
style: { display: "contents" }
|
|
375
|
+
}, value);
|
|
224
376
|
}
|
|
225
377
|
//#endregion
|
|
226
378
|
//#region packages/web-c/output-react-wrapper/src/index.ts
|
|
@@ -233,7 +385,7 @@ function reactWrapper(options = {}) {
|
|
|
233
385
|
dts: (_options$dts = options.dts) !== null && _options$dts !== void 0 ? _options$dts : true,
|
|
234
386
|
index: (_options$index = options.index) !== null && _options$index !== void 0 ? _options$index : true,
|
|
235
387
|
namedSlots: (_options$namedSlots = options.namedSlots) !== null && _options$namedSlots !== void 0 ? _options$namedSlots : "props",
|
|
236
|
-
wrapper: (_options$wrapper = options.wrapper) !== null && _options$wrapper !== void 0 ? _options$wrapper : "
|
|
388
|
+
wrapper: (_options$wrapper = options.wrapper) !== null && _options$wrapper !== void 0 ? _options$wrapper : "runtime"
|
|
237
389
|
};
|
|
238
390
|
return {
|
|
239
391
|
name: "zeus-output-react-wrapper",
|
|
@@ -276,4 +428,4 @@ function reactWrapper(options = {}) {
|
|
|
276
428
|
};
|
|
277
429
|
}
|
|
278
430
|
//#endregion
|
|
279
|
-
export { reactWrapper as default };
|
|
431
|
+
export { createComponent, reactWrapper as default };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* output-react-wrapper v0.1.0-beta.5
|
|
3
|
+
* (c) 2026 baicie
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
**/
|
|
6
|
+
Object.defineProperties(exports, {
|
|
7
|
+
__esModule: { value: true },
|
|
8
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
9
|
+
});
|
|
10
|
+
let _lit_react = require("@lit/react");
|
|
11
|
+
//#region packages/web-c/output-react-wrapper/src/runtime/createComponent.ts
|
|
12
|
+
function createComponent(options) {
|
|
13
|
+
var _customElements$get;
|
|
14
|
+
const { defineCustomElement, react, tagName, transformTag, elementClass, events = {}, slots = [], displayName } = options;
|
|
15
|
+
const finalTagName = transformTag ? transformTag(tagName) : tagName;
|
|
16
|
+
defineCustomElement === null || defineCustomElement === void 0 || defineCustomElement();
|
|
17
|
+
const LitComponent = (0, _lit_react.createComponent)({
|
|
18
|
+
react,
|
|
19
|
+
tagName: finalTagName,
|
|
20
|
+
elementClass: elementClass !== null && elementClass !== void 0 ? elementClass : typeof customElements === "undefined" ? HTMLElement : (_customElements$get = customElements.get(finalTagName)) !== null && _customElements$get !== void 0 ? _customElements$get : HTMLElement,
|
|
21
|
+
events,
|
|
22
|
+
displayName
|
|
23
|
+
});
|
|
24
|
+
if (!slots.length) return LitComponent;
|
|
25
|
+
const slotSet = new Set(slots);
|
|
26
|
+
return react.forwardRef((inputProps, ref) => {
|
|
27
|
+
const rest = {};
|
|
28
|
+
const slottedChildren = [];
|
|
29
|
+
if (inputProps == null) {
|
|
30
|
+
rest.ref = ref;
|
|
31
|
+
return react.createElement(LitComponent, rest);
|
|
32
|
+
}
|
|
33
|
+
const props = inputProps;
|
|
34
|
+
for (const key in props) {
|
|
35
|
+
if (!Object.prototype.hasOwnProperty.call(props, key)) continue;
|
|
36
|
+
const value = props[key];
|
|
37
|
+
if (slotSet.has(key)) {
|
|
38
|
+
const child = createNamedSlot(react, key, value);
|
|
39
|
+
if (child != null) slottedChildren.push(child);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
rest[key] = value;
|
|
43
|
+
}
|
|
44
|
+
rest.ref = ref;
|
|
45
|
+
if (props.children != null) slottedChildren.push(props.children);
|
|
46
|
+
return react.createElement(LitComponent, rest, ...slottedChildren);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function createNamedSlot(react, name, value) {
|
|
50
|
+
if (value == null || value === false) return null;
|
|
51
|
+
return react.createElement("span", {
|
|
52
|
+
slot: name,
|
|
53
|
+
style: { display: "contents" }
|
|
54
|
+
}, value);
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
exports.createComponent = createComponent;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* output-react-wrapper v0.1.0-beta.5
|
|
3
|
+
* (c) 2026 baicie
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
**/
|
|
6
|
+
Object.defineProperties(exports, {
|
|
7
|
+
__esModule: { value: true },
|
|
8
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
9
|
+
});
|
|
10
|
+
let _lit_react = require("@lit/react");
|
|
11
|
+
//#region packages/web-c/output-react-wrapper/src/runtime/createComponent.ts
|
|
12
|
+
function createComponent(options) {
|
|
13
|
+
var _customElements$get;
|
|
14
|
+
const { defineCustomElement, react, tagName, transformTag, elementClass, events = {}, slots = [], displayName } = options;
|
|
15
|
+
const finalTagName = transformTag ? transformTag(tagName) : tagName;
|
|
16
|
+
defineCustomElement === null || defineCustomElement === void 0 || defineCustomElement();
|
|
17
|
+
const LitComponent = (0, _lit_react.createComponent)({
|
|
18
|
+
react,
|
|
19
|
+
tagName: finalTagName,
|
|
20
|
+
elementClass: elementClass !== null && elementClass !== void 0 ? elementClass : typeof customElements === "undefined" ? HTMLElement : (_customElements$get = customElements.get(finalTagName)) !== null && _customElements$get !== void 0 ? _customElements$get : HTMLElement,
|
|
21
|
+
events,
|
|
22
|
+
displayName
|
|
23
|
+
});
|
|
24
|
+
if (!slots.length) return LitComponent;
|
|
25
|
+
const slotSet = new Set(slots);
|
|
26
|
+
return react.forwardRef((inputProps, ref) => {
|
|
27
|
+
const rest = {};
|
|
28
|
+
const slottedChildren = [];
|
|
29
|
+
if (inputProps == null) {
|
|
30
|
+
rest.ref = ref;
|
|
31
|
+
return react.createElement(LitComponent, rest);
|
|
32
|
+
}
|
|
33
|
+
const props = inputProps;
|
|
34
|
+
for (const key in props) {
|
|
35
|
+
if (!Object.prototype.hasOwnProperty.call(props, key)) continue;
|
|
36
|
+
const value = props[key];
|
|
37
|
+
if (slotSet.has(key)) {
|
|
38
|
+
const child = createNamedSlot(react, key, value);
|
|
39
|
+
if (child != null) slottedChildren.push(child);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
rest[key] = value;
|
|
43
|
+
}
|
|
44
|
+
rest.ref = ref;
|
|
45
|
+
if (props.children != null) slottedChildren.push(props.children);
|
|
46
|
+
return react.createElement(LitComponent, rest, ...slottedChildren);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function createNamedSlot(react, name, value) {
|
|
50
|
+
if (value == null || value === false) return null;
|
|
51
|
+
return react.createElement("span", {
|
|
52
|
+
slot: name,
|
|
53
|
+
style: { display: "contents" }
|
|
54
|
+
}, value);
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
exports.createComponent = createComponent;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type EventName<T extends Event = Event> = string & {
|
|
2
|
+
__eventType: T;
|
|
3
|
+
};
|
|
4
|
+
type EventNames = Record<string, EventName | string>;
|
|
5
|
+
type ElementProps<I extends HTMLElement> = Partial<Omit<I, keyof HTMLElement>>;
|
|
6
|
+
type ReactRef<I extends HTMLElement> = ((instance: I | null) => void) | {
|
|
7
|
+
current: I | null;
|
|
8
|
+
} | null;
|
|
9
|
+
export interface ReactModule {
|
|
10
|
+
createElement: (...args: unknown[]) => unknown;
|
|
11
|
+
forwardRef: (...args: unknown[]) => unknown;
|
|
12
|
+
}
|
|
13
|
+
type EventListeners<E extends EventNames> = {
|
|
14
|
+
[K in keyof E]?: E[K] extends EventName<infer T> ? (event: T) => void : (event: Event) => void;
|
|
15
|
+
};
|
|
16
|
+
type ComponentProps<I extends HTMLElement, E extends EventNames> = {
|
|
17
|
+
children?: unknown;
|
|
18
|
+
className?: string;
|
|
19
|
+
ref?: ReactRef<I>;
|
|
20
|
+
style?: unknown;
|
|
21
|
+
} & {
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
} & EventListeners<E> & ElementProps<I>;
|
|
24
|
+
export type ZeusReactComponent<I extends HTMLElement, E extends EventNames = {}> = (props: ComponentProps<I, E>) => unknown;
|
|
25
|
+
export interface ZeusReactCreateComponentOptions<I extends HTMLElement, E extends EventNames> {
|
|
26
|
+
tagName: string;
|
|
27
|
+
react: ReactModule;
|
|
28
|
+
defineCustomElement?: () => void;
|
|
29
|
+
elementClass?: {
|
|
30
|
+
new (): I;
|
|
31
|
+
};
|
|
32
|
+
events?: E;
|
|
33
|
+
slots?: string[];
|
|
34
|
+
displayName?: string;
|
|
35
|
+
transformTag?: (tagName: string) => string;
|
|
36
|
+
}
|
|
37
|
+
export declare function createComponent<I extends HTMLElement, E extends EventNames = {}>(options: ZeusReactCreateComponentOptions<I, E>): ZeusReactComponent<I, E>;
|
|
38
|
+
|
|
39
|
+
|