summaryrefslogtreecommitdiff
path: root/packages/integrations/react/vnode-children.js
diff options
context:
space:
mode:
Diffstat (limited to 'packages/integrations/react/vnode-children.js')
-rw-r--r--packages/integrations/react/vnode-children.js29
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;
+}