{"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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"}