schlechtenburg/packages/core/lib/use-block-tree.ts

70 lines
1.7 KiB
TypeScript
Raw Normal View History

2021-03-07 17:47:28 +00:00
import {
2021-03-08 15:29:35 +00:00
ref,
2021-03-07 17:47:28 +00:00
Ref,
reactive,
inject,
provide,
onUnmounted,
} from 'vue';
import {
2021-03-08 15:29:35 +00:00
TreeNode,
BlockData,
} from './types';
2021-03-07 17:47:28 +00:00
2021-03-08 15:29:35 +00:00
export const SymBlockTree= Symbol('Schlechtenburg block tree');
export const SymBlockTreeRegister = Symbol('Schlechtenburg block tree register');
export const SymBlockTreeUnregister = Symbol('Schlechtenburg block tree unregister');
2021-03-07 17:47:28 +00:00
export function useBlockTree() {
2021-03-08 15:29:35 +00:00
const blockTree: Ref<TreeNode|null> = inject(SymBlockTree, ref(null));
const registerWithParent = inject(SymBlockTreeRegister, (_: TreeNode) => {});
const unregisterWithParent = inject(SymBlockTreeUnregister, (_: TreeNode) => {});
2021-03-07 17:47:28 +00:00
2021-03-08 15:29:35 +00:00
const self: TreeNode = reactive({
2021-03-07 17:47:28 +00:00
id: '',
name: '',
icon: '',
children: [],
});
// Provide a registration function to child blocks
2021-03-08 15:29:35 +00:00
provide(SymBlockTreeRegister, (block: TreeNode) => {
if (self.children.find((child: TreeNode) => child.id === block.id)) {
2021-03-07 17:47:28 +00:00
return;
}
self.children = [
...self.children,
block,
];
});
// Provide an unregistration function to child blocks
2021-03-08 15:29:35 +00:00
provide(SymBlockTreeUnregister, ({ id }: TreeNode) => {
self.children = self.children.filter((child: TreeNode) => child.id !== id);
2021-03-07 17:47:28 +00:00
});
2021-03-08 15:29:35 +00:00
const register = (block: BlockData<any>) => {
2021-03-07 17:47:28 +00:00
if (!block.id) {
throw new Error(`Cannot register a block without an id: ${JSON.stringify(block)}`);
}
self.id = block.id;
self.name = block.name;
// Register ourselves at the parent block
registerWithParent(self);
}
// Unregister from parent when we get destroyed
onUnmounted(() => {
if (self.id) {
unregisterWithParent(self);
}
});
return {
blockTree,
register,
};
}