86 lines
2.2 KiB
TypeScript
86 lines
2.2 KiB
TypeScript
import {
|
|
ref,
|
|
Ref,
|
|
reactive,
|
|
inject,
|
|
provide,
|
|
onUnmounted,
|
|
} from 'vue';
|
|
import {
|
|
ITreeNode,
|
|
IBlockData,
|
|
} from './types';
|
|
import { useDynamicBlocks } from './use-dynamic-blocks';
|
|
import { SbMode } from './mode';
|
|
|
|
export const SymBlockTree= Symbol('Schlechtenburg block tree');
|
|
export const SymBlockTreeRegister = Symbol('Schlechtenburg block tree register');
|
|
export const SymBlockTreeUnregister = Symbol('Schlechtenburg block tree unregister');
|
|
|
|
export function useBlockTree() {
|
|
const blockTree: Ref<ITreeNode|null> = inject(SymBlockTree, ref(null));
|
|
const registerWithParent = inject(SymBlockTreeRegister, (_b: ITreeNode, _i: number) => {});
|
|
const unregisterWithParent = inject(SymBlockTreeUnregister, (_b: ITreeNode) => {});
|
|
|
|
const self: ITreeNode = reactive({
|
|
id: '',
|
|
name: '',
|
|
icon: '',
|
|
children: [],
|
|
});
|
|
|
|
// Provide a registration function to child blocks
|
|
provide(SymBlockTreeRegister, (block: ITreeNode, index:number = -1) => {
|
|
if (self.children.find((child: ITreeNode) => child.id === block.id)) {
|
|
return;
|
|
}
|
|
|
|
if (index < 0) {
|
|
}
|
|
|
|
const normalizedIndex = index < 0 ? 0 : index;
|
|
|
|
self.children =[
|
|
...self.children.slice(0, normalizedIndex),
|
|
block,
|
|
...self.children.slice(normalizedIndex),
|
|
];
|
|
});
|
|
|
|
// Provide an unregistration function to child blocks
|
|
provide(SymBlockTreeUnregister, ({ id }: ITreeNode) => {
|
|
self.children = self.children.filter((child: ITreeNode) => child.id !== id);
|
|
});
|
|
|
|
const { mode } = useDynamicBlocks();
|
|
|
|
const register = (block: IBlockData<any>, index: number = 0) => {
|
|
if (!block.id) {
|
|
throw new Error(`Cannot register a block without an id: ${JSON.stringify(block)}`);
|
|
}
|
|
|
|
if (mode.value !== SbMode.Edit) {
|
|
console.warn('Ignoring block tree registration requests outside of edit mode.');
|
|
return;
|
|
}
|
|
|
|
self.id = block.id;
|
|
self.name = block.name;
|
|
|
|
// Register ourselves at the parent block
|
|
registerWithParent(self, index);
|
|
}
|
|
|
|
// Unregister from parent when we get destroyed
|
|
onUnmounted(() => {
|
|
if (self.id) {
|
|
unregisterWithParent(self);
|
|
}
|
|
});
|
|
|
|
return {
|
|
blockTree,
|
|
register,
|
|
};
|
|
}
|