{"version":3,"file":"tree.mjs","names":[],"sources":["../../../../../../../packages/components/table/src/store/tree.ts"],"sourcesContent":["import { computed, getCurrentInstance, ref, unref, watch } from 'vue'\nimport { isArray, isUndefined } from '@element-plus/utils'\nimport { getRowIdentity, walkTreeNode } from '../util'\n\nimport type { WatcherPropsData } from '.'\nimport type { DefaultRow, Table, TableProps, TreeNode } from '../table/defaults'\n\nexport interface TreeData extends TreeNode {\n  children?: string[]\n  lazy?: boolean\n  loaded?: boolean\n}\n\nfunction useTree<T extends DefaultRow>(watcherData: WatcherPropsData<T>) {\n  const expandRowKeys = ref<Array<string>>([])\n  const treeData = ref<Record<string, TreeData>>({})\n  const indent = ref(16)\n  const lazy = ref(false)\n  const lazyTreeNodeMap = ref<Record<string, T[]>>({})\n  const lazyColumnIdentifier = ref('hasChildren')\n  const childrenColumnName = ref('children')\n  const checkStrictly = ref(false)\n  const instance = getCurrentInstance() as Table<T>\n  const normalizedData = computed(() => {\n    if (!watcherData.rowKey.value) return {}\n    const data = watcherData.data.value || []\n    return normalize(data)\n  })\n  const normalizedLazyNode = computed(() => {\n    const rowKey = watcherData.rowKey.value\n    const keys = Object.keys(lazyTreeNodeMap.value)\n    const res: Record<string, { children: string[] }> = {}\n    if (!keys.length) return res\n    keys.forEach((key) => {\n      if (lazyTreeNodeMap.value[key].length) {\n        const item: (typeof res)[number] = { children: [] }\n        lazyTreeNodeMap.value[key].forEach((row) => {\n          const currentRowKey = getRowIdentity(row, rowKey)\n          item.children.push(currentRowKey)\n          if (row[lazyColumnIdentifier.value] && !res[currentRowKey]) {\n            res[currentRowKey] = { children: [] }\n          }\n        })\n        res[key] = item\n      }\n    })\n    return res\n  })\n\n  const normalize = (data: T[]) => {\n    const rowKey = watcherData.rowKey.value\n    const res = {} as Record<string, TreeData>\n    walkTreeNode(\n      data,\n      (parent, children, level) => {\n        const parentId = getRowIdentity(parent, rowKey)\n        if (isArray(children)) {\n          res[parentId] = {\n            children: children.map((row) => getRowIdentity(row, rowKey)),\n            level,\n          }\n        } else if (lazy.value) {\n          // 当 children 不存在且 lazy 为 true，该节点即为懒加载的节点\n          res[parentId] = {\n            children: [],\n            lazy: true,\n            level,\n          }\n        }\n      },\n      childrenColumnName.value,\n      lazyColumnIdentifier.value,\n      lazy.value\n    )\n    return res\n  }\n\n  const updateTreeData = (\n    ifChangeExpandRowKeys = false,\n    ifExpandAll?: boolean\n  ) => {\n    ifExpandAll ||= instance.store?.states.defaultExpandAll.value\n    const nested = normalizedData.value\n    const normalizedLazyNode_ = normalizedLazyNode.value\n    const keys = Object.keys(nested)\n    const newTreeData: Record<string, TreeData> = {}\n    if (keys.length) {\n      const oldTreeData = unref(treeData)\n      const rootLazyRowKeys: string[] = []\n      const getExpanded = (oldValue: TreeData, key: string) => {\n        if (ifChangeExpandRowKeys) {\n          if (expandRowKeys.value) {\n            return ifExpandAll || expandRowKeys.value.includes(key)\n          } else {\n            return !!(ifExpandAll || oldValue?.expanded)\n          }\n        } else {\n          const included =\n            ifExpandAll ||\n            (expandRowKeys.value && expandRowKeys.value.includes(key))\n          return !!(oldValue?.expanded || included)\n        }\n      }\n      // 合并 expanded 与 display，确保数据刷新后，状态不变\n      keys.forEach((key) => {\n        const oldValue = oldTreeData[key]\n        const newValue = { ...nested[key] }\n        newValue.expanded = getExpanded(oldValue, key)\n        if (newValue.lazy) {\n          const { loaded = false, loading = false } = oldValue || {}\n          newValue.loaded = !!loaded\n          newValue.loading = !!loading\n          rootLazyRowKeys.push(key)\n        }\n        newTreeData[key] = newValue\n      })\n      // 根据懒加载数据更新 treeData\n      const lazyKeys = Object.keys(normalizedLazyNode_)\n      if (lazy.value && lazyKeys.length && rootLazyRowKeys.length) {\n        lazyKeys.forEach((key) => {\n          const oldValue = oldTreeData[key]\n          const lazyNodeChildren = normalizedLazyNode_[key].children\n          if (rootLazyRowKeys.includes(key)) {\n            // 懒加载的 root 节点，更新一下原有的数据，原来的 children 一定是空数组\n            if (newTreeData[key].children?.length !== 0) {\n              throw new Error('[ElTable]children must be an empty array.')\n            }\n            newTreeData[key].children = lazyNodeChildren\n          } else {\n            const { loaded = false, loading = false } = oldValue || {}\n            newTreeData[key] = {\n              lazy: true,\n              loaded: !!loaded,\n              loading: !!loading,\n              expanded: getExpanded(oldValue, key),\n              children: lazyNodeChildren,\n              level: undefined,\n            }\n          }\n        })\n      }\n    }\n    treeData.value = newTreeData\n    instance.store?.updateTableScrollY()\n  }\n\n  watch(\n    () => expandRowKeys.value,\n    () => {\n      updateTreeData(true)\n    },\n    { deep: true }\n  )\n\n  watch(\n    () => normalizedData.value,\n    () => {\n      updateTreeData()\n    }\n  )\n  watch(\n    () => normalizedLazyNode.value,\n    () => {\n      updateTreeData()\n    }\n  )\n\n  const updateTreeExpandKeys = (value: string[]) => {\n    expandRowKeys.value = value\n    updateTreeData()\n  }\n  const isUseLazy = (data: TreeData) => {\n    return lazy.value && data && 'loaded' in data && !data.loaded\n  }\n  const toggleTreeExpansion = (row: T, expanded?: boolean) => {\n    instance.store.assertRowKey()\n\n    const rowKey = watcherData.rowKey.value\n    const id = getRowIdentity(row, rowKey)\n    const data = id && treeData.value[id]\n    if (id && data && 'expanded' in data) {\n      const oldExpanded = data.expanded\n      expanded = isUndefined(expanded) ? !data.expanded : expanded\n      treeData.value[id].expanded = expanded\n      if (oldExpanded !== expanded) {\n        instance.emit('expand-change', row, expanded)\n      }\n      expanded && isUseLazy(data) && loadData(row, id, data)\n      instance.store.updateTableScrollY()\n    }\n  }\n\n  const loadOrToggle = (row: T) => {\n    instance.store.assertRowKey()\n    const rowKey = watcherData.rowKey.value\n    const id = getRowIdentity(row, rowKey)\n    const data = treeData.value[id]\n    if (isUseLazy(data)) {\n      loadData(row, id, data)\n    } else {\n      toggleTreeExpansion(row, undefined)\n    }\n  }\n\n  const loadData = (row: T, key: string, treeNode: TreeNode) => {\n    const { load } = instance.props as unknown as TableProps<T>\n    if (load && !treeData.value[key].loaded) {\n      treeData.value[key].loading = true\n      load(row, treeNode, (data) => {\n        if (!isArray(data)) {\n          throw new TypeError('[ElTable] data must be an array')\n        }\n        treeData.value[key].loading = false\n        treeData.value[key].loaded = true\n        treeData.value[key].expanded = true\n        if (data.length) {\n          lazyTreeNodeMap.value = { ...lazyTreeNodeMap.value, [key]: data }\n        }\n        instance.emit('expand-change', row, true)\n      })\n    }\n  }\n\n  const updateKeyChildren = (key: string, data: T[]) => {\n    const { lazy, rowKey } = instance.props as unknown as TableProps<T>\n    if (!lazy) return\n    if (!rowKey) throw new Error('[Table] rowKey is required in updateKeyChild')\n\n    if (lazyTreeNodeMap.value[key]) {\n      lazyTreeNodeMap.value = { ...lazyTreeNodeMap.value, [key]: data }\n    }\n  }\n\n  return {\n    loadData,\n    loadOrToggle,\n    toggleTreeExpansion,\n    updateTreeExpandKeys,\n    updateTreeData,\n    updateKeyChildren,\n    normalize,\n    states: {\n      expandRowKeys,\n      treeData,\n      indent,\n      lazy,\n      lazyTreeNodeMap,\n      lazyColumnIdentifier,\n      childrenColumnName,\n      checkStrictly,\n    },\n  }\n}\n\nexport default useTree\n"],"mappings":"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"}