@extclp/vexip-ui
Version:
A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good
1 lines • 73.2 kB
Source Map (JSON)
{"version":3,"file":"tree.vue2.mjs","sources":["../../../components/tree/tree.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { CollapseTransition } from '@/components/collapse-transition'\r\nimport { Renderer } from '@/components/renderer'\r\nimport { VirtualList } from '@/components/virtual-list'\r\n\r\nimport {\r\n computed,\r\n nextTick,\r\n onMounted,\r\n provide,\r\n reactive,\r\n ref,\r\n toRef,\r\n watch,\r\n watchEffect,\r\n} from 'vue'\r\n\r\nimport TreeNode from './tree-node.vue'\r\nimport { createIconProp, emitEvent, useLocale, useNameHelper, useProps } from '@vexip-ui/config'\r\nimport { useMounted, useSetTimeout } from '@vexip-ui/hooks'\r\nimport {\r\n debounce,\r\n filterTree,\r\n flatTree,\r\n getGlobalCount,\r\n getLast,\r\n isNull,\r\n isPromise,\r\n mapTree,\r\n queryAll,\r\n removeArrayItem,\r\n transformTree,\r\n walkTree,\r\n} from '@vexip-ui/utils'\r\nimport { treeProps } from './props'\r\nimport { useCascadedChecked } from './hooks'\r\nimport { DropType, TREE_NODE_STATE, TREE_STATE, defaultKeyConfig } from './symbol'\r\n\r\nimport type { VirtualListExposed } from '@/components/virtual-list'\r\nimport type {\r\n Data,\r\n FilterFn,\r\n Key,\r\n TreeCollapseProps,\r\n TreeNodeInstance,\r\n TreeNodeProps,\r\n TreeNodeState,\r\n TreeSlots,\r\n} from './symbol'\r\n\r\ndefineOptions({ name: 'Tree' })\r\n\r\nconst _props = defineProps(treeProps)\r\nconst props = useProps('tree', _props, {\r\n arrow: {\r\n default: 'auto',\r\n validator: value => typeof value === 'boolean' || value === 'auto',\r\n },\r\n data: {\r\n default: () => [],\r\n static: true,\r\n },\r\n noBuildTree: false,\r\n emptyText: null,\r\n disabled: false,\r\n readonly: false,\r\n checkbox: false,\r\n suffixCheckbox: false,\r\n renderer: {\r\n default: null,\r\n isFunc: true,\r\n },\r\n prefixRenderer: {\r\n default: null,\r\n isFunc: true,\r\n },\r\n suffixRenderer: {\r\n default: null,\r\n isFunc: true,\r\n },\r\n multiple: false,\r\n indent: '16px',\r\n accordion: false,\r\n draggable: false,\r\n appear: false,\r\n floorSelect: false,\r\n onAsyncLoad: {\r\n default: null,\r\n isFunc: true,\r\n },\r\n cacheNode: false,\r\n rootId: null,\r\n keyConfig: () => ({}),\r\n noCascaded: false,\r\n filter: '',\r\n ignoreCase: false,\r\n nodeProps: null,\r\n linkLine: false,\r\n postCreate: {\r\n default: null,\r\n isFunc: true,\r\n },\r\n virtual: false,\r\n nodeMinHeight: {\r\n default: 26,\r\n validator: value => value > 0,\r\n },\r\n useYBar: false,\r\n noTransition: false,\r\n arrowIcon: createIconProp(),\r\n blockEffect: false,\r\n filterLeaf: false,\r\n keepSelected: false,\r\n slots: () => ({}),\r\n})\r\n\r\nconst slots = defineSlots<TreeSlots>()\r\n\r\nconst nh = useNameHelper('tree')\r\nconst locale = useLocale('tree', toRef(props, 'locale'))\r\n\r\nconst nodeMap = new Map<Key, TreeNodeProps>()\r\nconst nodeDataMap = new Map<Data, TreeNodeProps>()\r\nconst treeNodes = ref<TreeNodeProps[]>([])\r\nconst flattedNodes = ref<TreeNodeProps[]>([])\r\nconst dragging = ref(false)\r\nconst indicatorShow = ref(false)\r\nconst keyConfig = reactive({ ...defaultKeyConfig })\r\nconst nodeStates = reactive(new Map<Key, TreeNodeState>())\r\nconst expanding = ref(false)\r\nconst expandingNodes = ref<TreeNodeProps[]>([])\r\nconst expandedNodeIds = ref(new Set<Key>())\r\n\r\nconst { timer } = useSetTimeout()\r\nconst { isMounted } = useMounted()\r\n\r\nconst virtualList = ref<VirtualListExposed>()\r\nconst trap = ref<HTMLElement>()\r\nconst indicator = ref<HTMLElement>()\r\n\r\nconst wrapper = computed(() => virtualList.value?.wrapper)\r\n\r\nlet visibleNodeEls: HTMLElement[] = []\r\n\r\nconst defaultNodeProperties = {\r\n visible: true,\r\n selected: false,\r\n expanded: false,\r\n disabled: false,\r\n checked: false,\r\n loading: false,\r\n loaded: false,\r\n loadFail: false,\r\n readonly: false,\r\n arrow: 'auto' as boolean | 'auto',\r\n // will follow checkbox prop of tree when not set (be null)\r\n checkbox: null! as boolean,\r\n selectDisabled: false,\r\n expandDisabled: false,\r\n checkDisabled: false,\r\n isLeaf: 'auto' as boolean | 'auto',\r\n}\r\n\r\nconst boundAsyncLoad = computed(() => typeof props.onAsyncLoad === 'function')\r\nconst linkLine = computed(() => {\r\n return props.linkLine === true ? 'dashed' : props.linkLine === 'none' ? false : props.linkLine\r\n})\r\nconst style = computed(() => {\r\n return {\r\n [nh.cv('indent-width')]: typeof props.indent === 'number' ? `${props.indent}px` : props.indent,\r\n [nh.cv('link-line-type')]: linkLine.value || undefined,\r\n }\r\n})\r\nconst visibleNodes = computed(() => flatNodes(treeNodes.value))\r\nconst renderedNodes = computed(() => {\r\n return expanding.value ? expandingNodes.value : visibleNodes.value\r\n})\r\nconst toNodeProps = computed(() => {\r\n return typeof props.nodeProps === 'function' ? props.nodeProps : () => props.nodeProps\r\n})\r\n\r\nfunction createDefaultFilter(value: string) {\r\n const pattern = props.ignoreCase ? String(value).toLocaleLowerCase() : value\r\n const defaultFilter: FilterFn = data => {\r\n const label = data[keyConfig.label]\r\n\r\n return props.ignoreCase\r\n ? String(label).toLocaleLowerCase().includes(pattern)\r\n : String(label).includes(pattern)\r\n }\r\n\r\n return defaultFilter\r\n}\r\n\r\nconst updateVisibleNodeEls = debounce(() => {\r\n if (wrapper.value) {\r\n visibleNodeEls = queryAll(`.${nh.be('node')}`, wrapper.value)\r\n }\r\n}, 300)\r\n\r\nlet disableExpand = false\r\n\r\nfunction disableExpandTick() {\r\n disableExpand = true\r\n\r\n nextTick(() => {\r\n disableExpand = false\r\n })\r\n}\r\nwatchEffect(() => {\r\n const nodes = flattedNodes.value\r\n\r\n disableExpandTick()\r\n\r\n if (!props.filter) {\r\n for (let i = 0, len = nodes.length; i < len; ++i) {\r\n const node = nodes[i]\r\n\r\n node.matched = true\r\n node.childMatched = false\r\n node.upperMatched = false\r\n }\r\n } else {\r\n const filter =\r\n typeof props.filter === 'function' ? props.filter : createDefaultFilter(props.filter)\r\n const leafOnly = props.filterLeaf\r\n\r\n for (let i = 0, len = nodes.length; i < len; ++i) {\r\n const node = nodes[i]\r\n\r\n if (leafOnly && !isLeafNode(node)) {\r\n node.matched = false\r\n node.childMatched = false\r\n node.upperMatched = false\r\n\r\n continue\r\n }\r\n\r\n const parent = node.parent ? nodeMap.get(node.parent) : undefined\r\n\r\n node.matched = filter(node.data, node)\r\n node.childMatched = false\r\n node.upperMatched = !!parent && (parent.matched || parent.upperMatched)\r\n\r\n if (node.matched) {\r\n let upper = parent\r\n\r\n while (upper && !upper.childMatched) {\r\n upper.childMatched = true\r\n upper.expanded = true\r\n upper = upper.parent ? nodeMap.get(upper.parent) : undefined\r\n }\r\n }\r\n }\r\n }\r\n\r\n resetExpanded()\r\n})\r\nwatchEffect(() => Object.assign(keyConfig, props.keyConfig))\r\nwatchEffect(() => {\r\n const oldIds = expandedNodeIds.value\r\n const ids = new Set<Key>()\r\n\r\n let changed = false\r\n\r\n for (const node of flattedNodes.value) {\r\n if (node.expanded) {\r\n ids.add(node.id)\r\n\r\n if (!changed && !oldIds.has(node.id)) {\r\n changed = true\r\n }\r\n }\r\n }\r\n\r\n if (changed || ids.size !== oldIds.size) {\r\n expandedNodeIds.value = ids\r\n }\r\n})\r\nwatch(\r\n [\r\n () => props.data,\r\n () => props.data.length,\r\n () => keyConfig.id,\r\n () => keyConfig.children,\r\n () => keyConfig.parent,\r\n () => props.rootId,\r\n ],\r\n parseAndTransformData,\r\n { immediate: true },\r\n)\r\nwatch(\r\n [treeNodes, () => props.rootId],\r\n () => {\r\n flattedNodes.value = flatTree(treeNodes.value, {\r\n keyField: 'id',\r\n parentField: 'parent',\r\n childField: 'children',\r\n rootId: props.rootId,\r\n injectId: false,\r\n depthFirst: true,\r\n })\r\n },\r\n { immediate: true },\r\n)\r\nwatch(expandedNodeIds, (value, prev) => {\r\n if (props.noTransition) {\r\n updateVisibleNodeEls()\r\n }\r\n\r\n if (props.noTransition || disableExpand || !wrapper.value) return\r\n\r\n let addedId: Key | undefined\r\n let removedId: Key | undefined\r\n\r\n for (const id of value) {\r\n if (!prev.has(id)) {\r\n if (addedId != null) return\r\n\r\n addedId = id\r\n }\r\n }\r\n\r\n for (const id of prev) {\r\n if (!value.has(id)) {\r\n if (removedId != null) return\r\n\r\n removedId = id\r\n }\r\n }\r\n\r\n if (addedId == null && removedId == null) return\r\n if (\r\n (addedId && !nodeMap.get(addedId)?.children?.length) ||\r\n (removedId && !nodeMap.get(removedId)?.children?.length)\r\n )\r\n return\r\n\r\n clearTimeout(timer.expand)\r\n\r\n transferring.value = false\r\n expanding.value = true\r\n\r\n let baseExpandedIds: Set<Key> | undefined\r\n\r\n if (addedId != null) {\r\n baseExpandedIds = prev\r\n }\r\n\r\n if (removedId != null) {\r\n if (!baseExpandedIds) {\r\n baseExpandedIds = value\r\n } else {\r\n baseExpandedIds = new Set(baseExpandedIds)\r\n baseExpandedIds.delete(removedId)\r\n }\r\n }\r\n\r\n const baseNodes = flatNodes(treeNodes.value, baseExpandedIds!)\r\n\r\n const virtual = props.virtual\r\n const viewHeight = wrapper.value.offsetHeight\r\n const nodeHeight = props.nodeMinHeight || 1\r\n const viewCount = Math.ceil(viewHeight / nodeHeight) + 1\r\n\r\n const loop = [\r\n addedId != null && { id: addedId, type: 'expand' },\r\n removedId != null && { id: removedId, type: 'reduce' },\r\n ]\r\n\r\n for (const meta of loop) {\r\n if (!meta) continue\r\n\r\n const { id, type } = meta\r\n const index = baseNodes.findIndex(node => node.id === id)\r\n\r\n if (~index) {\r\n const children = baseNodes[index].children\r\n\r\n if (children?.length) {\r\n const addedNodes = flatNodes(children, value)\r\n\r\n baseNodes.splice(index + 1, 0, {\r\n id: Symbol('TreeNodePlaceholder'),\r\n collapse: true,\r\n type,\r\n height: virtual ? addedNodes.length * nodeHeight : undefined,\r\n nodes: virtual ? addedNodes.slice(0, viewCount) : addedNodes,\r\n } as any)\r\n }\r\n }\r\n }\r\n\r\n expandingNodes.value = baseNodes\r\n})\r\n\r\nprovide(\r\n TREE_STATE,\r\n reactive({\r\n arrow: toRef(props, 'arrow'),\r\n checkbox: toRef(props, 'checkbox'),\r\n suffixCheckbox: toRef(props, 'suffixCheckbox'),\r\n noCascaded: toRef(props, 'noCascaded'),\r\n linkLine,\r\n virtual: toRef(props, 'virtual'),\r\n labelKey: toRef(keyConfig, 'label'),\r\n draggable: toRef(props, 'draggable'),\r\n floorSelect: toRef(props, 'floorSelect'),\r\n renderer: toRef(props, 'renderer'),\r\n prefixRenderer: toRef(props, 'prefixRenderer'),\r\n suffixRenderer: toRef(props, 'suffixRenderer'),\r\n arrowIcon: toRef(props, 'arrowIcon'),\r\n blockEffect: toRef(props, 'blockEffect'),\r\n dragging,\r\n boundAsyncLoad,\r\n nodeStates,\r\n expanding,\r\n keepSelected: toRef(props, 'keepSelected'),\r\n multiple: toRef(props, 'multiple'),\r\n getParentNode,\r\n updateVisibleNodeEls,\r\n computeCheckedState,\r\n handleNodeClick,\r\n handleNodeSelect,\r\n handleNodeCancel,\r\n handleNodeExpand,\r\n handleNodeReduce,\r\n handleNodeContextmenu,\r\n handleAsyncLoad,\r\n handleNodeDragStart,\r\n handleNodeDragOver,\r\n handleNodeDrop,\r\n handleNodeDragEnd,\r\n handleHittingChange,\r\n handleNodeHitting,\r\n handleLabelClick,\r\n }),\r\n)\r\nprovide(\r\n TREE_NODE_STATE,\r\n reactive({\r\n depth: -1,\r\n disabled: toRef(props, 'disabled'),\r\n readonly: toRef(props, 'readonly'),\r\n }),\r\n)\r\n\r\ndefineExpose({\r\n treeNodes,\r\n flattedNodes,\r\n dragging,\r\n expanding,\r\n\r\n virtualList,\r\n trap,\r\n indicator,\r\n\r\n refreshScroll,\r\n isLeafNode,\r\n parseAndTransformData,\r\n forceUpdateData,\r\n syncNodeStateIntoData,\r\n getCheckedNodes,\r\n getCheckedNodeData,\r\n getSelectedNodes,\r\n getSelectedNodeData,\r\n getExpandedNodes,\r\n getDisabledNodes,\r\n getParentNode,\r\n getNodeChildren,\r\n getSiblingNodes,\r\n getPrevSiblingNode,\r\n getNextSiblingNode,\r\n getNodeByData,\r\n expandNodeByData,\r\n selectNodeByData,\r\n checkNodeByData,\r\n toggleNodeLoadingByData,\r\n toggleAllExpanded,\r\n getTreeData,\r\n getFlattedData,\r\n updateVisibleNodeEls,\r\n})\r\n\r\nonMounted(updateVisibleNodeEls)\r\n\r\nconst { updateCheckedUpward, updateCheckedDown } = useCascadedChecked({\r\n getNode: key => nodeMap.get(key),\r\n disableNode: node => node.disabled,\r\n})\r\n\r\nfunction getIndexId() {\r\n return `__vxp-tree-key-${getGlobalCount()}`\r\n}\r\n\r\nfunction isLeafNode(node: TreeNodeProps) {\r\n const isLeaf = node.isLeaf\r\n\r\n let leafSign: boolean | 'auto' = 'auto'\r\n let asyncLoad = false\r\n\r\n if (isNull(isLeaf) || isLeaf === 'auto') {\r\n leafSign = 'auto'\r\n asyncLoad = boundAsyncLoad.value\r\n } else {\r\n leafSign = isLeaf\r\n }\r\n\r\n return leafSign === 'auto' ? !(node.children?.length || (asyncLoad && !node.loaded)) : !!leafSign\r\n}\r\n\r\nfunction flatNodes(nodes: TreeNodeProps[], expandedIds?: Set<Key>) {\r\n const rootNodes = new Set(nodes)\r\n\r\n return flatTree(nodes, {\r\n keyField: 'id',\r\n parentField: 'parent',\r\n childField: 'children',\r\n injectId: false,\r\n depthFirst: true,\r\n cascaded: true,\r\n filter: node => {\r\n if (rootNodes.has(node)) {\r\n return node.matched || node.childMatched || node.upperMatched\r\n }\r\n\r\n const parentNode = getParentNode(node)\r\n\r\n return (\r\n node.visible &&\r\n (node.matched || node.childMatched || node.upperMatched) &&\r\n (!parentNode || (expandedIds ? expandedIds.has(parentNode.id) : parentNode.expanded))\r\n )\r\n },\r\n })\r\n}\r\n\r\nfunction isCollapse(node: any): node is TreeCollapseProps {\r\n return node.collapse\r\n}\r\n\r\nfunction refreshNodesDepth() {\r\n walkTree(treeNodes.value, (node, depth) => {\r\n node.depth = depth\r\n node.lineIndexes = [0]\r\n\r\n if (node.parent && nodeMap.has(node.parent)) {\r\n const parent = nodeMap.get(node.parent)!\r\n\r\n node.last = getLast(parent.children) === node\r\n node.upstreamLast = [parent.last, ...parent.upstreamLast]\r\n } else {\r\n node.last = getLast(treeNodes.value) === node\r\n node.upstreamLast = []\r\n }\r\n\r\n for (let i = 1; i < depth; ++i) {\r\n if (!node.upstreamLast[i - 1]) {\r\n node.lineIndexes.push(i)\r\n }\r\n }\r\n })\r\n}\r\n\r\nfunction buildTreeNodes(nodes: TreeNodeProps[]) {\r\n treeNodes.value = transformTree(nodes, {\r\n keyField: 'id',\r\n parentField: 'parent',\r\n childField: 'children',\r\n rootId: props.rootId,\r\n })\r\n\r\n refreshNodesDepth()\r\n}\r\n\r\nfunction parseAndTransformData() {\r\n const idKey = keyConfig.id\r\n const oldDataMap = new Map<Data, TreeNodeProps>()\r\n const oldIdMap = new Map<any, TreeNodeProps>()\r\n\r\n for (const node of nodeMap.values()) {\r\n oldDataMap.set(node.data, node)\r\n oldIdMap.set(node.data[idKey], node)\r\n }\r\n\r\n nodeMap.clear()\r\n nodeDataMap.clear()\r\n\r\n const nodes: TreeNodeProps[] = []\r\n\r\n if (props.noBuildTree) {\r\n walkTree(\r\n props.data,\r\n (item, _, parent) => {\r\n const oldNode = oldDataMap.get(item)\r\n const id = oldNode?.id ?? getIndexId()\r\n const node = props.cacheNode\r\n ? (oldNode ?? createNodeItem(item))\r\n : createNodeItem(item, oldNode)\r\n\r\n node.id = id\r\n node.parent = parent ? nodeDataMap.get(parent)?.id : undefined\r\n\r\n nodeMap.set(node.id, node)\r\n nodes.push(node)\r\n nodeDataMap.set(item, node)\r\n },\r\n { childField: keyConfig.children, depthFirst: true },\r\n )\r\n } else {\r\n const data = props.data\r\n\r\n for (let i = 0, len = data.length; i < len; ++i) {\r\n const item = data[i]\r\n const oldNode = oldDataMap.get(item) ?? oldIdMap.get(item[idKey])\r\n const node = props.cacheNode\r\n ? (oldNode ?? createNodeItem(item))\r\n : createNodeItem(item, oldNode)\r\n\r\n nodeMap.set(node.id, node)\r\n nodes.push(node)\r\n nodeDataMap.set(item, node)\r\n }\r\n }\r\n\r\n buildTreeNodes(nodes)\r\n\r\n if (!props.noCascaded) {\r\n const checkedNodes = flattedNodes.value.filter(item => item.checked)\r\n\r\n for (let i = 0, len = checkedNodes.length; i < len; ++i) {\r\n const item = checkedNodes[i]\r\n const parentKey = item.parent\r\n\r\n updateCheckedDown(item.id)\r\n\r\n if (parentKey && nodeMap.has(parentKey)) {\r\n const parent = nodeMap.get(parentKey)!\r\n\r\n if (!parent.checked) {\r\n updateCheckedUpward(item.id)\r\n }\r\n }\r\n }\r\n }\r\n\r\n resetExpanded()\r\n}\r\n\r\nfunction forceUpdateData() {\r\n const nodes: TreeNodeProps[] = []\r\n\r\n const {\r\n id: idKey,\r\n visible: visibleKey,\r\n selected: selectedKey,\r\n expanded: expandedKey,\r\n disabled: disabledKey,\r\n checked: checkedKey,\r\n loading: loadingKey,\r\n loaded: loadedKey,\r\n loadFail: loadFailKey,\r\n readonly: readonlyKey,\r\n arrow: arrowKey,\r\n checkbox: checkboxKey,\r\n selectDisabled: selectDisabledKey,\r\n expandDisabled: expandDisabledKey,\r\n checkDisabled: checkDisabledKey,\r\n isLeaf: isLeafKey,\r\n } = keyConfig\r\n\r\n const refresh = (node: TreeNodeProps, item: Data) => {\r\n const {\r\n [visibleKey]: visible = node.visible,\r\n [selectedKey]: selected = node.selected,\r\n [expandedKey]: expanded = node.expanded,\r\n [disabledKey]: disabled = node.disabled,\r\n [checkedKey]: checked = node.checked,\r\n [loadingKey]: loading = node.loading,\r\n [loadedKey]: loaded = node.loaded,\r\n [loadFailKey]: loadFail = node.loadFail,\r\n [readonlyKey]: readonly = node.readonly,\r\n [arrowKey]: arrow = node.arrow,\r\n [checkboxKey]: checkbox = node.checkbox,\r\n [selectDisabledKey]: selectDisabled = node.selectDisabled,\r\n [expandDisabledKey]: expandDisabled = node.expandDisabled,\r\n [checkDisabledKey]: checkDisabled = node.checkDisabled,\r\n [isLeafKey]: isLeaf = node.isLeaf,\r\n } = item\r\n\r\n node.visible = visible\r\n node.selected = selected\r\n node.expanded = expanded\r\n node.disabled = disabled\r\n node.checked = checked\r\n node.loading = loading\r\n node.loaded = loaded\r\n node.loadFail = loadFail\r\n node.readonly = readonly\r\n node.arrow = arrow\r\n node.checkbox = checkbox\r\n node.selectDisabled = selectDisabled\r\n node.expandDisabled = expandDisabled\r\n node.checkDisabled = checkDisabled\r\n node.isLeaf = isLeaf\r\n }\r\n\r\n if (props.noBuildTree) {\r\n walkTree(\r\n props.data,\r\n (item, _, parent) => {\r\n let node = nodeDataMap.get(item)\r\n\r\n if (node) {\r\n refresh(node, item)\r\n } else {\r\n node = createNodeItem(item)\r\n node.id = getIndexId()\r\n node.parent = parent ? nodeDataMap.get(parent)?.id : undefined\r\n\r\n nodeMap.set(node.id, node)\r\n nodeDataMap.set(item, node)\r\n }\r\n\r\n nodes.push(node)\r\n },\r\n { childField: keyConfig.children, depthFirst: true },\r\n )\r\n } else {\r\n const data = props.data\r\n\r\n for (let i = 0, len = data.length; i < len; ++i) {\r\n const item = data[i]\r\n const id = item[idKey] as Key\r\n\r\n let node = nodeMap.get(id)\r\n\r\n if (node) {\r\n refresh(node, item)\r\n } else {\r\n node = createNodeItem(item)\r\n nodeMap.set(id, node)\r\n }\r\n\r\n nodes.push(node)\r\n }\r\n }\r\n\r\n buildTreeNodes(nodes)\r\n resetExpanded()\r\n}\r\n\r\nfunction syncNodeStateIntoData() {\r\n flattedNodes.value.forEach(node => {\r\n if (!node.data) return\r\n\r\n const { data, visible, selected, expanded, disabled, checked, loading, readonly } = node\r\n\r\n data.visible = visible\r\n data.selected = selected\r\n data.expanded = expanded\r\n data.disabled = disabled\r\n data.checked = checked\r\n data.loading = loading\r\n data.readonly = readonly\r\n })\r\n\r\n resetExpanded()\r\n}\r\n\r\nfunction createNodeItem(data: Data, defaults = defaultNodeProperties): TreeNodeProps {\r\n const {\r\n id: idKey,\r\n parent: parentKey,\r\n visible: visibleKey,\r\n selected: selectedKey,\r\n expanded: expandedKey,\r\n disabled: disabledKey,\r\n checked: checkedKey,\r\n loading: loadingKey,\r\n loaded: loadedKey,\r\n loadFail: loadFailKey,\r\n readonly: readonlyKey,\r\n arrow: arrowKey,\r\n checkbox: checkboxKey,\r\n selectDisabled: selectDisabledKey,\r\n expandDisabled: expandDisabledKey,\r\n checkDisabled: checkDisabledKey,\r\n isLeaf: isLeafKey,\r\n } = keyConfig\r\n\r\n const {\r\n [visibleKey]: visible = defaults.visible,\r\n [selectedKey]: selected = defaults.selected,\r\n [expandedKey]: expanded = defaults.expanded,\r\n [disabledKey]: disabled = defaults.disabled,\r\n [checkedKey]: checked = defaults.checked,\r\n [loadingKey]: loading = defaults.loading,\r\n [loadedKey]: loaded = defaults.loaded,\r\n [loadFailKey]: loadFail = defaults.loadFail,\r\n [readonlyKey]: readonly = defaults.readonly,\r\n [arrowKey]: arrow = defaults.arrow,\r\n [checkboxKey]: checkbox = defaults.checkbox,\r\n [selectDisabledKey]: selectDisabled = defaults.selectDisabled,\r\n [expandDisabledKey]: expandDisabled = defaults.expandDisabled,\r\n [checkDisabledKey]: checkDisabled = defaults.checkDisabled,\r\n [isLeafKey]: isLeaf = defaults.isLeaf,\r\n } = data\r\n const id = props.noBuildTree ? null : data[idKey]\r\n const parent = props.noBuildTree ? null : data[parentKey]\r\n\r\n const node = {\r\n id,\r\n parent,\r\n data,\r\n visible,\r\n selected,\r\n expanded,\r\n disabled,\r\n checked,\r\n loading,\r\n loaded,\r\n loadFail,\r\n readonly,\r\n arrow,\r\n checkbox,\r\n selectDisabled,\r\n expandDisabled,\r\n checkDisabled,\r\n isLeaf,\r\n }\r\n\r\n if (typeof props.postCreate === 'function') {\r\n props.postCreate(node as TreeNodeProps)\r\n }\r\n\r\n return reactive({\r\n ...node,\r\n id,\r\n parent,\r\n children: [],\r\n partial: false,\r\n matched: false,\r\n childMatched: false,\r\n upperMatched: false,\r\n depth: -1,\r\n last: false,\r\n // inLastCount: 0,\r\n upstreamLast: [],\r\n lineIndexes: [],\r\n })\r\n}\r\n\r\nfunction computeCheckedState(originNode: TreeNodeProps, able: boolean) {\r\n if (!props.noCascaded) {\r\n const nodeList = [originNode].concat(\r\n // 需要包含被禁用且被勾选的节点\r\n flattedNodes.value.filter(item => (item.disabled || item.checkDisabled) && item.checked),\r\n )\r\n\r\n for (let i = 0, len = nodeList.length; i < len; ++i) {\r\n const item = nodeList[i]\r\n\r\n updateCheckedUpward(item.id)\r\n updateCheckedDown(item.id)\r\n }\r\n }\r\n\r\n emitEvent(props.onNodeChange, originNode.data, originNode, able)\r\n}\r\n\r\nfunction handleNodeClick(node: TreeNodeProps) {\r\n emitEvent(props.onNodeClick, node.data, node)\r\n}\r\n\r\nfunction handleLabelClick(node: TreeNodeProps) {\r\n emitEvent(props.onLabelClick, node.data, node)\r\n}\r\n\r\nfunction handleNodeSelect(node: TreeNodeProps) {\r\n const selectedNodes = flattedNodes.value.filter(item => item.selected)\r\n\r\n if (props.multiple) {\r\n emitEvent(\r\n props.onNodeSelect,\r\n selectedNodes.map(item => item.data),\r\n selectedNodes,\r\n )\r\n } else {\r\n const currentId = node.id\r\n\r\n for (let i = 0, len = selectedNodes.length; i < len; ++i) {\r\n const item = selectedNodes[i]\r\n\r\n item.selected = item.id === currentId\r\n }\r\n\r\n emitEvent(props.onNodeSelect, node.data, node)\r\n }\r\n}\r\n\r\nfunction handleNodeCancel(node: TreeNodeProps) {\r\n emitEvent(props.onNodeCancel, node.data, node)\r\n}\r\n\r\nfunction handleNodeExpand(node: TreeNodeProps) {\r\n if (props.accordion) {\r\n const siblingNodes = getSiblingNodes(node)\r\n\r\n for (let i = 0, len = siblingNodes.length; i < len; ++i) {\r\n siblingNodes[i].expanded = false\r\n }\r\n }\r\n\r\n emitEvent(props.onNodeExpand, node.data, node)\r\n}\r\n\r\nfunction handleNodeReduce(node: TreeNodeProps) {\r\n emitEvent(props.onNodeReduce, node.data, node)\r\n}\r\n\r\nfunction handleNodeContextmenu(event: MouseEvent, node: TreeNodeProps) {\r\n emitEvent(props.onNodeContextmenu, event, node.data, node)\r\n}\r\n\r\nasync function handleAsyncLoad(node: TreeNodeProps) {\r\n if (!boundAsyncLoad.value) return false\r\n\r\n let result = props.onAsyncLoad(node.data, node)\r\n\r\n if (isPromise(result)) {\r\n result = await result\r\n }\r\n\r\n return result !== false\r\n}\r\n\r\nlet dragState: {\r\n draggingNode: TreeNodeProps,\r\n treeRect: DOMRect,\r\n willDropNode: TreeNodeProps | null,\r\n dropType: DropType,\r\n} | null = null\r\n\r\nfunction handleNodeDragStart(nodeInstance: TreeNodeInstance) {\r\n if (!wrapper.value) return\r\n\r\n dragState = {\r\n draggingNode: nodeInstance.node,\r\n treeRect: wrapper.value.getBoundingClientRect(),\r\n willDropNode: null,\r\n dropType: DropType.BEFORE,\r\n }\r\n\r\n dragging.value = true\r\n emitEvent(props.onDragStart, nodeInstance.node.data, nodeInstance.node)\r\n}\r\n\r\nfunction handleNodeDragOver(nodeInstance: TreeNodeInstance, event: DragEvent) {\r\n if (!dragState || !nodeInstance.el || !nodeInstance.arrow) return\r\n\r\n const dropNodeRect = nodeInstance.el.getBoundingClientRect()\r\n const treeRect = dragState.treeRect\r\n const dropArrowRect = nodeInstance.arrow.getBoundingClientRect()\r\n const prevPercent = 0.25\r\n const nextPercent = 0.75\r\n const distance = event.clientY - dropNodeRect.top\r\n const dropNodeHeight = dropArrowRect.height\r\n\r\n let dropType: DropType\r\n let indicatorTop = -9999\r\n let isIndicatorShow = true\r\n\r\n if (distance < dropNodeHeight * prevPercent) {\r\n dropType = DropType.BEFORE\r\n indicatorTop = dropArrowRect.top - treeRect.top\r\n } else if (distance > dropNodeHeight * nextPercent) {\r\n dropType = DropType.AFTER\r\n indicatorTop = dropArrowRect.bottom - treeRect.top\r\n } else {\r\n dropType = DropType.INNER\r\n isIndicatorShow = false\r\n }\r\n\r\n if (indicator.value) {\r\n indicator.value.style.top = `${indicatorTop}px`\r\n indicator.value.style.insetInlineStart = `${dropArrowRect.right - treeRect.left}px`\r\n }\r\n\r\n dragState.willDropNode = nodeInstance.node\r\n dragState.dropType = dropType\r\n\r\n indicatorShow.value = isIndicatorShow\r\n emitEvent(props.onDragOver, nodeInstance.node.data, nodeInstance.node)\r\n}\r\n\r\nfunction isLeftInsideRight(left: TreeNodeProps, right: TreeNodeProps) {\r\n if (!left || !right) return true\r\n\r\n while (left) {\r\n if (left === right || left.id === right.id) {\r\n return true\r\n }\r\n\r\n left = getParentNode(left)!\r\n }\r\n\r\n return false\r\n}\r\n\r\nfunction handleNodeDrop(nodeInstance: TreeNodeInstance) {\r\n if (!dragState) return\r\n\r\n const { draggingNode, willDropNode, dropType } = dragState\r\n\r\n if (!willDropNode || isLeftInsideRight(willDropNode, draggingNode)) return\r\n\r\n let currentId: Key\r\n let parent: TreeNodeProps | null\r\n\r\n if (draggingNode) {\r\n parent = getParentNode(draggingNode)\r\n\r\n if (!parent) {\r\n parent = {\r\n children: treeNodes.value,\r\n } as TreeNodeProps\r\n }\r\n\r\n currentId = draggingNode.id as Key\r\n removeArrayItem(parent.children, item => item.id === currentId)\r\n }\r\n\r\n if (dropType === DropType.INNER) {\r\n if (!Array.isArray(willDropNode.children)) {\r\n willDropNode.children = []\r\n }\r\n\r\n const children = Array.from(willDropNode.children as TreeNodeProps[])\r\n\r\n children.push(draggingNode)\r\n\r\n willDropNode.children = children\r\n draggingNode.parent = willDropNode.id\r\n } else {\r\n parent = getParentNode(willDropNode)\r\n\r\n if (!parent) {\r\n parent = {\r\n parent: undefined! as Key,\r\n children: treeNodes.value,\r\n } as TreeNodeProps\r\n }\r\n\r\n currentId = willDropNode.id\r\n const index = parent.children.findIndex(item => item.id === currentId)\r\n\r\n if (~index) {\r\n parent.children.splice(+(dropType === DropType.AFTER) + index, 0, draggingNode)\r\n\r\n draggingNode.parent = parent.id\r\n }\r\n }\r\n\r\n refreshNodesDepth()\r\n emitEvent(props.onDrop, nodeInstance.node.data, nodeInstance.node, dropType)\r\n}\r\n\r\nfunction handleNodeDragEnd(nodeInstance: TreeNodeInstance) {\r\n dragging.value = true\r\n indicatorShow.value = false\r\n dragState = null\r\n emitEvent(props.onDragEnd, nodeInstance.node.data, nodeInstance.node)\r\n}\r\n\r\nfunction handleHittingChange(type: 'up' | 'down') {\r\n const activeEl = document.activeElement\r\n\r\n if (!visibleNodeEls.length || !activeEl) return\r\n\r\n const index = visibleNodeEls.findIndex(nodeEl => nodeEl === activeEl)\r\n\r\n if (~index) {\r\n visibleNodeEls[\r\n (index + (type === 'up' ? -1 : 1) + visibleNodeEls.length) % visibleNodeEls.length\r\n ]?.focus()\r\n }\r\n}\r\n\r\nfunction handleNodeHitting(nodeEl?: HTMLElement | null) {\r\n if (!nodeEl || !visibleNodeEls.length) return\r\n\r\n if (visibleNodeEls.includes(nodeEl)) {\r\n nodeEl.focus()\r\n }\r\n}\r\n\r\nfunction handleScroll() {\r\n // onScroll()\r\n updateVisibleNodeEls()\r\n}\r\n\r\nfunction handleTreeFocus(event: FocusEvent) {\r\n const target = event.target as HTMLElement\r\n\r\n if (!visibleNodeEls.length || !target || !trap.value) {\r\n return\r\n }\r\n\r\n if (target === trap.value) {\r\n visibleNodeEls[0].focus()\r\n }\r\n}\r\n\r\nfunction refreshScroll() {\r\n virtualList.value?.refresh()\r\n}\r\n\r\nfunction resetExpanded() {\r\n expanding.value = false\r\n isMounted.value && updateVisibleNodeEls()\r\n}\r\n\r\nfunction afterExpand() {\r\n if (props.virtual) {\r\n resetExpanded()\r\n return\r\n }\r\n\r\n transferring.value = true\r\n\r\n requestAnimationFrame(() => {\r\n resetExpanded()\r\n timer.expand = setTimeout(() => {\r\n transferring.value = false\r\n }, 300)\r\n })\r\n}\r\n\r\nfunction getCheckedNodes(includePartial = false): TreeNodeProps[] {\r\n return flattedNodes.value.filter(item => item.checked || (includePartial && item.partial))\r\n}\r\n\r\nfunction getCheckedNodeData(includePartial = false) {\r\n return getCheckedNodes(includePartial).map(node => node.data)\r\n}\r\n\r\nfunction getSelectedNodes(): TreeNodeProps[] {\r\n return flattedNodes.value.filter(item => item.selected)\r\n}\r\n\r\nfunction getSelectedNodeData() {\r\n return getSelectedNodes().map(node => node.data)\r\n}\r\n\r\nfunction getExpandedNodes(): TreeNodeProps[] {\r\n return flattedNodes.value.filter(item => item.expanded)\r\n}\r\n\r\nfunction getDisabledNodes(): TreeNodeProps[] {\r\n return flattedNodes.value.filter(item => item.disabled)\r\n}\r\n\r\nfunction getParentNode(node: TreeNodeProps): TreeNodeProps | null {\r\n if (node.parent) {\r\n return nodeMap.get(node.parent) ?? null\r\n }\r\n\r\n return null\r\n}\r\n\r\nfunction getNodeChildren(node: TreeNodeProps) {\r\n return node.children\r\n}\r\n\r\nfunction getSiblingNodes(node: TreeNodeProps, includeSelf = false): TreeNodeProps[] {\r\n const parent = getParentNode(node)\r\n\r\n const currentId = node.id as Key\r\n const parentId = parent ? (parent.id as Key) : null\r\n\r\n return flattedNodes.value.filter(item => {\r\n const isChild = parentId === null ? !item.parent : item.parent === parentId\r\n\r\n if (isChild && !includeSelf) {\r\n return item.id !== currentId\r\n }\r\n\r\n return isChild\r\n })\r\n}\r\n\r\nfunction getPrevSiblingNode(node: TreeNodeProps): TreeNodeProps | null {\r\n const parent = getParentNode(node)\r\n\r\n if (!parent) return null\r\n\r\n const currentId = node.id\r\n const parentId = parent.id\r\n const children = flattedNodes.value.filter(item => item.parent === parentId)\r\n\r\n if (children && children.length) {\r\n const index = children.findIndex(item => item.id === currentId)\r\n\r\n if (index > 0) {\r\n return children[index - 1]\r\n }\r\n }\r\n\r\n return null\r\n}\r\n\r\nfunction getNextSiblingNode(node: TreeNodeProps): TreeNodeProps | null {\r\n const parent = getParentNode(node)\r\n\r\n if (!parent) return null\r\n\r\n const currentId = node.id\r\n const parentId = parent.id\r\n const children = flattedNodes.value.filter(item => item.parent === parentId)\r\n\r\n if (children && children.length) {\r\n const index = children.findIndex(item => item.id === currentId)\r\n\r\n if (!~index && index < children.length - 1) {\r\n return children[index + 1]\r\n }\r\n }\r\n\r\n return null\r\n}\r\n\r\nfunction getNodeByData<T extends Data>(data: T): TreeNodeProps | null {\r\n if (props.noBuildTree) {\r\n return flattedNodes.value.find(item => item.data === data) ?? null\r\n }\r\n\r\n const idKey = keyConfig.id\r\n\r\n return (\r\n flattedNodes.value.find(\r\n item => item.data === data || item.data[idKey] === data[idKey as keyof T],\r\n ) ?? null\r\n )\r\n}\r\n\r\nfunction expandNodeByData<T extends Data>(data: T, expanded?: boolean, upstream = false) {\r\n const node = getNodeByData(data)\r\n\r\n if (node) {\r\n node.expanded = isNull(expanded) ? !node.expanded : !!expanded\r\n\r\n if (upstream) {\r\n let parentNode = getParentNode(node)\r\n\r\n while (parentNode) {\r\n parentNode.expanded = node.expanded\r\n parentNode = getParentNode(parentNode)\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction selectNodeByData<T extends Data>(data: T, selected?: boolean) {\r\n const node = getNodeByData(data)\r\n\r\n if (node) {\r\n node.selected = isNull(selected) ? !node.selected : !!selected\r\n }\r\n}\r\n\r\nfunction checkNodeByData<T extends Data>(data: T, checked?: boolean) {\r\n const node = getNodeByData(data)\r\n\r\n if (node) {\r\n node.checked = isNull(checked) ? !node.checked : !!checked\r\n\r\n if (!props.noCascaded) {\r\n const nodeList = [node].concat(\r\n flattedNodes.value.filter(item => item.disabled && item.checked),\r\n )\r\n\r\n for (let i = 0, len = nodeList.length; i < len; ++i) {\r\n const item = nodeList[i]\r\n\r\n updateCheckedUpward(item.id)\r\n updateCheckedDown(item.id)\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction toggleNodeLoadingByData<T extends Data>(data: T, loading?: boolean) {\r\n const node = getNodeByData(data)\r\n\r\n if (node) {\r\n node.checked = isNull(loading) ? !node.loading : !!loading\r\n }\r\n}\r\n\r\nfunction toggleAllExpanded(expanded: boolean) {\r\n for (const node of flattedNodes.value) {\r\n if (!node.disabled && !node.expandDisabled && !node.loading && node.children?.length) {\r\n node.expanded = expanded\r\n }\r\n }\r\n}\r\n\r\nfunction getTreeData(withFilter = false) {\r\n return mapTree(\r\n withFilter\r\n ? filterTree(treeNodes.value, node => node.matched, {\r\n childField: 'children',\r\n leafOnly: props.filterLeaf,\r\n isLeaf: isLeafNode,\r\n })\r\n : treeNodes.value,\r\n node => ({ ...node.data }),\r\n )\r\n}\r\n\r\nfunction getFlattedData(withFilter = false) {\r\n return (\r\n withFilter\r\n ? flattedNodes.value.filter(node => node.matched || node.childMatched || node.upperMatched)\r\n : flattedNodes.value\r\n ).map(node => ({ ...node.data }))\r\n}\r\n\r\nconst transferring = ref(false)\r\n</script>\r\n\r\n<template>\r\n <VirtualList\r\n ref=\"virtualList\"\r\n :class=\"[nh.b(), nh.bs('vars'), props.inherit && nh.bm('inherit')]\"\r\n :inherit=\"props.inherit\"\r\n :items=\"renderedNodes\"\r\n :item-size=\"props.nodeMinHeight\"\r\n items-tag=\"ul\"\r\n :items-attrs=\"{ class: nh.be('list') }\"\r\n :hide-bar=\"!props.useYBar\"\r\n :ignore-resize=\"transferring\"\r\n :disabled=\"!props.virtual\"\r\n role=\"tree\"\r\n tabindex=\"-1\"\r\n :aria-disabled=\"props.disabled\"\r\n :aria-readonly=\"props.readonly\"\r\n :style=\"style\"\r\n @scroll=\"handleScroll\"\r\n >\r\n <template #prefix-trap>\r\n <div\r\n ref=\"trap\"\r\n tabindex=\"0\"\r\n role=\"none\"\r\n style=\"width: 0; height: 0; overflow: hidden; outline: none\"\r\n @focus=\"handleTreeFocus\"\r\n ></div>\r\n </template>\r\n <template #default=\"{ item: node }: { item: TreeNodeProps }\">\r\n <CollapseTransition\r\n v-if=\"isCollapse(node)\"\r\n appear\r\n :reverse=\"node.type === 'reduce'\"\r\n @after-enter=\"afterExpand\"\r\n >\r\n <div :class=\"nh.be('collapse')\" :style=\"{ height: `${node.height}px` }\">\r\n <TreeNode\r\n v-for=\"(innerNode, index) in node.nodes\"\r\n :key=\"innerNode.id ?? index\"\r\n v-bind=\"toNodeProps(innerNode.data, innerNode)\"\r\n :node=\"innerNode\"\r\n >\r\n <template v-if=\"slots.node || props.slots.node\" #default=\"payload\">\r\n <slot name=\"node\" v-bind=\"payload\">\r\n <Renderer :renderer=\"props.slots.node\" :data=\"payload\"></Renderer>\r\n </slot>\r\n </template>\r\n <template v-if=\"slots.arrow || props.slots.arrow\" #arrow=\"payload\">\r\n <slot name=\"arrow\" v-bind=\"payload\">\r\n <Renderer :renderer=\"props.slots.arrow\" :data=\"payload\"></Renderer>\r\n </slot>\r\n </template>\r\n <template v-if=\"slots.label || props.slots.label\" #label=\"payload\">\r\n <slot name=\"label\" v-bind=\"payload\">\r\n <Renderer :renderer=\"props.slots.label\" :data=\"payload\"></Renderer>\r\n </slot>\r\n </template>\r\n <template v-if=\"slots.prefix || props.slots.prefix\" #prefix=\"payload\">\r\n <slot name=\"prefix\" v-bind=\"payload\">\r\n <Renderer :renderer=\"props.slots.prefix\" :data=\"payload\"></Renderer>\r\n </slot>\r\n </template>\r\n <template v-if=\"slots.suffix || props.slots.suffix\" #suffix=\"payload\">\r\n <slot name=\"suffix\" v-bind=\"payload\">\r\n <Renderer :renderer=\"props.slots.suffix\" :data=\"payload\"></Renderer>\r\n </slot>\r\n </template>\r\n </TreeNode>\r\n </div>\r\n </CollapseTransition>\r\n <TreeNode v-else v-bind=\"toNodeProps(node.data, node)\" :node=\"node\">\r\n <template v-if=\"slots.node || props.slots.node\" #default=\"payload\">\r\n <slot name=\"node\" v-bind=\"payload\">\r\n <Renderer :renderer=\"props.slots.node\" :data=\"payload\"></Renderer>\r\n </slot>\r\n </template>\r\n <template v-if=\"slots.arrow || props.slots.arrow\" #arrow=\"payload\">\r\n <slot name=\"arrow\" v-bind=\"payload\">\r\n <Renderer :renderer=\"props.slots.arrow\" :data=\"payload\"></Renderer>\r\n </slot>\r\n </template>\r\n <template v-if=\"slots.label || props.slots.label\" #label=\"payload\">\r\n <slot name=\"label\" v-bind=\"payload\">\r\n <Renderer :renderer=\"props.slots.label\" :data=\"payload\"></Renderer>\r\n </slot>\r\n </template>\r\n <template v-if=\"slots.prefix || props.slots.prefix\" #prefix=\"payload\">\r\n <slot name=\"prefix\" v-bind=\"payload\">\r\n <Renderer :renderer=\"props.slots.prefix\" :data=\"payload\"></Renderer>\r\n </slot>\r\n </template>\r\n <template v-if=\"slots.suffix || props.slots.suffix\" #suffix=\"payload\">\r\n <slot name=\"suffix\" v-bind=\"payload\">\r\n <Renderer :renderer=\"props.slots.suffix\" :data=\"payload\"></Renderer>\r\n </slot>\r\n </template>\r\n </TreeNode>\r\n </template>\r\n <template #empty>\r\n <div :class=\"nh.be('empty-tip')\">\r\n <slot name=\"empty\">\r\n <Renderer :renderer=\"props.slots.empty\">\r\n {{ props.emptyText ?? locale.empty }}\r\n </Renderer>\r\n </slot>\r\n </div>\r\n </template>\r\n <template #suffix-trap>\r\n <div\r\n v-if=\"props.draggable\"\r\n v-show=\"indicatorShow\"\r\n ref=\"indicator\"\r\n :class=\"nh.be('indicator')\"\r\n ></div>\r\n </template>\r\n </VirtualList>\r\n</template>\r\n"],"names":["props","useProps","__props","value","createIconProp","slots","_useSlots","nh","useNameHelper","locale","useLocale","toRef","nodeMap","nodeDataMap","treeNodes","ref","flattedNodes","dragging","indicatorShow","keyConfig","reactive","defaultKeyConfig","nodeStates","expanding","expandingNodes","expandedNodeIds","timer","useSetTimeout","isMounted","useMounted","virtualList","trap","indicator","wrapper","computed","_a","visibleNodeEls","defaultNodeProperties","boundAsyncLoad","linkLine","style","visibleNodes","flatNodes","renderedNodes","toNodeProps","createDefaultFilter","pattern","data","label","updateVisibleNodeEls","debounce","queryAll","disableExpand","disableExpandTick","nextTick","watchEffect","nodes","filter","leafOnly","i","len","node","isLeafNode","parent","upper","resetExpanded","oldIds","ids","changed","watch","parseAndTransformData","flatTree","prev","addedId","removedId","id","_b","_d","_c","transferring","baseExpandedIds","baseNodes","virtual","viewHeight","nodeHeight","viewCount","loop","meta","type","index","children","addedNodes","provide","TREE_STATE","getParentNode","computeCheckedState","handleNodeClick","handleNodeSelect","handleNodeCancel","handleNodeExpand","handleNodeReduce","handleNodeContextmenu","handleAsyncLoad","handleNodeDragStart","handleNodeDragOver","handleNodeDrop","handleNodeDragEnd","handleHittingChange","handleNodeHitting","handleLabelClick","TREE_NODE_STATE","__expose","refreshScroll","forceUpdateData","syncNodeStateIntoData","getCheckedNodes","getCheckedNodeData","getSelectedNodes","getSelectedNodeData","getExpandedNodes","getDisabledNodes","getNodeChildren","getSiblingNodes","getPrevSiblingNode","getNextSiblingNode","getNodeByData","expandNodeByData","selectNodeByData","checkNodeByData","toggleNodeLoadingByData","toggleAllExpanded","getTreeData","getFlattedData","onMounted","updateCheckedUpward","updateCheckedDown","useCascadedChecked","key","getIndexId","getGlobalCount","isLeaf","leafSign","asyncLoad","isNull","expandedIds","rootNodes","parentNode","isCollapse","refreshNodesDepth","walkTree","depth","getLast","buildTreeNodes","transformTree","idKey","oldDataMap","oldIdMap","item","_","oldNode","createNodeItem","checkedNodes","parentKey","visibleKey","selectedKey","expandedKey","disabledKey","checkedKey","loadingKey","loadedKey","loadFailKey","readonlyKey","arrowKey","checkboxKey","selectDisabledKey","expandDisabledKey","checkDisabledKey","isLeafKey","refresh","visible","selected","expanded","disabled","checked","loading","loaded","loadFail","readonly","arrow","checkbox","selectDisabled","expandDisabled","checkDisabled","defaults","originNode","able","nodeList","emitEvent","selectedNodes","currentId","siblingNodes","event","result","isPromise","dragState","nodeInstance","DropType","dropNodeRect","treeRect","dropArrowRect","prevPercent","nextPercent","distance","dropNodeHeight","dropType","indicatorTop","isIndicatorShow","isLeftInsideRight","left","right","draggingNode","willDropNode","removeArrayItem","activeEl","nodeEl","handleScroll","handleTreeFocus","target","afterExpand","includePartial","includeSelf","parentId","isChild","upstream","withFilter","mapTree","filterTree","_createBlock","_unref","VirtualList","_normalizeClass","_createElementVNode","_withCtx","CollapseTransition","_normalizeStyle","_openBlock","_createElementBlock","_Fragment","innerNode","TreeNode","_mergeProps","_createSlots","payload","_renderSlot","_ctx","_createVNode","Renderer","_normalizeProps","_guardReactiveProps","_createTextVNode","_toDisplayString"],"mappings":";;;;;;;;;;;;;;;;;;;;AAqDM,UAAAA,IAAQC,GAAS,QADRC,IACwB;AAAA,MACrC,OAAO;AAAA,QACL,SAAS;AAAA,QACT,WAAW,CAAAC,MAAS,OAAOA,KAAU,aAAaA,MAAU;AAAA,MAC9D;AAAA,MACA,MAAM;AAAA,QACJ,SAAS,MAAM,CAAC;AAAA,QAChB,QAAQ;AAAA,MACV;AAAA,MACA,aAAa;AAAA,MACb,WAAW;AAAA,MACX,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,MACV,gBAAgB;AAAA,MAChB,UAAU;AAAA,QACR,SAAS;AAAA,QACT,QAAQ;AAAA,MACV;AAAA,MACA,gBAAgB;AAAA,QACd,SAAS;AAAA,QACT,QAAQ;AAAA,MACV;AAAA,MACA,gBAAgB;AAAA,QACd,SAAS;AAAA,QACT,QAAQ;AAAA,MACV;AAAA,MACA,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,aAAa;AAAA,QACX,SAAS;AAAA,QACT,QAAQ;AAAA,MACV;AAAA,MACA,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,WAAW,OAAO,CAAA;AAAA,MAClB,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,UAAU;AAAA,MACV,YAAY;AAAA,QACV,SAAS;AAAA,QACT,QAAQ;AAAA,MACV;AAAA,MACA,SAAS;AAAA,MACT,eAAe;AAAA,QACb,SAAS;AAAA,QACT,WAAW,OAASA,IAAQ;AAAA,MAC9B;AAAA,MACA,SAAS;AAAA,MACT,cAAc;AAAA,MACd,WAAWC,GAAe;AAAA,MAC1B,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,OAAO,OAAO,CAAC;AAAA,IAAA,CAChB,GAEKC,IAAQC,GAAwB,GAEhCC,IAAKC,GAAc,MAAM,GACzBC,KAASC,GAAU,QAAQC,EAAMX,GAAO,QAAQ,CAAC,GAEjDY,wBAAc,IAAwB,GACtCC,wBAAkB,IAAyB,GAC3CC,IAAYC,EAAqB,EAAE,GACnCC,IAAeD,EAAqB,EAAE,GACtCE,KAAWF,EAAI,EAAK,GACpBG,KAAgBH,EAAI,EAAK,GACzBI,IAAYC,GAAS,EAAE,GAAGC,IAAkB,GAC5CC,KAAaF,GAAa,oBAAA,KAAyB,GACnDG,IAAYR,EAAI,EAAK,GACrBS,KAAiBT,EAAqB,EAAE,GACxCU,KAAkBV,EAAQ,oBAAA,KAAU,GAEpC,EAAE,OAAAW,GAAM,IAAIC,GAAc,GAC1B,EAAE,WAAAC,GAAU,IAAIC,GAAW,GAE3BC,KAAcf,EAAwB,GACtCgB,KAAOhB,EAAiB,GACxBiB,IAAYjB,EAAiB,GAE7BkB,IAAUC,EAAS,MAAM;;AAAA,cAAAC,IAAAL,GAAY,UAAZ,gBAAAK,EAAmB;AAAA,KAAO;AAEzD,QAAIC,IAAgC,CAAC;AAErC,UAAMC,KAAwB;AAAA,MAC5B,SAAS;AAAA,MACT,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,MACV,SAAS;AAAA,MACT,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,UAAU;AAAA,MACV,OAAO;AAAA;AAAA,MAEP,UAAU;AAAA,MACV,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,QAAQ;AAAA,IACV,GAEMC,KAAiBJ,EAAS,MAAM,OAAOlC,EAAM,eAAgB,UAAU,GACvEuC,KAAWL,EAAS,MACjBlC,EAAM,aAAa,KAAO,WAAWA,EAAM,aAAa,SAAS,KAAQA,EAAM,QACvF,GACKwC,KAAQN,EAAS,OACd;AAAA,MACL,CAAC3B,EAAG,GAAG,cAAc,CAAC,GAAG,OAAOP,EAAM,UAAW,WAAW,GAAGA,EAAM,MAAM,OAAOA,EAAM;AAAA,MACxF,CAACO,EAAG,GAAG,gBAAgB,CAAC,GAAGgC,GAAS,SAAS;AAAA,IAC/C,EACD,GACKE,KAAeP,EAAS,MAAMQ,GAAU5B,EAAU,KAAK,CAAC,GACxD6B,KAAgBT,EAAS,MACtBX,EAAU,QAAQC,GAAe,QAAQiB,GAAa,KAC9D,GACKG,KAAcV,EAAS,MACpB,OAAOlC,EAAM,aAAc,aAAaA,EAAM,YAAY,MAAMA,EAAM,SAC9E;AAED,aAAS6C,GAAoB1C,GAAe;AAC1C,YAAM2C,IAAU9C,EAAM,aAAa,OAAOG,CAAK,EAAE,sBAAsBA;AAShE,aARyB,CAAQ4C,MAAA;AAChC,cAAAC,IAAQD,EAAK5B,EAAU,KAAK;AAElC,eAAOnB,EAAM,aACT,OAAOgD,CAAK,EAAE,kBAAkB,EAAE,SAASF,CAAO,IAClD,OAAOE,CAAK,EAAE,SAASF,CAAO;AAAA,MACpC;AAAA,IAEO;AAGH,UAAAG,IAAuBC,GAAS,MAAM;AAC1C,MAAIjB,EAAQ,UACOG,IAAAe,GAAS,IAAI5C,EAAG,GAAG,MAAM,CAAC,IAAI0B,EAAQ,KAAK;AAAA,OAE7D,GAAG;AAEN,QAAImB,KAAgB;AAEpB,aAASC,KAAoB;AACX,MAAAD,KAAA,IAEhBE,GAAS,MAAM;AACG,QAAAF,KAAA;AAAA,MAAA,CACjB;AAAA,IAAA;AAEH,IAAAG,GAAY,MAAM;AAChB,YAAMC,IAAQxC,EAAa;AAIvB,UAFcqC,GAAA,GAEbrD,EAAM,QAQJ;AACC,cAAAyD,IACJ,OAAOzD,EAAM,UAAW,aAAaA,EAAM,SAAS6C,GAAoB7C,EAAM,MAAM,GAChF0D,IAAW1D,EAAM;AAEd,iBAAA2D,IAAI,GAAGC,IAAMJ,EAAM,QAAQG,IAAIC,GAAK,EAAED,GAAG;AAC1C,gBAAAE,IAAOL,EAAMG,CAAC;AAEpB,cAAID,KAAY,CAACI,GAAWD,CAAI,GAAG;AACjC,YAAAA,EAAK,UAAU,IACfA,EAAK,eAAe,IACpBA,EAAK,eAAe;AAEpB;AAAA,UAAA;AAGF,gBAAME,IAASF,EAAK,SAASjD,EAAQ,IAAIiD,EAAK,MAAM,IAAI;AAMxD,cAJAA,EAAK,UAAUJ,EAAOI,EAAK,MAAMA,CAAI,GACrCA,EAAK,eAAe,IACpBA,EAAK,eAAe,CAAC,CAACE,MAAWA,EAAO,WAAWA,EAAO,eAEtDF,EAAK,SAAS;AAChB,gBAAIG,IAAQD;AAEL,mBAAAC,KAAS,CAACA,EAAM;AACrB,cAAAA,EAAM,eAAe,IACrBA,EAAM,WAAW,IACjBA,IAAQA,EAAM,SAASpD,EAAQ,IAAIoD,EAAM,MAAM,IAAI;AAAA,UACrD;AAAA,QACF;AAAA,MACF;AAtCS,iBAAAL,IAAI,GAAGC,IAAMJ,EAAM,QAAQG,IAAIC,GAAK,EAAED,GAAG;AAC1C,gBAAAE,IAAOL,EAAMG,CAAC;AAEpB,UAAAE,EAAK,UAAU,IACfA,EAAK,eAAe,IACpBA,EAAK,eAAe;AAAA,QAAA;AAoCV,MAAAI,EAAA;AAAA,IAAA,CACf,GACDV,GAAY,MAAM,OAAO,OAAOpC,GAAWnB,EAAM,SAAS,CAAC,GAC3DuD,GAAY,MAAM;AAChB,YAAMW,IAASzC,GAAgB,OACzB0C,wBAAU,IAAS;AAEzB,UAAIC,IAAU;AAEH,iBAAAP,KAAQ7C,EAAa;AAC9B,QAAI6C,EAAK,aACHM,EAAA,IAAIN,EAAK,EAAE,GAEX,CAACO,KAAW,CAACF,EAAO,IAAIL,EAAK,EAAE,MACvBO,IAAA;AAKhB,OAAIA,KAAWD,EAAI,SAASD,EAAO,UACjCzC,GAAgB,QAAQ0C;AAAA,IAC1B,CACD,GACDE;AAAA,MACE;AAAA,QACE,MAAMrE,EAAM;AAAA,QACZ,MAAMA,EAAM,KAAK;AAAA,QACjB,MAAMmB,EAAU;AAAA,QAChB,MAAMA,EAAU;AAAA,QAChB,MAAMA,EAAU;AAAA,QAChB,MAAMnB,EAAM;AAAA,MACd;AAAA,MACAsE;AAAA,MACA,EAAE,WAAW,GAAK;AAAA,IACpB,GACAD;AAAA,MACE,CAACvD,GAAW,MAAMd,EAAM,MAAM;AAAA,MAC9B,MAAM;AACS,QAAAgB,EAAA,QAAQuD,GAASzD,EAAU,OAAO;AAAA,UAC7C,UAAU;AAAA,UACV,aAAa;AAAA,UACb,YAAY;AAAA,UACZ,QAAQd,EAAM;AAAA,UACd,UAAU;AAAA,UACV,YAAY;AAAA,QAAA,CACb;AAAA,MACH;AAAA,MACA,EAAE,WAAW,GAAK;AAAA,IACpB,GACMqE,GAAA5C,IAAiB,CAACtB,GAAOqE,MAAS;;AAKtC,UAJIxE,EAAM,gBACaiD,EAAA,GAGnBjD,EAAM,gBAAgBoD,MAAiB,CAACnB,EAAQ,MAAO;AAEvD,UAAAwC,GACAC;AAEJ,iBAAWC,KAAMxE;AACf,YAAI,CAACqE,EAAK,IAAIG,CAAE,GAAG;AACjB,cAAIF,KAAW,KAAM;AAEX,UAAAA,IAAAE;AAAA,QAAA;AAId,iBAAWA,KAAMH;AACf,YAAI,CAACrE,EAAM,IAAIwE,CAAE,GAAG;AAClB,cAAID,KAAa,KAAM;AAEX,UAAAA,IAAAC;AAAA,QAAA;AAKhB,UADIF,KAAW,QAAQC,KAAa,QAEjCD,KAAW,GAACG,KAAAzC,IAAAvB,E