element-plus
Version:
A Component Library for Vue 3
1 lines • 13.9 kB
Source Map (JSON)
{"version":3,"file":"useTree.mjs","names":[],"sources":["../../../../../../../packages/components/tree-v2/src/composables/useTree.ts"],"sourcesContent":["import { computed, ref, shallowRef, watch } from 'vue'\nimport { isObject } from '@element-plus/utils'\nimport {\n CURRENT_CHANGE,\n NODE_CLICK,\n NODE_COLLAPSE,\n NODE_DROP,\n NODE_EXPAND,\n TreeOptionsEnum,\n} from '../virtual-tree'\nimport { useCheck } from './useCheck'\nimport { useFilter } from './useFilter'\n\nimport type {\n FixedSizeList,\n Alignment as ScrollStrategy,\n} from '@element-plus/components/virtual-list'\nimport type { SetupContext } from 'vue'\nimport type { treeEmits } from '../virtual-tree'\nimport type { CheckboxValueType } from '@element-plus/components/checkbox'\nimport type {\n Tree,\n TreeData,\n TreeKey,\n TreeNode,\n TreeNodeData,\n TreeProps,\n} from '../types'\n\nexport function useTree(\n props: TreeProps,\n emit: SetupContext<typeof treeEmits>['emit']\n) {\n const expandedKeySet = ref<Set<TreeKey>>(new Set())\n const currentKey = ref<TreeKey | undefined>()\n const tree = shallowRef<Tree | undefined>()\n const listRef = ref<typeof FixedSizeList | undefined>()\n\n const {\n isIndeterminate,\n isChecked,\n toggleCheckbox,\n getCheckedKeys,\n getCheckedNodes,\n getHalfCheckedKeys,\n getHalfCheckedNodes,\n setChecked,\n setCheckedKeys,\n } = useCheck(props, tree)\n\n const { doFilter, hiddenNodeKeySet, isForceHiddenExpandIcon } = useFilter(\n props,\n tree\n )\n\n const valueKey = computed(() => {\n return props.props?.value || TreeOptionsEnum.KEY\n })\n const childrenKey = computed(() => {\n return props.props?.children || TreeOptionsEnum.CHILDREN\n })\n const disabledKey = computed(() => {\n return props.props?.disabled || TreeOptionsEnum.DISABLED\n })\n const labelKey = computed(() => {\n return props.props?.label || TreeOptionsEnum.LABEL\n })\n\n const flattenTree = computed(() => {\n const expandedKeys = expandedKeySet.value\n const hiddenKeys = hiddenNodeKeySet.value\n const flattenNodes: TreeNode[] = []\n const nodes = tree.value?.treeNodes || []\n\n const stack: TreeNode[] = []\n for (let i = nodes.length - 1; i >= 0; --i) {\n stack.push(nodes[i])\n }\n while (stack.length) {\n const node = stack.pop()!\n if (hiddenKeys.has(node.key)) continue\n\n flattenNodes.push(node)\n if (node.children && expandedKeys.has(node.key)) {\n for (let i = node.children.length - 1; i >= 0; --i) {\n stack.push(node.children[i])\n }\n }\n }\n\n return flattenNodes\n })\n\n const isNotEmpty = computed(() => {\n return flattenTree.value.length > 0\n })\n\n function createTree(data: TreeData): Tree {\n const treeNodeMap: Map<TreeKey, TreeNode> = new Map()\n const levelTreeNodeMap: Map<number, TreeNode[]> = new Map()\n let maxLevel = 1\n function traverse(\n nodes: TreeData,\n level = 1,\n parent: TreeNode | undefined = undefined\n ) {\n const siblings: TreeNode[] = []\n for (const rawNode of nodes) {\n const value = getKey(rawNode)\n const node: TreeNode = {\n level,\n key: value,\n data: rawNode,\n }\n node.label = getLabel(rawNode)\n node.parent = parent\n const children = getChildren(rawNode)\n node.disabled = getDisabled(rawNode)\n node.isLeaf = !children || children.length === 0\n node.expanded = expandedKeySet.value.has(value)\n if (children && children.length) {\n node.children = traverse(children, level + 1, node)\n }\n siblings.push(node)\n treeNodeMap.set(value, node)\n if (!levelTreeNodeMap.has(level)) {\n levelTreeNodeMap.set(level, [])\n }\n levelTreeNodeMap.get(level)?.push(node)\n }\n if (level > maxLevel) {\n maxLevel = level\n }\n return siblings\n }\n const treeNodes: TreeNode[] = traverse(data)\n return {\n treeNodeMap,\n levelTreeNodeMap,\n maxLevel,\n treeNodes,\n }\n }\n\n function filter(query: string) {\n const keys = doFilter(query)\n if (keys) {\n expandedKeySet.value = keys\n }\n }\n\n function getChildren(node: TreeNodeData): TreeNodeData[] {\n return node[childrenKey.value]\n }\n\n function getKey(node: TreeNodeData): TreeKey {\n if (!node) {\n return ''\n }\n return node[valueKey.value]\n }\n\n function getDisabled(node: TreeNodeData): boolean {\n return node[disabledKey.value]\n }\n\n function getLabel(node: TreeNodeData): string {\n return node[labelKey.value]\n }\n\n function toggleExpand(node: TreeNode) {\n const expandedKeys = expandedKeySet.value\n if (expandedKeys.has(node.key)) {\n collapseNode(node)\n } else {\n expandNode(node)\n }\n }\n\n function setExpandedKeys(keys: TreeKey[]) {\n const expandedKeys = new Set<TreeKey>()\n const nodeMap = tree.value!.treeNodeMap\n\n expandedKeySet.value.forEach((key) => {\n const node = nodeMap.get(key)\n if (node) node.expanded = false\n })\n\n keys.forEach((k) => {\n let node = nodeMap.get(k)\n while (node && !expandedKeys.has(node.key)) {\n expandedKeys.add(node.key)\n node.expanded = true\n node = node.parent\n }\n })\n\n expandedKeySet.value = expandedKeys\n }\n\n function handleNodeClick(node: TreeNode, e: MouseEvent) {\n emit(NODE_CLICK, node.data, node, e)\n handleCurrentChange(node)\n if (props.expandOnClickNode) {\n toggleExpand(node)\n }\n if (\n props.showCheckbox &&\n (props.checkOnClickNode || (node.isLeaf && props.checkOnClickLeaf)) &&\n !node.disabled\n ) {\n toggleCheckbox(node, !isChecked(node), true)\n }\n }\n\n function handleNodeDrop(node: TreeNode, e: DragEvent) {\n emit(NODE_DROP, node.data, node, e)\n }\n\n function handleCurrentChange(node: TreeNode) {\n if (!isCurrent(node)) {\n currentKey.value = node.key\n emit(CURRENT_CHANGE, node.data, node)\n }\n }\n\n function handleNodeCheck(node: TreeNode, checked: CheckboxValueType) {\n toggleCheckbox(node, checked)\n }\n\n function expandNode(node: TreeNode) {\n const keySet = expandedKeySet.value\n if (tree.value && props.accordion) {\n // whether only one node among the same level can be expanded at one time\n const { treeNodeMap } = tree.value\n keySet.forEach((key) => {\n const treeNode = treeNodeMap.get(key)\n if (node && node.level === treeNode?.level) {\n keySet.delete(key)\n treeNode.expanded = false\n }\n })\n }\n keySet.add(node.key)\n const _node = getNode(node.key)\n if (_node) {\n _node.expanded = true\n emit(NODE_EXPAND, _node.data, _node)\n }\n }\n\n function collapseNode(node: TreeNode) {\n expandedKeySet.value.delete(node.key)\n const _node = getNode(node.key)\n if (_node) {\n _node.expanded = false\n emit(NODE_COLLAPSE, _node.data, _node)\n }\n }\n\n function isDisabled(node: TreeNode): boolean {\n return !!node.disabled\n }\n\n function isCurrent(node: TreeNode): boolean {\n const current = currentKey.value\n return current !== undefined && current === node.key\n }\n\n function getCurrentNode(): TreeNodeData | undefined {\n if (!currentKey.value) return undefined\n return tree.value?.treeNodeMap.get(currentKey.value)?.data\n }\n\n function getCurrentKey(): TreeKey | undefined {\n return currentKey.value\n }\n\n function setCurrentKey(key: TreeKey): void {\n currentKey.value = key\n }\n\n function setData(data: TreeData) {\n tree.value = createTree(data)\n }\n\n function getNode(data: TreeKey | TreeNodeData) {\n const key = isObject(data) ? getKey(data) : data\n return tree.value?.treeNodeMap.get(key)\n }\n\n function scrollToNode(key: TreeKey, strategy: ScrollStrategy = 'auto') {\n const node = getNode(key)\n if (node && listRef.value) {\n listRef.value.scrollToItem(flattenTree.value.indexOf(node), strategy)\n }\n }\n\n function scrollTo(offset: number) {\n listRef.value?.scrollTo(offset)\n }\n\n watch(\n () => props.currentNodeKey,\n (key) => {\n currentKey.value = key\n },\n {\n immediate: true,\n }\n )\n\n watch(\n () => props.defaultExpandedKeys,\n (keys) => {\n setExpandedKeys(keys || [])\n }\n )\n\n watch(\n () => props.data!,\n (data: TreeData) => {\n setData(data)\n setExpandedKeys(props.defaultExpandedKeys || [])\n },\n {\n immediate: true,\n }\n )\n\n return {\n tree,\n flattenTree,\n isNotEmpty,\n listRef,\n getKey,\n getChildren,\n toggleExpand,\n toggleCheckbox,\n isChecked,\n isIndeterminate,\n isDisabled,\n isCurrent,\n isForceHiddenExpandIcon,\n handleNodeClick,\n handleNodeDrop,\n handleNodeCheck,\n // expose\n getCurrentNode,\n getCurrentKey,\n setCurrentKey,\n getCheckedKeys,\n getCheckedNodes,\n getHalfCheckedKeys,\n getHalfCheckedNodes,\n setChecked,\n setCheckedKeys,\n filter,\n setData,\n getNode,\n expandNode,\n collapseNode,\n setExpandedKeys,\n scrollToNode,\n scrollTo,\n }\n}\n"],"mappings":"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"}