wip: support true react vnodes in renderer
This commit is contained in:
parent
4ce2ba972a
commit
304dbada53
4 changed files with 58 additions and 2 deletions
|
@ -45,7 +45,8 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.22.5",
|
"@babel/core": "^7.22.5",
|
||||||
"@babel/plugin-transform-react-jsx": "^7.22.5"
|
"@babel/plugin-transform-react-jsx": "^7.22.5",
|
||||||
|
"ultrahtml": "^1.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^17.0.62",
|
"@types/react": "^17.0.62",
|
||||||
|
|
|
@ -43,6 +43,12 @@ async function check(Component, props, children) {
|
||||||
return React.createElement('div');
|
return React.createElement('div');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (props['use:vnode']) {
|
||||||
|
const convert = await import('./vnode-children.js').then(mod => mod.default);
|
||||||
|
delete props['use:vnode'];
|
||||||
|
children = convert(children);
|
||||||
|
}
|
||||||
|
|
||||||
await renderToStaticMarkup(Tester, props, children, {});
|
await renderToStaticMarkup(Tester, props, children, {});
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -85,7 +91,11 @@ async function renderToStaticMarkup(Component, props, { default: children, ...sl
|
||||||
...slots,
|
...slots,
|
||||||
};
|
};
|
||||||
const newChildren = children ?? props.children;
|
const newChildren = children ?? props.children;
|
||||||
if (newChildren != null) {
|
if (props['use:vnode']) {
|
||||||
|
const convert = await import('./vnode-children.js').then(mod => mod.default);
|
||||||
|
delete props['use:vnode'];
|
||||||
|
newProps.children = convert(children)
|
||||||
|
} else if (newChildren != null) {
|
||||||
newProps.children = React.createElement(StaticHtml, {
|
newProps.children = React.createElement(StaticHtml, {
|
||||||
hydrate: needsHydration(metadata),
|
hydrate: needsHydration(metadata),
|
||||||
value: newChildren,
|
value: newChildren,
|
||||||
|
|
38
packages/integrations/react/vnode-children.js
Normal file
38
packages/integrations/react/vnode-children.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import { parse, walkSync, DOCUMENT_NODE, ELEMENT_NODE, TEXT_NODE } from 'ultrahtml'
|
||||||
|
import { createElement, Fragment } from 'react';
|
||||||
|
|
||||||
|
export default function convert(children) {
|
||||||
|
const nodeMap = new WeakMap();
|
||||||
|
let doc = parse(children.default.toString().trim());
|
||||||
|
let root = createElement(Fragment, { children: [] });
|
||||||
|
|
||||||
|
walkSync(doc, (node, parent, index) => {
|
||||||
|
let newNode = {};
|
||||||
|
if (node.type === DOCUMENT_NODE) {
|
||||||
|
nodeMap.set(node, root);
|
||||||
|
} else if (node.type === ELEMENT_NODE) {
|
||||||
|
const { class: className, ...props } = node.attributes;
|
||||||
|
newNode = createElement(node.name, { ...props, className, children: [] });
|
||||||
|
nodeMap.set(node, newNode);
|
||||||
|
if (parent) {
|
||||||
|
const newParent = nodeMap.get(parent);
|
||||||
|
newParent.props.children[index] = newNode;
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if (node.type === TEXT_NODE) {
|
||||||
|
newNode = node.value.trim();
|
||||||
|
if (newNode.trim()) {
|
||||||
|
if (parent) {
|
||||||
|
const newParent = nodeMap.get(parent);
|
||||||
|
if (parent.children.length === 1) {
|
||||||
|
newParent.props.children[0] = newNode;
|
||||||
|
} else {
|
||||||
|
newParent.props.children[index] = newNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return root.props.children;
|
||||||
|
}
|
7
pnpm-lock.yaml
generated
7
pnpm-lock.yaml
generated
|
@ -4720,6 +4720,9 @@ importers:
|
||||||
'@babel/plugin-transform-react-jsx':
|
'@babel/plugin-transform-react-jsx':
|
||||||
specifier: ^7.22.5
|
specifier: ^7.22.5
|
||||||
version: 7.22.5(@babel/core@7.22.5)
|
version: 7.22.5(@babel/core@7.22.5)
|
||||||
|
ultrahtml:
|
||||||
|
specifier: ^1.2.0
|
||||||
|
version: 1.2.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@types/react':
|
'@types/react':
|
||||||
specifier: ^17.0.62
|
specifier: ^17.0.62
|
||||||
|
@ -17114,6 +17117,10 @@ packages:
|
||||||
resolution: {integrity: sha512-P24ulZdT9UKyQuKA1IApdAZ+F9lwruGvmKb4pG3+sMvR3CjN0pjawPnxuSABHQFB+XqnB35TVXzJPOBYjCv6Kw==}
|
resolution: {integrity: sha512-P24ulZdT9UKyQuKA1IApdAZ+F9lwruGvmKb4pG3+sMvR3CjN0pjawPnxuSABHQFB+XqnB35TVXzJPOBYjCv6Kw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/ultrahtml@1.2.0:
|
||||||
|
resolution: {integrity: sha512-vxZM2yNvajRmCj/SknRYGNXk2tqiy6kRNvZjJLaleG3zJbSh/aNkOqD1/CVzypw8tyHyhpzYuwQgMMhUB4ZVNQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/unbox-primitive@1.0.2:
|
/unbox-primitive@1.0.2:
|
||||||
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
|
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
Loading…
Add table
Reference in a new issue