element-plus
Version:
A Component Library for Vue 3
1 lines • 6.08 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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"}