{"mappings":"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","sources":["packages/react-stately/src/data/useTreeData.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Key} from '@react-types/shared';\nimport {useState} from 'react';\n\nexport interface TreeOptions<T extends object> {\n  /** Initial root items in the tree. */\n  initialItems?: T[],\n  /** The keys for the initially selected items. */\n  initialSelectedKeys?: Iterable<Key>,\n  /** A function that returns a unique key for an item object. */\n  getKey?: (item: T) => Key,\n  /** A function that returns the children for an item object. */\n  getChildren?: (item: T) => T[]\n}\n\ninterface TreeNode<T extends object> {\n  /** A unique key for the tree node. */\n  key: Key,\n  /** The key of the parent node. */\n  parentKey?: Key | null,\n  /** The value object for the tree node. */\n  value: T,\n  /** Children of the tree node. */\n  children: TreeNode<T>[] | null\n}\n\nexport interface TreeData<T extends object> {\n  /** The root nodes in the tree. */\n  items: TreeNode<T>[],\n\n  /** The keys of the currently selected items in the tree. */\n  selectedKeys: Set<Key>,\n\n  /** Sets the selected keys. */\n  setSelectedKeys(keys: Set<Key>): void,\n\n  /**\n   * Gets a node from the tree by key.\n   * @param key - The key of the item to retrieve.\n   */\n  getItem(key: Key): TreeNode<T> | undefined,\n\n  /**\n   * Inserts an item into a parent node as a child.\n   * @param parentKey - The key of the parent item to insert into. `null` for the root.\n   * @param index - The index within the parent to insert into.\n   * @param value - The value to insert.\n   */\n  insert(parentKey: Key | null, index: number, ...values: T[]): void,\n\n  /**\n   * Inserts items into the list before the item at the given key.\n   * @param key - The key of the item to insert before.\n   * @param values - The values to insert.\n   */\n  insertBefore(key: Key, ...values: T[]): void,\n\n  /**\n   * Inserts items into the list after the item at the given key.\n   * @param key - The key of the item to insert after.\n   * @param values - The values to insert.\n   */\n  insertAfter(key: Key, ...values: T[]): void,\n\n  /**\n   * Appends an item into a parent node as a child.\n   * @param parentKey - The key of the parent item to insert into. `null` for the root.\n   * @param value - The value to insert.\n   */\n  append(parentKey: Key | null, ...values: T[]): void,\n\n  /**\n   * Prepends an item into a parent node as a child.\n   * @param parentKey - The key of the parent item to insert into. `null` for the root.\n   * @param value - The value to insert.\n   */\n  prepend(parentKey: Key | null, ...value: T[]): void,\n\n  /**\n   * Removes an item from the tree by its key.\n   * @param key - The key of the item to remove.\n   */\n  remove(...keys: Key[]): void,\n\n  /**\n   * Removes all items from the tree that are currently\n   * in the set of selected items.\n   */\n  removeSelectedItems(): void,\n\n  /**\n   * Moves an item within the tree.\n   * @param key - The key of the item to move.\n   * @param toParentKey - The key of the new parent to insert into. `null` for the root.\n   * @param index - The index within the new parent to insert at.\n   */\n  move(key: Key, toParentKey: Key | null, index: number): void,\n\n  /**\n   * Moves one or more items before a given key.\n   * @param key - The key of the item to move the items before.\n   * @param keys - The keys of the items to move.\n   */\n  moveBefore(key: Key, keys: Iterable<Key>): void,\n\n  /**\n   * Moves one or more items after a given key.\n   * @param key - The key of the item to move the items after.\n   * @param keys - The keys of the items to move.\n   */\n  moveAfter(key: Key, keys: Iterable<Key>): void,\n\n  /**\n   * Updates an item in the tree.\n   * @param key - The key of the item to update.\n   * @param newValue - The new value for the item.\n   */\n  update(key: Key, newValue: T): void\n}\n\ninterface TreeDataState<T extends object> {\n    items: TreeNode<T>[],\n    nodeMap: Map<Key, TreeNode<T>>\n}\n\n/**\n * Manages state for an immutable tree data structure, and provides convenience methods to\n * update the data over time.\n */\nexport function useTreeData<T extends object>(options: TreeOptions<T>): TreeData<T> {\n  let {\n    initialItems = [],\n    initialSelectedKeys,\n    getKey = (item: any) => item.id ?? item.key,\n    getChildren = (item: any) => item.children\n  } = options;\n\n  // We only want to compute this on initial render.\n  let [tree, setItems] = useState<TreeDataState<T>>(() => buildTree(initialItems, new Map()));\n  let {items, nodeMap} = tree;\n\n  let [selectedKeys, setSelectedKeys] = useState(new Set<Key>(initialSelectedKeys || []));\n\n  function buildTree(initialItems: T[] | null = [], map: Map<Key, TreeNode<T>>, parentKey?: Key | null) {\n    if (initialItems == null) {\n      initialItems = [];\n    }\n    return {\n      items: initialItems.map(item => {\n        let node: TreeNode<T> = {\n          key: getKey(item),\n          parentKey: parentKey ?? null,\n          value: item,\n          children: null\n        };\n\n        node.children = buildTree(getChildren(item), map, node.key).items;\n        map.set(node.key, node);\n        return node;\n      }),\n      nodeMap: map\n    };\n  }\n\n  function updateTree(items: TreeNode<T>[], key: Key | null, update: (node: TreeNode<T>) => TreeNode<T> | null, originalMap: Map<Key, TreeNode<T>>) {\n    let node = key == null ? null : originalMap.get(key);\n    if (node == null) {\n      return {items, nodeMap: originalMap};\n    }\n    let map = new Map<Key, TreeNode<T>>(originalMap);\n\n    // Create a new node. If null, then delete the node, otherwise replace.\n    let newNode = update(node);\n    if (newNode == null) {\n      deleteNode(node, map);\n    } else {\n      addNode(newNode, map);\n    }\n\n    // Walk up the tree and update each parent to refer to the new children.\n    while (node && node.parentKey) {\n      let nextParent = map.get(node.parentKey)!;\n      let copy: TreeNode<T> = {\n        key: nextParent.key,\n        parentKey: nextParent.parentKey,\n        value: nextParent.value,\n        children: null\n      };\n\n      let children = nextParent.children;\n      if (newNode == null && children) {\n        children = children.filter(c => c !== node);\n      }\n\n      copy.children = children?.map(child => {\n        if (child === node) {\n          // newNode cannot be null here due to the above filter.\n          return newNode!;\n        }\n\n        return child;\n      }) ?? null;\n\n      map.set(copy.key, copy);\n\n      newNode = copy;\n      node = nextParent;\n    }\n\n    if (newNode == null) {\n      items = items.filter(c => c !== node);\n    }\n\n    return {\n      items: items.map(item => {\n        if (item === node) {\n          // newNode cannot be null here due to the above filter.\n          return newNode!;\n        }\n\n        return item;\n      }),\n      nodeMap: map\n    };\n  }\n\n  function addNode(node: TreeNode<T>, map: Map<Key, TreeNode<T>>) {\n    map.set(node.key, node);\n    if (node.children) {\n      for (let child of node.children) {\n        addNode(child, map);\n      }\n    }\n  }\n\n  function deleteNode(node: TreeNode<T>, map: Map<Key, TreeNode<T>>) {\n    map.delete(node.key);\n    if (node.children) {\n      for (let child of node.children) {\n        deleteNode(child, map);\n      }\n    }\n  }\n  return {\n    items,\n    selectedKeys,\n    setSelectedKeys,\n    getItem(key: Key) {\n      return nodeMap.get(key);\n    },\n    insert(parentKey: Key | null, index: number, ...values: T[]) {\n      setItems(({items, nodeMap: originalMap}) => {\n        let {items: newNodes, nodeMap: newMap} = buildTree(values, new Map(originalMap), parentKey);\n\n        // If parentKey is null, insert into the root.\n        if (parentKey == null) {\n          return {\n            items: [\n              ...items.slice(0, index),\n              ...newNodes,\n              ...items.slice(index)\n            ],\n            nodeMap: newMap\n          };\n        }\n\n        // Otherwise, update the parent node and its ancestors.\n        return updateTree(items, parentKey, parentNode => ({\n          key: parentNode.key,\n          parentKey: parentNode.parentKey,\n          value: parentNode.value,\n          children: [\n            ...parentNode.children!.slice(0, index),\n            ...newNodes,\n            ...parentNode.children!.slice(index)\n          ]\n        }), newMap);\n      });\n    },\n    insertBefore(key: Key, ...values: T[]): void {\n      let node = nodeMap.get(key);\n      if (!node) {\n        return;\n      }\n\n      let parentNode = nodeMap.get(node.parentKey!);\n      let nodes = parentNode ? parentNode.children : items;\n      let index = nodes!.indexOf(node);\n      this.insert(parentNode?.key ?? null, index, ...values);\n    },\n    insertAfter(key: Key, ...values: T[]): void {\n      let node = nodeMap.get(key);\n      if (!node) {\n        return;\n      }\n\n      let parentNode = nodeMap.get(node.parentKey!);\n      let nodes = parentNode ? parentNode.children : items;\n      let index = nodes!.indexOf(node);\n      this.insert(parentNode?.key ?? null, index + 1, ...values);\n    },\n    prepend(parentKey: Key | null, ...values: T[]) {\n      this.insert(parentKey, 0, ...values);\n    },\n    append(parentKey: Key | null, ...values: T[]) {\n      if (parentKey == null) {\n        this.insert(null, items.length, ...values);\n      } else {\n        let parentNode = nodeMap.get(parentKey);\n        if (!parentNode) {\n          return;\n        }\n\n        this.insert(parentKey, parentNode.children!.length, ...values);\n      }\n    },\n    remove(...keys: Key[]) {\n      if (keys.length === 0) {\n        return;\n      }\n\n      let newItems = items;\n      let prevMap = nodeMap;\n      let newTree;\n      for (let key of keys) {\n        newTree = updateTree(newItems, key, () => null, prevMap);\n        prevMap = newTree.nodeMap;\n        newItems = newTree.items;\n      }\n\n      setItems(newTree);\n\n      let selection = new Set(selectedKeys);\n      for (let key of selectedKeys) {\n        if (!newTree.nodeMap.has(key)) {\n          selection.delete(key);\n        }\n      }\n\n      setSelectedKeys(selection);\n    },\n    removeSelectedItems() {\n      this.remove(...selectedKeys);\n    },\n    move(key: Key, toParentKey: Key | null, index: number) {\n      setItems(({items, nodeMap: originalMap}) => {\n        let node = originalMap.get(key);\n        if (!node) {\n          return {items, nodeMap: originalMap};\n        }\n\n        let {items: newItems, nodeMap: newMap} = updateTree(items, key, () => null, originalMap);\n\n\n        const movedNode = {\n          ...node,\n          parentKey: toParentKey\n        };\n\n        // If parentKey is null, insert into the root.\n        if (toParentKey == null) {\n          addNode(movedNode, newMap);\n          return {items: [\n            ...newItems.slice(0, index),\n            movedNode,\n            ...newItems.slice(index)\n          ], nodeMap: newMap};\n        }\n\n        // Otherwise, update the parent node and its ancestors.\n        return updateTree(newItems, toParentKey, parentNode => ({\n          key: parentNode.key,\n          parentKey: parentNode.parentKey,\n          value: parentNode.value,\n          children: [\n            ...parentNode.children!.slice(0, index),\n            movedNode,\n            ...parentNode.children!.slice(index)\n          ]\n        }), newMap);\n      });\n    },\n    moveBefore(key: Key, keys: Iterable<Key>) {\n      setItems((prevState) => {\n        let {items, nodeMap} = prevState;\n        let node = nodeMap.get(key);\n        if (!node) {\n          return prevState;\n        }\n        let toParentKey = node.parentKey ?? null;\n        let parent: null | TreeNode<T> = null;\n        if (toParentKey != null) {\n          parent = nodeMap.get(toParentKey) ?? null;\n        }\n        let toIndex = parent?.children ? parent.children.indexOf(node) : items.indexOf(node);\n        return moveItems(prevState, keys, parent, toIndex, updateTree, addNode);\n      });\n    },\n    moveAfter(key: Key, keys: Iterable<Key>) {\n      setItems((prevState) => {\n        let {items, nodeMap} = prevState;\n        let node = nodeMap.get(key);\n        if (!node) {\n          return prevState;\n        }\n        let toParentKey = node.parentKey ?? null;\n        let parent: null | TreeNode<T> = null;\n        if (toParentKey != null) {\n          parent = nodeMap.get(toParentKey) ?? null;\n        }\n        let toIndex = parent?.children ? parent.children.indexOf(node) : items.indexOf(node);\n        toIndex++;\n        return moveItems(prevState, keys, parent, toIndex, updateTree, addNode);\n      });\n    },\n    update(oldKey: Key, newValue: T) {\n      setItems(({items, nodeMap: originalMap}) => updateTree(items, oldKey, oldNode => {\n        let node: TreeNode<T> = {\n          key: oldNode.key,\n          parentKey: oldNode.parentKey,\n          value: newValue,\n          children: null\n        };\n\n        let tree = buildTree(getChildren(newValue), originalMap, node.key);\n        node.children = tree.items;\n        return node;\n      }, originalMap));\n    }\n  };\n}\n\nfunction moveItems<T extends object>(\n  state: TreeDataState<T>,\n  keys: Iterable<Key>,\n  toParent: TreeNode<T> | null,\n  toIndex: number,\n  updateTree: (\n    items: TreeNode<T>[],\n    key: Key | null,\n    update: (node: TreeNode<T>) => TreeNode<T> | null,\n    originalMap: Map<Key, TreeNode<T>>\n  ) => TreeDataState<T>,\n  addNode: (node: TreeNode<T>, map: Map<Key, TreeNode<T>>) => void\n): TreeDataState<T> {\n  let {items, nodeMap} = state;\n\n  let parent = toParent;\n  let removeKeys = new Set(keys);\n  while (parent?.parentKey != null) {\n    if (removeKeys.has(parent.key)) {\n      throw new Error('Cannot move an item to be a child of itself.');\n    }\n    parent = nodeMap.get(parent.parentKey!) ?? null;\n  }\n\n  let originalToIndex = toIndex;\n\n  let keyArray = Array.isArray(keys) ? keys : [...keys];\n  // depth first search to put keys in order\n  let inOrderKeys: Map<Key, number> = new Map();\n  let removedItems: Array<TreeNode<T>> = [];\n  let newItems = items;\n  let newMap = nodeMap;\n  let i = 0;\n\n  function traversal(node, {inorder, postorder}) {\n    inorder?.(node);\n    if (node != null) {\n      for (let child of node.children ?? []) {\n        traversal(child, {inorder, postorder});\n        postorder?.(child);\n      }\n    }\n  }\n\n  function inorder(child) {\n    // in-order so we add items as we encounter them in the tree, then we can insert them in expected order later\n    if (keyArray.includes(child.key)) {\n      inOrderKeys.set(child.key, i++);\n    }\n  }\n\n  function postorder(child) {\n    // remove items and update the tree from the leaves and work upwards toward the root, this way\n    // we don't copy child node references from parents inadvertently\n    if (keyArray.includes(child.key)) {\n      removedItems.push({...newMap.get(child.key)!, parentKey: toParent?.key ?? null});\n      let {items: nextItems, nodeMap: nextMap} = updateTree(newItems, child.key, () => null, newMap);\n      newItems = nextItems;\n      newMap = nextMap;\n    }\n    // decrement the index if the child being removed is in the target parent and before the target index\n    // the root node is special, it is null, and will not have a key, however, a parentKey can still point to it\n    if ((child.parentKey === toParent\n      || child.parentKey === toParent?.key)\n      && keyArray.includes(child.key)\n      && (toParent?.children ? toParent.children.indexOf(child) : items.indexOf(child)) < originalToIndex) {\n      toIndex--;\n    }\n  }\n\n  traversal({children: items}, {inorder, postorder});\n\n  let inOrderItems = removedItems.sort((a, b) => inOrderKeys.get(a.key)! > inOrderKeys.get(b.key)! ? 1 : -1);\n  // If parentKey is null, insert into the root.\n  if (!toParent || toParent.key == null) {\n    inOrderItems.forEach(movedNode => {\n      addNode(movedNode, newMap); \n    });\n    return {items: [\n      ...newItems.slice(0, toIndex),\n      ...inOrderItems,\n      ...newItems.slice(toIndex)\n    ], nodeMap: newMap};\n  }\n\n  // Otherwise, update the parent node and its ancestors.\n  return updateTree(newItems, toParent.key, parentNode => ({\n    key: parentNode.key,\n    parentKey: parentNode.parentKey,\n    value: parentNode.value,\n    children: [\n      ...parentNode.children!.slice(0, toIndex),\n      ...inOrderItems,\n      ...parentNode.children!.slice(toIndex)\n    ]\n  }), newMap);\n}\n"],"names":[],"version":3,"file":"useTreeData.mjs.map"}