MCPcopy Create free account
hub / github.com/adobe/react-spectrum / moveItems

Function moveItems

packages/react-stately/src/data/useTreeData.ts:476–585  ·  view source on GitHub ↗
(
  state: TreeDataState<T>,
  keys: Iterable<Key>,
  toParent: TreeNode<T> | null,
  toIndex: number,
  updateTree: (
    items: TreeNode<T>[],
    key: Key | null,
    update: (node: TreeNode<T>) => TreeNode<T> | null,
    originalMap: Map<Key, TreeNode<T>>
  ) => TreeDataState<T>,
  addNode: (node: TreeNode<T>, map: Map<Key, TreeNode<T>>) => void
)

Source from the content-addressed store, hash-verified

474}
475
476function moveItems<T extends object>(
477 state: TreeDataState<T>,
478 keys: Iterable<Key>,
479 toParent: TreeNode<T> | null,
480 toIndex: number,
481 updateTree: (
482 items: TreeNode<T>[],
483 key: Key | null,
484 update: (node: TreeNode<T>) => TreeNode<T> | null,
485 originalMap: Map<Key, TreeNode<T>>
486 ) => TreeDataState<T>,
487 addNode: (node: TreeNode<T>, map: Map<Key, TreeNode<T>>) => void
488): TreeDataState<T> {
489 let {items, nodeMap} = state;
490
491 let parent = toParent;
492 let removeKeys = new Set(keys);
493 while (parent?.parentKey != null) {
494 if (removeKeys.has(parent.key)) {
495 throw new Error('Cannot move an item to be a child of itself.');
496 }
497 parent = nodeMap.get(parent.parentKey!) ?? null;
498 }
499
500 let originalToIndex = toIndex;
501
502 let keyArray = Array.isArray(keys) ? keys : [...keys];
503 // depth first search to put keys in order
504 let inOrderKeys: Map<Key, number> = new Map();
505 let removedItems: Array<TreeNode<T>> = [];
506 let newItems = items;
507 let newMap = nodeMap;
508 let i = 0;
509
510 function traversal(node, {inorder, postorder}) {
511 inorder?.(node);
512 if (node != null) {
513 for (let child of node.children ?? []) {
514 traversal(child, {inorder, postorder});
515 postorder?.(child);
516 }
517 }
518 }
519
520 function inorder(child) {
521 // in-order so we add items as we encounter them in the tree, then we can insert them in expected order later
522 if (keyArray.includes(child.key)) {
523 inOrderKeys.set(child.key, i++);
524 }
525 }
526
527 function postorder(child) {
528 // remove items and update the tree from the leaves and work upwards toward the root, this way
529 // we don't copy child node references from parents inadvertently
530 if (keyArray.includes(child.key)) {
531 removedItems.push({...newMap.get(child.key)!, parentKey: toParent?.key ?? null});
532 let {items: nextItems, nodeMap: nextMap} = updateTree(
533 newItems,

Callers 2

moveBeforeFunction · 0.85
moveAfterFunction · 0.85

Calls 6

traversalFunction · 0.85
addNodeFunction · 0.85
updateTreeFunction · 0.85
sliceMethod · 0.80
hasMethod · 0.65
sortMethod · 0.65

Tested by

no test coverage detected