@qwik.dev/react 2.0.0-beta.27 → 2.0.0-beta.29
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/lib/assets/BqrDAOEV-bundle-graph.json +1 -0
- package/lib/index.qwik.mjs +334 -148
- package/lib/q-manifest.json +50 -0
- package/lib/types/index.qwik.d.ts +1 -0
- package/lib/types/react/reactify.d.ts +55 -0
- package/lib/types/react/slot.d.ts +19 -4
- package/lib/types/react/types.d.ts +2 -0
- package/package.json +4 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[]
|
package/lib/index.qwik.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
import { jsx,
|
|
5
|
-
import {
|
|
6
|
-
import { SSRStream, SSRComment, SSRRaw } from "@qwik.dev/core/internal";
|
|
4
|
+
import { useSignal, isServer, useOn, useOnDocument, inlinedQrl, _captures, _jsxSorted, _jsxSplit, _wrapProp, Slot, jsx, componentQrl, useStylesScopedQrl, useStore, useTaskQrl, isBrowser, noSerialize, RenderOnce, SkipRender, implicit$FirstArg } from "@qwik.dev/core";
|
|
5
|
+
import { Fragment } from "@qwik.dev/core/jsx-runtime";
|
|
6
|
+
import { SSRStream, SSRComment, SSRRaw, _getContextContainer, _getContextHostElement, _addProjection, _setProjectionTarget, _removeProjection, _updateProjectionProps } from "@qwik.dev/core/internal";
|
|
7
7
|
import { renderToString } from "react-dom/server";
|
|
8
8
|
import { createElement, createContext, Component, createRef } from "react";
|
|
9
9
|
import { createRoot, hydrateRoot } from "react-dom/client";
|
|
@@ -11,23 +11,7 @@ import { flushSync } from "react-dom";
|
|
|
11
11
|
const SlotCtx = createContext({
|
|
12
12
|
scopeId: ""
|
|
13
13
|
});
|
|
14
|
-
|
|
15
|
-
const newProps = getReactProps(props);
|
|
16
|
-
return mainExactProps(slotEl, scopeId, RootCmp, newProps);
|
|
17
|
-
}
|
|
18
|
-
function mainExactProps(slotEl, scopeId, RootCmp, props) {
|
|
19
|
-
return createElement(SlotCtx.Provider, {
|
|
20
|
-
value: {
|
|
21
|
-
el: slotEl,
|
|
22
|
-
scopeId,
|
|
23
|
-
attachedEl: void 0
|
|
24
|
-
},
|
|
25
|
-
children: createElement(RootCmp, {
|
|
26
|
-
...props,
|
|
27
|
-
children: createElement(SlotElement, null)
|
|
28
|
-
})
|
|
29
|
-
});
|
|
30
|
-
}
|
|
14
|
+
const QwikProjectionCtx = createContext(null);
|
|
31
15
|
class SlotElement extends Component {
|
|
32
16
|
constructor() {
|
|
33
17
|
super(...arguments);
|
|
@@ -61,28 +45,34 @@ class SlotElement extends Component {
|
|
|
61
45
|
}
|
|
62
46
|
}
|
|
63
47
|
__publicField(SlotElement, "contextType", SlotCtx);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const obj = {};
|
|
76
|
-
Object.keys(props).forEach((key) => {
|
|
77
|
-
if (key.startsWith(HOST_PREFIX)) {
|
|
78
|
-
obj[key.slice(HOST_PREFIX.length)] = props[key];
|
|
79
|
-
}
|
|
48
|
+
function mainExactProps(slotEl, scopeId, RootCmp, props, projectionState) {
|
|
49
|
+
let tree = createElement(SlotCtx.Provider, {
|
|
50
|
+
value: {
|
|
51
|
+
el: slotEl,
|
|
52
|
+
scopeId,
|
|
53
|
+
attachedEl: void 0
|
|
54
|
+
},
|
|
55
|
+
children: createElement(RootCmp, {
|
|
56
|
+
...props,
|
|
57
|
+
children: createElement(SlotElement, null)
|
|
58
|
+
})
|
|
80
59
|
});
|
|
81
|
-
|
|
82
|
-
|
|
60
|
+
if (projectionState) {
|
|
61
|
+
tree = createElement(QwikProjectionCtx.Provider, {
|
|
62
|
+
value: projectionState,
|
|
63
|
+
children: tree
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return tree;
|
|
67
|
+
}
|
|
83
68
|
const useWakeupSignal = (props, opts = {}) => {
|
|
84
69
|
const signal = useSignal(false);
|
|
85
|
-
const activate =
|
|
70
|
+
const activate = /* @__PURE__ */ inlinedQrl(() => {
|
|
71
|
+
const signal2 = _captures[0];
|
|
72
|
+
return signal2.value = true;
|
|
73
|
+
}, "useWakeupSignal_activate_bbwdFkXhIMU", [
|
|
74
|
+
signal
|
|
75
|
+
]);
|
|
86
76
|
const clientOnly = !!(props["client:only"] || props["qwik:only"] || opts?.clientOnly);
|
|
87
77
|
const clientVisible = props["client:visible"] || props["qwik:visible"] || opts?.eagerness === "visible";
|
|
88
78
|
const clientIdle = props["client:idle"] || props["qwik:idle"] || opts?.eagerness === "idle";
|
|
@@ -116,157 +106,353 @@ const useWakeupSignal = (props, opts = {}) => {
|
|
|
116
106
|
];
|
|
117
107
|
};
|
|
118
108
|
const HOST_PREFIX = "host:";
|
|
109
|
+
const getReactProps = (props) => {
|
|
110
|
+
const obj = {};
|
|
111
|
+
Object.keys(props).forEach((key) => {
|
|
112
|
+
if (!key.startsWith("client:") && !key.startsWith("qwik:") && !key.startsWith(HOST_PREFIX)) {
|
|
113
|
+
const normalizedKey = key.endsWith("$") ? key.slice(0, -1) : key;
|
|
114
|
+
obj[normalizedKey] = props[key];
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
return obj;
|
|
118
|
+
};
|
|
119
|
+
function main(slotEl, scopeId, RootCmp, props, projectionState) {
|
|
120
|
+
const newProps = getReactProps(props);
|
|
121
|
+
return mainExactProps(slotEl, scopeId, RootCmp, newProps, projectionState);
|
|
122
|
+
}
|
|
123
|
+
const getHostProps = (props) => {
|
|
124
|
+
const obj = {};
|
|
125
|
+
Object.keys(props).forEach((key) => {
|
|
126
|
+
if (key.startsWith(HOST_PREFIX)) {
|
|
127
|
+
obj[key.slice(HOST_PREFIX.length)] = props[key];
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
return obj;
|
|
131
|
+
};
|
|
132
|
+
let _ssrProjectionRegistry = null;
|
|
133
|
+
function setSSRProjectionRegistry(registry) {
|
|
134
|
+
_ssrProjectionRegistry = registry;
|
|
135
|
+
}
|
|
136
|
+
function getSSRProjectionRegistry() {
|
|
137
|
+
return _ssrProjectionRegistry;
|
|
138
|
+
}
|
|
139
|
+
const SLOT_MARKER = "<!--SLOT-->";
|
|
140
|
+
function splitHtmlAtMarkers(html) {
|
|
141
|
+
const MARKER_RE = /<!--(?:SLOT|QWIK-PROJ:(.*?))-->/g;
|
|
142
|
+
const segments = [];
|
|
143
|
+
let lastIndex = 0;
|
|
144
|
+
let match;
|
|
145
|
+
while ((match = MARKER_RE.exec(html)) !== null) {
|
|
146
|
+
if (match.index > lastIndex) {
|
|
147
|
+
segments.push({
|
|
148
|
+
type: "html",
|
|
149
|
+
content: html.slice(lastIndex, match.index)
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if (match[1] !== void 0) {
|
|
153
|
+
segments.push({
|
|
154
|
+
type: "proj",
|
|
155
|
+
slotName: match[1]
|
|
156
|
+
});
|
|
157
|
+
} else {
|
|
158
|
+
segments.push({
|
|
159
|
+
type: "slot"
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
lastIndex = match.index + match[0].length;
|
|
163
|
+
}
|
|
164
|
+
if (lastIndex < html.length) {
|
|
165
|
+
segments.push({
|
|
166
|
+
type: "html",
|
|
167
|
+
content: html.slice(lastIndex)
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return segments;
|
|
171
|
+
}
|
|
119
172
|
async function renderFromServer(Host, reactCmp$, scopeId, props, ref, slotRef, hydrationProps) {
|
|
120
173
|
if (isServer) {
|
|
121
174
|
const Cmp = await reactCmp$.resolve();
|
|
122
175
|
const newProps = getReactProps(props);
|
|
123
176
|
Object.assign(hydrationProps, newProps);
|
|
177
|
+
const registry = {
|
|
178
|
+
entries: /* @__PURE__ */ new Map()
|
|
179
|
+
};
|
|
180
|
+
setSSRProjectionRegistry(registry);
|
|
124
181
|
const html = renderToString(mainExactProps(void 0, scopeId, Cmp, newProps));
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
182
|
+
setSSRProjectionRegistry(null);
|
|
183
|
+
const hasSlot = html.includes(SLOT_MARKER);
|
|
184
|
+
const hasProj = registry.entries.size > 0;
|
|
185
|
+
if (hasSlot || hasProj) {
|
|
186
|
+
const segments = splitHtmlAtMarkers(html);
|
|
187
|
+
return /* @__PURE__ */ _jsxSorted(Fragment, null, null, [
|
|
188
|
+
/* @__PURE__ */ _jsxSplit(Host, {
|
|
189
|
+
ref,
|
|
190
|
+
...getHostProps(props)
|
|
191
|
+
}, null, /* @__PURE__ */ _jsxSorted(SSRStream, null, null, async function* () {
|
|
192
|
+
yield /* @__PURE__ */ _jsxSorted(SSRComment, null, {
|
|
193
|
+
data: "q:ignore"
|
|
194
|
+
}, null, 3, "cl_0");
|
|
195
|
+
for (const segment of segments) {
|
|
196
|
+
if (segment.type === "html") {
|
|
197
|
+
yield /* @__PURE__ */ _jsxSorted(SSRRaw, {
|
|
198
|
+
data: _wrapProp(segment, "content")
|
|
199
|
+
}, null, null, 3, "cl_1");
|
|
200
|
+
} else if (segment.type === "slot") {
|
|
201
|
+
yield /* @__PURE__ */ _jsxSorted(SSRComment, null, {
|
|
202
|
+
data: "q:container-island"
|
|
203
|
+
}, null, 3, "cl_2");
|
|
204
|
+
yield /* @__PURE__ */ _jsxSorted("q-slot", {
|
|
205
|
+
ref: slotRef
|
|
206
|
+
}, null, /* @__PURE__ */ _jsxSorted(Slot, null, null, null, 3, "cl_3"), 1, "cl_4");
|
|
207
|
+
yield /* @__PURE__ */ _jsxSorted(SSRComment, null, {
|
|
208
|
+
data: "/q:container-island"
|
|
209
|
+
}, null, 3, "cl_5");
|
|
210
|
+
} else if (segment.type === "proj") {
|
|
211
|
+
const entry = registry.entries.get(segment.slotName);
|
|
212
|
+
if (entry) {
|
|
213
|
+
yield /* @__PURE__ */ _jsxSorted(SSRComment, null, {
|
|
214
|
+
data: "q:container-island"
|
|
215
|
+
}, null, 3, "cl_6");
|
|
216
|
+
const QwikComp = await entry.qrl.resolve();
|
|
217
|
+
yield jsx(QwikComp, entry.props);
|
|
218
|
+
yield /* @__PURE__ */ _jsxSorted(SSRComment, null, {
|
|
219
|
+
data: "/q:container-island"
|
|
220
|
+
}, null, 3, "cl_7");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
156
223
|
}
|
|
157
|
-
|
|
158
|
-
|
|
224
|
+
yield /* @__PURE__ */ _jsxSorted(SSRComment, null, {
|
|
225
|
+
data: "/q:ignore"
|
|
226
|
+
}, null, 3, "cl_8");
|
|
227
|
+
}, 1, "cl_9"), 0, "cl_10"),
|
|
228
|
+
!hasSlot && /* @__PURE__ */ _jsxSorted("q-slot", {
|
|
229
|
+
ref: slotRef
|
|
230
|
+
}, null, /* @__PURE__ */ _jsxSorted(Slot, null, null, null, 3, "cl_11"), 1, "cl_12")
|
|
231
|
+
], 1, "cl_13");
|
|
159
232
|
}
|
|
160
|
-
return /* @__PURE__ */
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
children: /* @__PURE__ */ jsx(Slot, {})
|
|
179
|
-
})
|
|
180
|
-
]
|
|
181
|
-
});
|
|
233
|
+
return /* @__PURE__ */ _jsxSorted(Fragment, null, null, [
|
|
234
|
+
/* @__PURE__ */ _jsxSorted(Host, {
|
|
235
|
+
ref
|
|
236
|
+
}, null, [
|
|
237
|
+
/* @__PURE__ */ _jsxSorted(SSRComment, null, {
|
|
238
|
+
data: "q:container=html"
|
|
239
|
+
}, null, 3, "cl_14"),
|
|
240
|
+
/* @__PURE__ */ _jsxSorted(SSRRaw, {
|
|
241
|
+
data: html
|
|
242
|
+
}, null, null, 3, "cl_15"),
|
|
243
|
+
/* @__PURE__ */ _jsxSorted(SSRComment, null, {
|
|
244
|
+
data: "/q:container"
|
|
245
|
+
}, null, 3, "cl_16")
|
|
246
|
+
], 1, "cl_17"),
|
|
247
|
+
/* @__PURE__ */ _jsxSorted("q-slot", {
|
|
248
|
+
ref: slotRef
|
|
249
|
+
}, null, /* @__PURE__ */ _jsxSorted(Slot, null, null, null, 3, "cl_18"), 1, null)
|
|
250
|
+
], 1, "cl_19");
|
|
182
251
|
}
|
|
183
252
|
}
|
|
184
253
|
function qwikifyQrl(reactCmp$, opts) {
|
|
185
|
-
return
|
|
186
|
-
const
|
|
254
|
+
return /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) => {
|
|
255
|
+
const opts2 = _captures[0], reactCmp$2 = _captures[1];
|
|
256
|
+
const { scopeId } = useStylesScopedQrl(/* @__PURE__ */ inlinedQrl(`q-slot{display:none} q-slotc,q-slotc>q-slot{display:contents}`, "qwikifyQrl_component_useStylesScoped_ppvg9vpFqsY"));
|
|
187
257
|
const hostRef = useSignal();
|
|
188
258
|
const slotRef = useSignal();
|
|
189
259
|
const internalState = useSignal();
|
|
190
|
-
const [signal, isClientOnly] = useWakeupSignal(props,
|
|
260
|
+
const [signal, isClientOnly] = useWakeupSignal(props, opts2);
|
|
191
261
|
const hydrationKeys = useStore({});
|
|
192
|
-
const TagName =
|
|
193
|
-
|
|
262
|
+
const TagName = opts2?.tagName ?? "qwik-react";
|
|
263
|
+
useTaskQrl(/* @__PURE__ */ inlinedQrl(async ({ track }) => {
|
|
264
|
+
const hostRef2 = _captures[0], hydrationKeys2 = _captures[1], internalState2 = _captures[2], isClientOnly2 = _captures[3], props2 = _captures[4], reactCmp$3 = _captures[5], scopeId2 = _captures[6], signal2 = _captures[7], slotRef2 = _captures[8];
|
|
194
265
|
const trackedProps = track(() => ({
|
|
195
|
-
...
|
|
266
|
+
...props2
|
|
196
267
|
}));
|
|
197
|
-
track(
|
|
268
|
+
track(signal2);
|
|
198
269
|
if (!isBrowser) {
|
|
199
270
|
return;
|
|
200
271
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
272
|
+
let projectionState = null;
|
|
273
|
+
const container = _getContextContainer();
|
|
274
|
+
const hostVNode = _getContextHostElement();
|
|
275
|
+
if (container && hostVNode) {
|
|
276
|
+
projectionState = {
|
|
277
|
+
parentVNode: hostVNode,
|
|
278
|
+
container
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
if (internalState2.value) {
|
|
282
|
+
if (internalState2.value.root) {
|
|
283
|
+
internalState2.value.root.render(main(slotRef2.value, scopeId2, internalState2.value.cmp, trackedProps, internalState2.value.projectionState));
|
|
204
284
|
}
|
|
205
285
|
} else {
|
|
206
286
|
let root = void 0;
|
|
207
|
-
const Cmp = await reactCmp
|
|
208
|
-
const hostElement =
|
|
287
|
+
const Cmp = await reactCmp$3.resolve();
|
|
288
|
+
const hostElement = hostRef2.value;
|
|
209
289
|
if (hostElement) {
|
|
210
|
-
if (
|
|
290
|
+
if (isClientOnly2) {
|
|
211
291
|
root = createRoot(hostElement);
|
|
212
292
|
} else {
|
|
213
293
|
root = flushSync(() => {
|
|
214
|
-
return hydrateRoot(hostElement, mainExactProps(
|
|
294
|
+
return hydrateRoot(hostElement, mainExactProps(slotRef2.value, scopeId2, Cmp, hydrationKeys2, projectionState));
|
|
215
295
|
});
|
|
216
296
|
}
|
|
217
|
-
if (
|
|
218
|
-
root.render(main(
|
|
297
|
+
if (isClientOnly2 || signal2.value === false) {
|
|
298
|
+
root.render(main(slotRef2.value, scopeId2, Cmp, trackedProps, projectionState));
|
|
219
299
|
}
|
|
220
300
|
}
|
|
221
|
-
|
|
301
|
+
internalState2.value = noSerialize({
|
|
222
302
|
cmp: Cmp,
|
|
223
|
-
root
|
|
303
|
+
root,
|
|
304
|
+
projectionState
|
|
224
305
|
});
|
|
225
306
|
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
307
|
+
}, "qwikifyQrl_component_useTask_JuFeaMCL0P0", [
|
|
308
|
+
hostRef,
|
|
309
|
+
hydrationKeys,
|
|
310
|
+
internalState,
|
|
311
|
+
isClientOnly,
|
|
312
|
+
props,
|
|
313
|
+
reactCmp$2,
|
|
314
|
+
scopeId,
|
|
315
|
+
signal,
|
|
316
|
+
slotRef
|
|
317
|
+
]));
|
|
318
|
+
useTaskQrl(/* @__PURE__ */ inlinedQrl(({ track, cleanup }) => {
|
|
319
|
+
const internalState2 = _captures[0], signal2 = _captures[1];
|
|
320
|
+
track(signal2);
|
|
229
321
|
if (isBrowser) {
|
|
230
322
|
cleanup(() => {
|
|
231
|
-
|
|
323
|
+
const root = internalState2.value?.root;
|
|
324
|
+
if (root) {
|
|
325
|
+
queueMicrotask(() => root.unmount());
|
|
326
|
+
}
|
|
232
327
|
});
|
|
233
328
|
}
|
|
234
|
-
}
|
|
329
|
+
}, "qwikifyQrl_component_useTask_1_mwaGrLCLc2w", [
|
|
330
|
+
internalState,
|
|
331
|
+
signal
|
|
332
|
+
]));
|
|
235
333
|
if (isServer && !isClientOnly) {
|
|
236
|
-
const
|
|
237
|
-
return /* @__PURE__ */
|
|
238
|
-
children: jsx$1
|
|
239
|
-
}, 2);
|
|
334
|
+
const jsx2 = renderFromServer(TagName, reactCmp$2, scopeId, props, hostRef, slotRef, hydrationKeys);
|
|
335
|
+
return /* @__PURE__ */ _jsxSorted(RenderOnce, null, null, jsx2, 1, 2);
|
|
240
336
|
}
|
|
241
|
-
return /* @__PURE__ */
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
337
|
+
return /* @__PURE__ */ _jsxSorted(Fragment, null, null, [
|
|
338
|
+
/* @__PURE__ */ _jsxSplit(TagName, {
|
|
339
|
+
...getHostProps(props)
|
|
340
|
+
}, {
|
|
341
|
+
ref: (el) => {
|
|
342
|
+
if (isBrowser) {
|
|
343
|
+
queueMicrotask(() => {
|
|
344
|
+
const internalData = internalState.value;
|
|
345
|
+
if (internalData && !internalData.root) {
|
|
346
|
+
const root = internalData.root = createRoot(el);
|
|
347
|
+
root.render(main(slotRef.value, scopeId, internalData.cmp, props, internalData.projectionState));
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
} else {
|
|
351
|
+
hostRef.value = el;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}, SkipRender, 0, "sV_0"),
|
|
355
|
+
/* @__PURE__ */ _jsxSorted("q-slot", {
|
|
356
|
+
ref: slotRef
|
|
357
|
+
}, null, /* @__PURE__ */ _jsxSorted(Slot, null, null, null, 3, "sV_1"), 1, null)
|
|
358
|
+
], 1, "sV_2");
|
|
359
|
+
}, "qwikifyQrl_component_5bB3apdeFTY", [
|
|
360
|
+
opts,
|
|
361
|
+
reactCmp$
|
|
362
|
+
]));
|
|
267
363
|
}
|
|
268
364
|
const qwikify$ = /* @__PURE__ */ implicit$FirstArg(qwikifyQrl);
|
|
365
|
+
let slotCounter = 0;
|
|
366
|
+
function reactifyQrl(qwikCompQrl) {
|
|
367
|
+
const _QwikInReact = class _QwikInReact extends Component {
|
|
368
|
+
constructor() {
|
|
369
|
+
super(...arguments);
|
|
370
|
+
__publicField(this, "slotName", `_rq:${slotCounter++}`);
|
|
371
|
+
__publicField(this, "vnode", null);
|
|
372
|
+
__publicField(this, "divRef", createRef());
|
|
373
|
+
__publicField(this, "mounted", false);
|
|
374
|
+
__publicField(this, "pendingProps", null);
|
|
375
|
+
}
|
|
376
|
+
componentDidMount() {
|
|
377
|
+
this.mounted = true;
|
|
378
|
+
const projectionState = this.context;
|
|
379
|
+
if (!projectionState) {
|
|
380
|
+
if (typeof console !== "undefined") {
|
|
381
|
+
console.warn("reactify$: component must be rendered inside a qwikify$() React tree.");
|
|
382
|
+
}
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
const div = this.divRef.current;
|
|
386
|
+
if (!div) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
if (div.firstElementChild) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
qwikCompQrl.resolve().then((QwikComp) => {
|
|
393
|
+
if (!this.mounted) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
const name = QwikComp.displayName || QwikComp.name || "QwikComponent";
|
|
397
|
+
_QwikInReact.displayName = `reactify$(${name})`;
|
|
398
|
+
const { parentVNode, container } = projectionState;
|
|
399
|
+
const reactProps = getReactProps(this.pendingProps || this.props);
|
|
400
|
+
this.vnode = _addProjection(container, parentVNode, qwikCompQrl, reactProps, this.slotName);
|
|
401
|
+
div.replaceChildren();
|
|
402
|
+
_setProjectionTarget(this.vnode, div);
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
componentWillUnmount() {
|
|
406
|
+
this.mounted = false;
|
|
407
|
+
if (this.vnode && this.context) {
|
|
408
|
+
_removeProjection(this.context.container, this.context.parentVNode, this.vnode, this.slotName);
|
|
409
|
+
this.vnode = null;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
shouldComponentUpdate(nextProps) {
|
|
413
|
+
if (this.vnode && this.context) {
|
|
414
|
+
const reactProps = getReactProps(nextProps);
|
|
415
|
+
_updateProjectionProps(this.context.container, this.vnode, reactProps);
|
|
416
|
+
} else {
|
|
417
|
+
this.pendingProps = nextProps;
|
|
418
|
+
}
|
|
419
|
+
return false;
|
|
420
|
+
}
|
|
421
|
+
render() {
|
|
422
|
+
const registry = getSSRProjectionRegistry();
|
|
423
|
+
if (registry) {
|
|
424
|
+
const reactProps = getReactProps(this.props);
|
|
425
|
+
registry.entries.set(this.slotName, {
|
|
426
|
+
qrl: qwikCompQrl,
|
|
427
|
+
props: reactProps
|
|
428
|
+
});
|
|
429
|
+
return createElement("div", {
|
|
430
|
+
"data-qwik-projection": this.slotName,
|
|
431
|
+
suppressHydrationWarning: true,
|
|
432
|
+
dangerouslySetInnerHTML: {
|
|
433
|
+
__html: `<!--QWIK-PROJ:${this.slotName}-->`
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
return createElement("div", {
|
|
438
|
+
ref: this.divRef,
|
|
439
|
+
suppressHydrationWarning: true,
|
|
440
|
+
dangerouslySetInnerHTML: {
|
|
441
|
+
__html: `<!--QWIK-PROJ:${this.slotName}-->`
|
|
442
|
+
},
|
|
443
|
+
"data-qwik-projection": this.slotName
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
__publicField(_QwikInReact, "contextType", QwikProjectionCtx);
|
|
448
|
+
let QwikInReact = _QwikInReact;
|
|
449
|
+
QwikInReact.displayName = `reactify$(...)`;
|
|
450
|
+
return QwikInReact;
|
|
451
|
+
}
|
|
452
|
+
const reactify$ = /* @__PURE__ */ implicit$FirstArg(reactifyQrl);
|
|
269
453
|
export {
|
|
270
454
|
qwikify$,
|
|
271
|
-
qwikifyQrl
|
|
455
|
+
qwikifyQrl,
|
|
456
|
+
reactify$,
|
|
457
|
+
reactifyQrl
|
|
272
458
|
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1",
|
|
3
|
+
"manifestHash": "v6wp5f",
|
|
4
|
+
"options": {
|
|
5
|
+
"target": "lib",
|
|
6
|
+
"buildMode": "development",
|
|
7
|
+
"entryStrategy": {
|
|
8
|
+
"type": "inline"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"bundleGraphAsset": "assets/BqrDAOEV-bundle-graph.json",
|
|
12
|
+
"injections": [],
|
|
13
|
+
"mapping": {},
|
|
14
|
+
"bundles": {
|
|
15
|
+
"../index.qwik.mjs": {
|
|
16
|
+
"size": 16132,
|
|
17
|
+
"total": 16132,
|
|
18
|
+
"origins": [
|
|
19
|
+
"src/index.qwik.ts",
|
|
20
|
+
"src/react/qwikify.tsx",
|
|
21
|
+
"src/react/reactify.ts",
|
|
22
|
+
"src/react/server-render.tsx",
|
|
23
|
+
"src/react/slot.ts"
|
|
24
|
+
],
|
|
25
|
+
"interactivity": 0
|
|
26
|
+
},
|
|
27
|
+
"../vite.mjs": {
|
|
28
|
+
"size": 483,
|
|
29
|
+
"total": 483,
|
|
30
|
+
"origins": [
|
|
31
|
+
"src/vite.ts"
|
|
32
|
+
],
|
|
33
|
+
"interactivity": 0
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"assets": {
|
|
37
|
+
"assets/BqrDAOEV-bundle-graph.json": {
|
|
38
|
+
"name": "bundle-graph.json",
|
|
39
|
+
"size": 0
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"symbols": {},
|
|
43
|
+
"platform": {
|
|
44
|
+
"vite": "",
|
|
45
|
+
"rollup": "4.59.0",
|
|
46
|
+
"env": "node",
|
|
47
|
+
"os": "linux",
|
|
48
|
+
"node": "24.14.0"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type QRL } from '@qwik.dev/core';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a React component that renders a Qwik component inside a qwikify$ React tree.
|
|
4
|
+
*
|
|
5
|
+
* This is the QRL form. Use `reactify$` for the convenience form with automatic `$()` wrapping.
|
|
6
|
+
*
|
|
7
|
+
* The returned React component must be rendered inside a `qwikify$()` React tree. It creates a div
|
|
8
|
+
* that Qwik renders into, while React ignores its contents.
|
|
9
|
+
*
|
|
10
|
+
* During SSR, a marker is emitted so that server-render.tsx can render the Qwik component inline
|
|
11
|
+
* inside `q:container-island` comments. On the client, Qwik resumes the SSR content naturally
|
|
12
|
+
* (events, signals, state are all serialized). For pure CSR, `_addProjection` renders from
|
|
13
|
+
* scratch.
|
|
14
|
+
*
|
|
15
|
+
* @param qwikCompQrl - A QRL wrapping a Qwik component (created with `component$`)
|
|
16
|
+
* @returns A React component that renders the Qwik component
|
|
17
|
+
*/
|
|
18
|
+
export declare function reactifyQrl(qwikCompQrl: QRL<any>): any;
|
|
19
|
+
/**
|
|
20
|
+
* Creates a React component that renders a Qwik component inside a qwikify$ React tree.
|
|
21
|
+
*
|
|
22
|
+
* The returned React component must be rendered inside a `qwikify$()` React tree. It creates a div
|
|
23
|
+
* that Qwik renders into, while React ignores its contents.
|
|
24
|
+
*
|
|
25
|
+
* During SSR, the Qwik component is rendered as HTML inside `q:container-island` comments. On the
|
|
26
|
+
* client, the component re-renders via the external projection API.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
*
|
|
30
|
+
* ```tsx
|
|
31
|
+
* import { component$ } from '@qwik.dev/core';
|
|
32
|
+
* import { qwikify$, reactify$ } from '@qwik.dev/react';
|
|
33
|
+
*
|
|
34
|
+
* const QwikCounter = component$(() => {
|
|
35
|
+
* const count = useSignal(0);
|
|
36
|
+
* return <button onClick$={() => count.value++}>{count.value}</button>;
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* const ReactCounter = reactify$(QwikCounter);
|
|
40
|
+
*
|
|
41
|
+
* const ReactApp = ({ children }) => (
|
|
42
|
+
* <div>
|
|
43
|
+
* <h1>React App</h1>
|
|
44
|
+
* <ReactCounter />
|
|
45
|
+
* {children}
|
|
46
|
+
* </div>
|
|
47
|
+
* );
|
|
48
|
+
*
|
|
49
|
+
* export const QwikifiedApp = qwikify$(ReactApp);
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @param qwikComp - A Qwik component (created with `component$`)
|
|
53
|
+
* @returns A React component that renders the Qwik component
|
|
54
|
+
*/
|
|
55
|
+
export declare const reactify$: (qrl: any) => any;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type QRL } from '@qwik.dev/core';
|
|
2
|
+
import { Component, type ReactElement } from 'react';
|
|
2
3
|
import type { QwikifyOptions, QwikifyProps } from './types';
|
|
3
4
|
interface SlotState {
|
|
4
5
|
el?: Element;
|
|
@@ -6,8 +7,13 @@ interface SlotState {
|
|
|
6
7
|
attachedEl?: Element;
|
|
7
8
|
}
|
|
8
9
|
declare const SlotCtx: import("react").Context<SlotState>;
|
|
9
|
-
export
|
|
10
|
-
|
|
10
|
+
export interface QwikProjectionState {
|
|
11
|
+
parentVNode: any;
|
|
12
|
+
container: any;
|
|
13
|
+
}
|
|
14
|
+
export declare const QwikProjectionCtx: import("react").Context<QwikProjectionState | null>;
|
|
15
|
+
export declare function main(slotEl: Element | undefined, scopeId: string, RootCmp: any, props: any, projectionState?: QwikProjectionState | null): ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
16
|
+
export declare function mainExactProps(slotEl: Element | undefined, scopeId: string, RootCmp: any, props: any, projectionState?: QwikProjectionState | null): ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
11
17
|
export declare class SlotElement extends Component {
|
|
12
18
|
static contextType: import("react").Context<SlotState>;
|
|
13
19
|
context: React.ContextType<typeof SlotCtx>;
|
|
@@ -25,5 +31,14 @@ export declare class SlotElement extends Component {
|
|
|
25
31
|
}
|
|
26
32
|
export declare const getReactProps: (props: Record<string, any>) => Record<string, any>;
|
|
27
33
|
export declare const getHostProps: (props: Record<string, any>) => Record<string, any>;
|
|
28
|
-
export declare const useWakeupSignal: (props: QwikifyProps<{}>, opts?: QwikifyOptions) => readonly [import("@qwik.dev/core").Signal<boolean>, boolean,
|
|
34
|
+
export declare const useWakeupSignal: (props: QwikifyProps<{}>, opts?: QwikifyOptions) => readonly [import("@qwik.dev/core").Signal<boolean>, boolean, QRL<() => true>];
|
|
35
|
+
export interface SSRProjectionEntry {
|
|
36
|
+
qrl: QRL<any>;
|
|
37
|
+
props: Record<string, any>;
|
|
38
|
+
}
|
|
39
|
+
export interface SSRProjectionRegistry {
|
|
40
|
+
entries: Map<string, SSRProjectionEntry>;
|
|
41
|
+
}
|
|
42
|
+
export declare function setSSRProjectionRegistry(registry: SSRProjectionRegistry | null): void;
|
|
43
|
+
export declare function getSSRProjectionRegistry(): SSRProjectionRegistry | null;
|
|
29
44
|
export {};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { QRL, Signal } from '@qwik.dev/core';
|
|
2
2
|
import type { FunctionComponent as ReactFC } from 'react';
|
|
3
3
|
import type { Root } from 'react-dom/client';
|
|
4
|
+
import type { QwikProjectionState } from './slot';
|
|
4
5
|
export interface Internal<PROPS> {
|
|
5
6
|
root: Root | undefined;
|
|
6
7
|
cmp: ReactFC<PROPS>;
|
|
8
|
+
projectionState: QwikProjectionState | null;
|
|
7
9
|
}
|
|
8
10
|
export interface QwikifyBase {
|
|
9
11
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qwik.dev/react",
|
|
3
3
|
"description": "Qwik React allows adding React components into existing Qwik application",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.29",
|
|
5
5
|
"bugs": "https://github.com/QwikDev/qwik/issues",
|
|
6
6
|
"devDependencies": {
|
|
7
7
|
"@types/react": "19.2.7",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"react-dom": "19.2.3",
|
|
11
11
|
"typescript": "5.9.3",
|
|
12
12
|
"vite": "7.3.1",
|
|
13
|
-
"@qwik.dev/core": "2.0.0-beta.
|
|
13
|
+
"@qwik.dev/core": "2.0.0-beta.29"
|
|
14
14
|
},
|
|
15
15
|
"engines": {
|
|
16
16
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"@types/react-dom": "^18",
|
|
38
38
|
"react": "^18",
|
|
39
39
|
"react-dom": "^18",
|
|
40
|
-
"vite": ">=
|
|
41
|
-
"@qwik.dev/core": "^2.0.0-beta.
|
|
40
|
+
"vite": ">=6 <9",
|
|
41
|
+
"@qwik.dev/core": "^2.0.0-beta.29"
|
|
42
42
|
},
|
|
43
43
|
"publishConfig": {
|
|
44
44
|
"access": "public"
|