From 2cc321461bbae820e45b029aee4dae7077c72578 Mon Sep 17 00:00:00 2001 From: Braden Mars Date: Tue, 5 Mar 2024 02:29:49 -0600 Subject: [PATCH] feat(components/tree): wip render tree tsx component Signed-off-by: Braden Mars --- src/components/tree/Recurse.tsx | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/components/tree/Recurse.tsx diff --git a/src/components/tree/Recurse.tsx b/src/components/tree/Recurse.tsx new file mode 100644 index 000000000..3c373ba8d --- /dev/null +++ b/src/components/tree/Recurse.tsx @@ -0,0 +1,48 @@ +import type { TreeNode } from './node'; +import { findUniqueNodeTypes, Tree } from './node'; +import type { FunctionalComponent, Slot, VNode } from 'vue'; + +export const RenderTree: FunctionalComponent<{ + tree: Tree; + seen?: Set; + sub?: boolean; +}> = (props, context) => { + const nodeTypes = computed(() => [...findUniqueNodeTypes(props.tree)]); + + const vnodes: [Slot, { node: TreeNode; subtree?: VNode }][] = []; + + const slotV = Object.fromEntries( + nodeTypes.value.map((nt) => [nt, context.slots[nt]]), + ); + console.log('slotv:', slotV); + + // const seen = props.seen ?? new Set>(); + let seen = toRef(props, 'seen'); + seen = seen?.value ?? ref(new Set()); + + props.tree.dfs((node) => { + // if (props.sub) return; + // if (seen.value.has(node)) return; + seen.value.add(node); + const slot = slotV[node.constructor.name] ?? context.slots.default; + if (slot) { + const subtree = node.isLeaf ? undefined : new Tree(node.clone()); + vnodes.push([slot, { node, subtree, self: slot, seen: seen.value }]); + } + }); + + return ( +
+ {{ + default: () => vnodes.map(([slot, slotProps]) => slot(slotProps)), + }} +
+ ); +}; + +RenderTree.props = { + tree: { + type: Object, + required: true, + }, +};