diff options
Diffstat (limited to 'packages/integrations/react/vnode-children.js')
-rw-r--r-- | packages/integrations/react/vnode-children.js | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/packages/integrations/react/vnode-children.js b/packages/integrations/react/vnode-children.js new file mode 100644 index 000000000..e0751c95a --- /dev/null +++ b/packages/integrations/react/vnode-children.js @@ -0,0 +1,29 @@ +import { Fragment, createElement } from 'react'; +import { DOCUMENT_NODE, ELEMENT_NODE, TEXT_NODE, parse } from 'ultrahtml'; + +let ids = 0; +export default function convert(children) { + let doc = parse(children.toString().trim()); + let id = ids++; + let key = 0; + + function createReactElementFromNode(node) { + const childVnodes = + Array.isArray(node.children) && node.children.length + ? node.children.map((child) => createReactElementFromNode(child)).filter(Boolean) + : undefined; + + if (node.type === DOCUMENT_NODE) { + return createElement(Fragment, {}, childVnodes); + } else if (node.type === ELEMENT_NODE) { + const { class: className, ...props } = node.attributes; + return createElement(node.name, { ...props, className, key: `${id}-${key++}` }, childVnodes); + } else if (node.type === TEXT_NODE) { + // 0-length text gets omitted in JSX + return node.value.trim() ? node.value : undefined; + } + } + + const root = createReactElementFromNode(doc); + return root.props.children; +} |