element-plus
Version:
A Component Library for Vue 3
1 lines • 5.91 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../../../../../packages/hooks/use-ordered-children/index.ts"],"sourcesContent":["import {\n defineComponent,\n h,\n isVNode,\n onMounted,\n shallowRef,\n triggerRef,\n} from 'vue'\nimport { flattedChildren } from '@element-plus/utils'\n\nimport type { Component, ComponentInternalInstance, VNode } from 'vue'\n\ntype ChildEssential = {\n uid: number\n getVnode: () => VNode\n}\n\nconst getOrderedChildren = <T>(\n vm: ComponentInternalInstance,\n childComponentName: string,\n children: Record<number, T>\n): T[] => {\n const nodes = flattedChildren(vm.subTree).filter(\n (n): n is VNode =>\n isVNode(n) &&\n (n.type as Component)?.name === childComponentName &&\n !!n.component\n )\n const uids = nodes.map((n) => n.component!.uid)\n return uids.map((uid) => children[uid]).filter((p) => !!p)\n}\n\nexport const useOrderedChildren = <T extends ChildEssential>(\n vm: ComponentInternalInstance,\n childComponentName: string\n) => {\n const children = shallowRef<Record<number, T>>({})\n const orderedChildren = shallowRef<T[]>([])\n const nodesMap = new WeakMap<ParentNode, Node[]>()\n\n const addChild = (child: T) => {\n children.value[child.uid] = child\n triggerRef(children)\n\n onMounted(() => {\n const childNode = child.getVnode().el! as Node\n const parentNode = childNode.parentNode!\n\n if (!nodesMap.has(parentNode)) {\n nodesMap.set(parentNode, [])\n\n const originalFn = parentNode.insertBefore.bind(parentNode)\n parentNode.insertBefore = <T extends Node>(\n node: T,\n anchor: Node | null\n ) => {\n // Schedule a job to update `orderedChildren` if the root element of child components is moved\n const shouldSortChildren = nodesMap\n .get(parentNode)!\n .some((el) => node === el || anchor === el)\n if (shouldSortChildren) triggerRef(children)\n\n return originalFn(node, anchor)\n }\n }\n\n nodesMap.get(parentNode)!.push(childNode)\n })\n }\n\n const removeChild = (child: T) => {\n delete children.value[child.uid]\n triggerRef(children)\n\n const childNode = child.getVnode().el! as Node\n const parentNode = childNode.parentNode!\n const childNodes = nodesMap.get(parentNode)!\n const index = childNodes.indexOf(childNode)\n childNodes.splice(index, 1)\n }\n\n const sortChildren = () => {\n orderedChildren.value = getOrderedChildren(\n vm,\n childComponentName,\n children.value\n )\n }\n\n const IsolatedRenderer = (props: { render: () => VNode[] }) => {\n return props.render()\n }\n\n // TODO: Refactor `el-description` before converting this to a functional component\n const ChildrenSorter = defineComponent({\n setup(_, { slots }) {\n return () => {\n sortChildren()\n\n return slots.default\n ? // Create a new `ReactiveEffect` to ensure `ChildrenSorter` doesn't track any extra dependencies\n // @ts-ignore TODO: Remove this after Vue is upgraded\n h(IsolatedRenderer, {\n render: slots.default,\n })\n : null\n }\n },\n })\n\n return {\n children: orderedChildren,\n addChild,\n removeChild,\n ChildrenSorter,\n }\n}\n"],"names":[],"mappings":"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"}