chromatic-lattice/src/features/trees/Tree.vue

101 lines
2.8 KiB
Vue

<template>
<component :is="nodesComp" />
<component v-if="leftNodesComp" :is="leftNodesComp" />
<component v-if="rightNodesComp" :is="rightNodesComp" />
<Links v-if="branches" :links="unref(branches)" />
</template>
<script lang="tsx">
import "components/common/table.css";
import { GenericTreeNode, TreeBranch } from "features/trees/tree";
import { coerceComponent, processedPropType, renderJSX, unwrapRef } from "util/vue";
import { Component, defineComponent, shallowRef, toRefs, unref, watchEffect } from "vue";
import Links from "features/links/Links.vue";
import { jsx } from "features/feature";
export default defineComponent({
props: {
nodes: {
type: processedPropType<GenericTreeNode[][]>(Array),
required: true
},
leftSideNodes: processedPropType<GenericTreeNode[]>(Array),
rightSideNodes: processedPropType<GenericTreeNode[]>(Array),
branches: processedPropType<TreeBranch[]>(Array)
},
components: { Links },
setup(props) {
const { nodes, leftSideNodes, rightSideNodes } = toRefs(props);
const nodesComp = shallowRef<Component | "">();
watchEffect(() => {
const currNodes = unwrapRef(nodes);
nodesComp.value = coerceComponent(
jsx(() => (
<>
{currNodes.map(row => (
<span class="row">{row.map(renderJSX)}</span>
))}
</>
))
);
});
const leftNodesComp = shallowRef<Component | "">();
watchEffect(() => {
const currNodes = unwrapRef(leftSideNodes);
leftNodesComp.value = currNodes
? coerceComponent(
jsx(() => (
<span class="left-side-nodes small">{currNodes.map(renderJSX)}</span>
))
)
: "";
});
const rightNodesComp = shallowRef<Component | "">();
watchEffect(() => {
const currNodes = unwrapRef(rightSideNodes);
rightNodesComp.value = currNodes
? coerceComponent(
jsx(() => <span class="side-nodes small">{currNodes.map(renderJSX)}</span>)
)
: "";
});
return {
unref,
nodesComp,
leftNodesComp,
rightNodesComp
};
}
});
</script>
<style scoped>
.row {
margin: 50px auto;
}
.left-side-nodes {
position: absolute;
left: 15px;
top: 65px;
}
.side-nodes {
position: absolute;
right: 15px;
top: 65px;
}
.small :deep(.treeNode) {
height: 60px;
width: 60px;
}
.small :deep(.treeNode) > *:first-child {
font-size: 30px;
}
</style>