@react-stately/data 3.0.0-nightly-a166aaab8-250421 → 3.0.0-nightly-e4ec6b4e9-250422

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/types.d.ts CHANGED
@@ -244,6 +244,18 @@ export interface TreeData<T extends object> {
244
244
  * @param index - The index within the new parent to insert at.
245
245
  */
246
246
  move(key: Key, toParentKey: Key | null, index: number): void;
247
+ /**
248
+ * Moves one or more items before a given key.
249
+ * @param key - The key of the item to move the items before.
250
+ * @param keys - The keys of the items to move.
251
+ */
252
+ moveBefore(key: Key, keys: Iterable<Key>): void;
253
+ /**
254
+ * Moves one or more items after a given key.
255
+ * @param key - The key of the item to move the items after.
256
+ * @param keys - The keys of the items to move.
257
+ */
258
+ moveAfter(key: Key, keys: Iterable<Key>): void;
247
259
  /**
248
260
  * Updates an item in the tree.
249
261
  * @param key - The key of the item to update.
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-stately/data/src/packages/@react-stately/data/src/useListData.ts","packages/@react-stately/data/src/packages/@react-stately/data/src/useAsyncList.ts","packages/@react-stately/data/src/packages/@react-stately/data/src/useTreeData.ts","packages/@react-stately/data/src/packages/@react-stately/data/src/index.ts","packages/@react-stately/data/src/index.ts"],"sourcesContent":[null,null,null,null,"/*\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\nexport {useAsyncList} from './useAsyncList';\nexport {useTreeData} from './useTreeData';\nexport {useListData} from './useListData';\n\nexport type {ListOptions, ListData} from './useListData';\nexport type {AsyncListOptions, AsyncListData} from './useAsyncList';\nexport type {TreeOptions, TreeData} from './useTreeData';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
1
+ {"mappings":";AAeA,6BAA6B,CAAC;IAC5B,iCAAiC;IACjC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC;IACnB,iDAAiD;IACjD,mBAAmB,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC5C,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,GAAG,CAAC;IAC1B,8EAA8E;IAC9E,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAA;CAClD;AAED,0BAA0B,CAAC;IACzB,6BAA6B;IAC7B,KAAK,EAAE,CAAC,EAAE,CAAC;IAEX,4DAA4D;IAC5D,YAAY,EAAE,SAAS,CAAC;IAExB,8BAA8B;IAC9B,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAEvC,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IAEnB,4BAA4B;IAC5B,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAExC;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,SAAS,CAAC;IAEjC;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;IAE5C;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;IAE7C;;;;OAIG;IACH,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;IAE5C;;;OAGG;IACH,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;IAE7B;;;OAGG;IACH,OAAO,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;IAE9B;;;OAGG;IACH,MAAM,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAE7B;;;OAGG;IACH,mBAAmB,IAAI,IAAI,CAAC;IAE5B;;;;OAIG;IACH,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtC;;;;OAIG;IACH,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAEhD;;;;OAIG;IACH,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAE/C;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAA;CACpC;AAYD;;;GAGG;AACH,4BAA4B,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CA4BnE;ACtJD,kCAAkC,CAAC,EAAE,CAAC;IACpC,iDAAiD;IACjD,mBAAmB,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IACpC,mCAAmC;IACnC,qBAAqB,CAAC,EAAE,cAAc,CAAC;IACvC,+BAA+B;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,GAAG,CAAC;IAC1B,gEAAgE;IAChE,IAAI,EAAE,sBAAsB,CAAC,EAAE,CAAC,CAAC,CAAC;IAClC;;;OAGG;IACH,IAAI,CAAC,EAAE,sBAAsB,CAAC,EAAE,CAAC,EAAE,qBAAqB,CAAC,EAAE,CAAC,CAAC,GAAG;QAAC,cAAc,EAAE,cAAc,CAAA;KAAC,CAAC,CAAA;CAClG;AAED,2BAA2B,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,qBAAqB,CAAC,EAAE,CAAC,CAAC,GAAG,qBAAqB,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,qBAAqB,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAErL,+BAA+B,CAAC,EAAE,CAAC;IACjC,uCAAuC;IACvC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,4DAA4D;IAC5D,YAAY,EAAE,SAAS,CAAC;IACxB,gDAAgD;IAChD,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,0FAA0F;IAC1F,MAAM,EAAE,WAAW,CAAC;IACpB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,CAAC,CAAC;IACX,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,YAAY,CAAC,EAAE,YAAY,CAAA;CAC5B;AAED,+BAA+B,CAAC,EAAE,CAAC;IACjC,2CAA2C;IAC3C,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnB,wCAAwC;IACxC,YAAY,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC7B,kCAAkC;IAClC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,+DAA+D;IAC/D,MAAM,CAAC,EAAE,CAAC,CAAC;IACX,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AA4BD,+BAA+B,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC;IACnD,8CAA8C;IAC9C,SAAS,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,KAAK,CAAC;IAId,gDAAgD;IAChD,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC,oCAAoC;IACpC,MAAM,IAAI,IAAI,CAAC;IACf,+CAA+C;IAC/C,QAAQ,IAAI,IAAI,CAAC;IACjB,qCAAqC;IACrC,IAAI,CAAC,UAAU,EAAE,cAAc,GAAG,IAAI,CAAC;IACvC,8CAA8C;IAC9C,YAAY,EAAE,YAAY,CAAA;CAC3B;AAyJD;;;GAGG;AACH,6BAA6B,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAwF7F;ACrVD,6BAA6B,CAAC,SAAS,MAAM;IAC3C,sCAAsC;IACtC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC;IACnB,iDAAiD;IACjD,mBAAmB,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IACpC,+DAA+D;IAC/D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,GAAG,CAAC;IAC1B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAA;CAC/B;AAED,mBAAmB,CAAC,SAAS,MAAM;IACjC,sCAAsC;IACtC,GAAG,EAAE,GAAG,CAAC;IACT,kCAAkC;IAClC,SAAS,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IACvB,0CAA0C;IAC1C,KAAK,EAAE,CAAC,CAAC;IACT,iCAAiC;IACjC,QAAQ,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG,IAAI,CAAA;CAC/B;AAED,0BAA0B,CAAC,SAAS,MAAM;IACxC,kCAAkC;IAClC,KAAK,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;IAErB,4DAA4D;IAC5D,YAAY,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAEvB,8BAA8B;IAC9B,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAEtC;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC;IAE3C;;;;;OAKG;IACH,MAAM,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;IAEnE;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;IAE7C;;;;OAIG;IACH,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;IAE5C;;;;OAIG;IACH,MAAM,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;IAEpD;;;;OAIG;IACH,OAAO,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;IAEpD;;;OAGG;IACH,MAAM,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAE7B;;;OAGG;IACH,mBAAmB,IAAI,IAAI,CAAC;IAE5B;;;;;OAKG;IACH,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7D;;;;OAIG;IACH,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAEhD;;;;OAIG;IACH,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAE/C;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAA;CACpC;AAOD;;;GAGG;AACH,4BAA4B,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CA+SlF","sources":["packages/@react-stately/data/src/packages/@react-stately/data/src/useListData.ts","packages/@react-stately/data/src/packages/@react-stately/data/src/useAsyncList.ts","packages/@react-stately/data/src/packages/@react-stately/data/src/useTreeData.ts","packages/@react-stately/data/src/packages/@react-stately/data/src/index.ts","packages/@react-stately/data/src/index.ts"],"sourcesContent":[null,null,null,null,"/*\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\nexport {useAsyncList} from './useAsyncList';\nexport {useTreeData} from './useTreeData';\nexport {useListData} from './useListData';\n\nexport type {ListOptions, ListData} from './useListData';\nexport type {AsyncListOptions, AsyncListData} from './useAsyncList';\nexport type {TreeOptions, TreeData} from './useTreeData';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
@@ -32,7 +32,7 @@ function $2d16d1aab63a81f4$export$d14e1352e21f4a16(options) {
32
32
  items: initialItems.map((item)=>{
33
33
  let node = {
34
34
  key: getKey(item),
35
- parentKey: parentKey,
35
+ parentKey: parentKey !== null && parentKey !== void 0 ? parentKey : null,
36
36
  value: item,
37
37
  children: null
38
38
  };
@@ -44,8 +44,8 @@ function $2d16d1aab63a81f4$export$d14e1352e21f4a16(options) {
44
44
  };
45
45
  }
46
46
  function updateTree(items, key, update, originalMap) {
47
- let node = originalMap.get(key);
48
- if (!node) return {
47
+ let node = key == null ? null : originalMap.get(key);
48
+ if (node == null) return {
49
49
  items: items,
50
50
  nodeMap: originalMap
51
51
  };
@@ -186,6 +186,8 @@ function $2d16d1aab63a81f4$export$d14e1352e21f4a16(options) {
186
186
  };
187
187
  // If parentKey is null, insert into the root.
188
188
  if (toParentKey == null) {
189
+ // safe to reuse the original map since no node was actually removed, so we just need to update the one moved node
190
+ newMap = new Map(originalMap);
189
191
  newMap.set(movedNode.key, movedNode);
190
192
  return {
191
193
  items: [
@@ -209,6 +211,35 @@ function $2d16d1aab63a81f4$export$d14e1352e21f4a16(options) {
209
211
  }), newMap);
210
212
  });
211
213
  },
214
+ moveBefore (key, keys) {
215
+ setItems((prevState)=>{
216
+ let { items: items, nodeMap: nodeMap } = prevState;
217
+ let node = nodeMap.get(key);
218
+ if (!node) return prevState;
219
+ var _node_parentKey;
220
+ let toParentKey = (_node_parentKey = node.parentKey) !== null && _node_parentKey !== void 0 ? _node_parentKey : null;
221
+ let parent = null;
222
+ var _nodeMap_get;
223
+ if (toParentKey != null) parent = (_nodeMap_get = nodeMap.get(toParentKey)) !== null && _nodeMap_get !== void 0 ? _nodeMap_get : null;
224
+ let toIndex = (parent === null || parent === void 0 ? void 0 : parent.children) ? parent.children.indexOf(node) : items.indexOf(node);
225
+ return $2d16d1aab63a81f4$var$moveItems(prevState, keys, parent, toIndex, updateTree);
226
+ });
227
+ },
228
+ moveAfter (key, keys) {
229
+ setItems((prevState)=>{
230
+ let { items: items, nodeMap: nodeMap } = prevState;
231
+ let node = nodeMap.get(key);
232
+ if (!node) return prevState;
233
+ var _node_parentKey;
234
+ let toParentKey = (_node_parentKey = node.parentKey) !== null && _node_parentKey !== void 0 ? _node_parentKey : null;
235
+ let parent = null;
236
+ var _nodeMap_get;
237
+ if (toParentKey != null) parent = (_nodeMap_get = nodeMap.get(toParentKey)) !== null && _nodeMap_get !== void 0 ? _nodeMap_get : null;
238
+ let toIndex = (parent === null || parent === void 0 ? void 0 : parent.children) ? parent.children.indexOf(node) : items.indexOf(node);
239
+ toIndex++;
240
+ return $2d16d1aab63a81f4$var$moveItems(prevState, keys, parent, toIndex, updateTree);
241
+ });
242
+ },
212
243
  update (oldKey, newValue) {
213
244
  setItems(({ items: items, nodeMap: originalMap })=>updateTree(items, oldKey, (oldNode)=>{
214
245
  let node = {
@@ -224,6 +255,88 @@ function $2d16d1aab63a81f4$export$d14e1352e21f4a16(options) {
224
255
  }
225
256
  };
226
257
  }
258
+ function $2d16d1aab63a81f4$var$moveItems(state, keys, toParent, toIndex, updateTree) {
259
+ let { items: items, nodeMap: nodeMap } = state;
260
+ let parent = toParent;
261
+ let removeKeys = new Set(keys);
262
+ while((parent === null || parent === void 0 ? void 0 : parent.parentKey) != null){
263
+ if (removeKeys.has(parent.key)) throw new Error('Cannot move an item to be a child of itself.');
264
+ var _nodeMap_get;
265
+ parent = (_nodeMap_get = nodeMap.get(parent.parentKey)) !== null && _nodeMap_get !== void 0 ? _nodeMap_get : null;
266
+ }
267
+ let originalToIndex = toIndex;
268
+ let keyArray = Array.isArray(keys) ? keys : [
269
+ ...keys
270
+ ];
271
+ // depth first search to put keys in order
272
+ let inOrderKeys = new Map();
273
+ let removedItems = [];
274
+ let newItems = items;
275
+ let newMap = nodeMap;
276
+ let i = 0;
277
+ function traversal(node, { inorder: inorder, postorder: postorder }) {
278
+ inorder === null || inorder === void 0 ? void 0 : inorder(node);
279
+ var _node_children;
280
+ if (node != null) for (let child of (_node_children = node.children) !== null && _node_children !== void 0 ? _node_children : []){
281
+ traversal(child, {
282
+ inorder: inorder,
283
+ postorder: postorder
284
+ });
285
+ postorder === null || postorder === void 0 ? void 0 : postorder(child);
286
+ }
287
+ }
288
+ function inorder(child) {
289
+ // in-order so we add items as we encounter them in the tree, then we can insert them in expected order later
290
+ if (keyArray.includes(child.key)) inOrderKeys.set(child.key, i++);
291
+ }
292
+ function postorder(child) {
293
+ // remove items and update the tree from the leaves and work upwards toward the root, this way
294
+ // we don't copy child node references from parents inadvertently
295
+ if (keyArray.includes(child.key)) {
296
+ var _toParent_key;
297
+ removedItems.push({
298
+ ...newMap.get(child.key),
299
+ parentKey: (_toParent_key = toParent === null || toParent === void 0 ? void 0 : toParent.key) !== null && _toParent_key !== void 0 ? _toParent_key : null
300
+ });
301
+ let { items: nextItems, nodeMap: nextMap } = updateTree(newItems, child.key, ()=>null, newMap);
302
+ newItems = nextItems;
303
+ newMap = nextMap;
304
+ }
305
+ // decrement the index if the child being removed is in the target parent and before the target index
306
+ if (child.parentKey === (toParent === null || toParent === void 0 ? void 0 : toParent.key) && keyArray.includes(child.key) && ((toParent === null || toParent === void 0 ? void 0 : toParent.children) ? toParent.children.indexOf(child) : items.indexOf(child)) < originalToIndex) toIndex--;
307
+ }
308
+ traversal({
309
+ children: items
310
+ }, {
311
+ inorder: inorder,
312
+ postorder: postorder
313
+ });
314
+ let inOrderItems = removedItems.sort((a, b)=>inOrderKeys.get(a.key) > inOrderKeys.get(b.key) ? 1 : -1);
315
+ // If parentKey is null, insert into the root.
316
+ if (!toParent || toParent.key == null) {
317
+ newMap = new Map(nodeMap);
318
+ inOrderItems.forEach((movedNode)=>newMap.set(movedNode.key, movedNode));
319
+ return {
320
+ items: [
321
+ ...newItems.slice(0, toIndex),
322
+ ...inOrderItems,
323
+ ...newItems.slice(toIndex)
324
+ ],
325
+ nodeMap: newMap
326
+ };
327
+ }
328
+ // Otherwise, update the parent node and its ancestors.
329
+ return updateTree(newItems, toParent.key, (parentNode)=>({
330
+ key: parentNode.key,
331
+ parentKey: parentNode.parentKey,
332
+ value: parentNode.value,
333
+ children: [
334
+ ...parentNode.children.slice(0, toIndex),
335
+ ...inOrderItems,
336
+ ...parentNode.children.slice(toIndex)
337
+ ]
338
+ }), newMap);
339
+ }
227
340
 
228
341
 
229
342
  //# sourceMappingURL=useTreeData.main.js.map
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-stately/data/src/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 * 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\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<{items: TreeNode<T>[], nodeMap: Map<Key, TreeNode<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,\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, update: (node: TreeNode<T>) => TreeNode<T> | null, originalMap: Map<Key, TreeNode<T>>) {\n let node = originalMap.get(key);\n if (!node) {\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\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, 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 newMap.set(movedNode.key, movedNode);\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 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"],"names":[],"version":3,"file":"useTreeData.main.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-stately/data/src/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, 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 // safe to reuse the original map since no node was actually removed, so we just need to update the one moved node\n newMap = new Map(originalMap);\n newMap.set(movedNode.key, movedNode);\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);\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);\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,\n update: (node: TreeNode<T>) => TreeNode<T> | null,\n originalMap: Map<Key, TreeNode<T>>\n ) => TreeDataState<T>\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 if (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 newMap = new Map(nodeMap);\n inOrderItems.forEach(movedNode => newMap.set(movedNode.key, movedNode));\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.main.js.map"}
@@ -26,7 +26,7 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
26
26
  items: initialItems.map((item)=>{
27
27
  let node = {
28
28
  key: getKey(item),
29
- parentKey: parentKey,
29
+ parentKey: parentKey !== null && parentKey !== void 0 ? parentKey : null,
30
30
  value: item,
31
31
  children: null
32
32
  };
@@ -38,8 +38,8 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
38
38
  };
39
39
  }
40
40
  function updateTree(items, key, update, originalMap) {
41
- let node = originalMap.get(key);
42
- if (!node) return {
41
+ let node = key == null ? null : originalMap.get(key);
42
+ if (node == null) return {
43
43
  items: items,
44
44
  nodeMap: originalMap
45
45
  };
@@ -180,6 +180,8 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
180
180
  };
181
181
  // If parentKey is null, insert into the root.
182
182
  if (toParentKey == null) {
183
+ // safe to reuse the original map since no node was actually removed, so we just need to update the one moved node
184
+ newMap = new Map(originalMap);
183
185
  newMap.set(movedNode.key, movedNode);
184
186
  return {
185
187
  items: [
@@ -203,6 +205,35 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
203
205
  }), newMap);
204
206
  });
205
207
  },
208
+ moveBefore (key, keys) {
209
+ setItems((prevState)=>{
210
+ let { items: items, nodeMap: nodeMap } = prevState;
211
+ let node = nodeMap.get(key);
212
+ if (!node) return prevState;
213
+ var _node_parentKey;
214
+ let toParentKey = (_node_parentKey = node.parentKey) !== null && _node_parentKey !== void 0 ? _node_parentKey : null;
215
+ let parent = null;
216
+ var _nodeMap_get;
217
+ if (toParentKey != null) parent = (_nodeMap_get = nodeMap.get(toParentKey)) !== null && _nodeMap_get !== void 0 ? _nodeMap_get : null;
218
+ let toIndex = (parent === null || parent === void 0 ? void 0 : parent.children) ? parent.children.indexOf(node) : items.indexOf(node);
219
+ return $be2ea0343af54212$var$moveItems(prevState, keys, parent, toIndex, updateTree);
220
+ });
221
+ },
222
+ moveAfter (key, keys) {
223
+ setItems((prevState)=>{
224
+ let { items: items, nodeMap: nodeMap } = prevState;
225
+ let node = nodeMap.get(key);
226
+ if (!node) return prevState;
227
+ var _node_parentKey;
228
+ let toParentKey = (_node_parentKey = node.parentKey) !== null && _node_parentKey !== void 0 ? _node_parentKey : null;
229
+ let parent = null;
230
+ var _nodeMap_get;
231
+ if (toParentKey != null) parent = (_nodeMap_get = nodeMap.get(toParentKey)) !== null && _nodeMap_get !== void 0 ? _nodeMap_get : null;
232
+ let toIndex = (parent === null || parent === void 0 ? void 0 : parent.children) ? parent.children.indexOf(node) : items.indexOf(node);
233
+ toIndex++;
234
+ return $be2ea0343af54212$var$moveItems(prevState, keys, parent, toIndex, updateTree);
235
+ });
236
+ },
206
237
  update (oldKey, newValue) {
207
238
  setItems(({ items: items, nodeMap: originalMap })=>updateTree(items, oldKey, (oldNode)=>{
208
239
  let node = {
@@ -218,6 +249,88 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
218
249
  }
219
250
  };
220
251
  }
252
+ function $be2ea0343af54212$var$moveItems(state, keys, toParent, toIndex, updateTree) {
253
+ let { items: items, nodeMap: nodeMap } = state;
254
+ let parent = toParent;
255
+ let removeKeys = new Set(keys);
256
+ while((parent === null || parent === void 0 ? void 0 : parent.parentKey) != null){
257
+ if (removeKeys.has(parent.key)) throw new Error('Cannot move an item to be a child of itself.');
258
+ var _nodeMap_get;
259
+ parent = (_nodeMap_get = nodeMap.get(parent.parentKey)) !== null && _nodeMap_get !== void 0 ? _nodeMap_get : null;
260
+ }
261
+ let originalToIndex = toIndex;
262
+ let keyArray = Array.isArray(keys) ? keys : [
263
+ ...keys
264
+ ];
265
+ // depth first search to put keys in order
266
+ let inOrderKeys = new Map();
267
+ let removedItems = [];
268
+ let newItems = items;
269
+ let newMap = nodeMap;
270
+ let i = 0;
271
+ function traversal(node, { inorder: inorder, postorder: postorder }) {
272
+ inorder === null || inorder === void 0 ? void 0 : inorder(node);
273
+ var _node_children;
274
+ if (node != null) for (let child of (_node_children = node.children) !== null && _node_children !== void 0 ? _node_children : []){
275
+ traversal(child, {
276
+ inorder: inorder,
277
+ postorder: postorder
278
+ });
279
+ postorder === null || postorder === void 0 ? void 0 : postorder(child);
280
+ }
281
+ }
282
+ function inorder(child) {
283
+ // in-order so we add items as we encounter them in the tree, then we can insert them in expected order later
284
+ if (keyArray.includes(child.key)) inOrderKeys.set(child.key, i++);
285
+ }
286
+ function postorder(child) {
287
+ // remove items and update the tree from the leaves and work upwards toward the root, this way
288
+ // we don't copy child node references from parents inadvertently
289
+ if (keyArray.includes(child.key)) {
290
+ var _toParent_key;
291
+ removedItems.push({
292
+ ...newMap.get(child.key),
293
+ parentKey: (_toParent_key = toParent === null || toParent === void 0 ? void 0 : toParent.key) !== null && _toParent_key !== void 0 ? _toParent_key : null
294
+ });
295
+ let { items: nextItems, nodeMap: nextMap } = updateTree(newItems, child.key, ()=>null, newMap);
296
+ newItems = nextItems;
297
+ newMap = nextMap;
298
+ }
299
+ // decrement the index if the child being removed is in the target parent and before the target index
300
+ if (child.parentKey === (toParent === null || toParent === void 0 ? void 0 : toParent.key) && keyArray.includes(child.key) && ((toParent === null || toParent === void 0 ? void 0 : toParent.children) ? toParent.children.indexOf(child) : items.indexOf(child)) < originalToIndex) toIndex--;
301
+ }
302
+ traversal({
303
+ children: items
304
+ }, {
305
+ inorder: inorder,
306
+ postorder: postorder
307
+ });
308
+ let inOrderItems = removedItems.sort((a, b)=>inOrderKeys.get(a.key) > inOrderKeys.get(b.key) ? 1 : -1);
309
+ // If parentKey is null, insert into the root.
310
+ if (!toParent || toParent.key == null) {
311
+ newMap = new Map(nodeMap);
312
+ inOrderItems.forEach((movedNode)=>newMap.set(movedNode.key, movedNode));
313
+ return {
314
+ items: [
315
+ ...newItems.slice(0, toIndex),
316
+ ...inOrderItems,
317
+ ...newItems.slice(toIndex)
318
+ ],
319
+ nodeMap: newMap
320
+ };
321
+ }
322
+ // Otherwise, update the parent node and its ancestors.
323
+ return updateTree(newItems, toParent.key, (parentNode)=>({
324
+ key: parentNode.key,
325
+ parentKey: parentNode.parentKey,
326
+ value: parentNode.value,
327
+ children: [
328
+ ...parentNode.children.slice(0, toIndex),
329
+ ...inOrderItems,
330
+ ...parentNode.children.slice(toIndex)
331
+ ]
332
+ }), newMap);
333
+ }
221
334
 
222
335
 
223
336
  export {$be2ea0343af54212$export$d14e1352e21f4a16 as useTreeData};
@@ -26,7 +26,7 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
26
26
  items: initialItems.map((item)=>{
27
27
  let node = {
28
28
  key: getKey(item),
29
- parentKey: parentKey,
29
+ parentKey: parentKey !== null && parentKey !== void 0 ? parentKey : null,
30
30
  value: item,
31
31
  children: null
32
32
  };
@@ -38,8 +38,8 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
38
38
  };
39
39
  }
40
40
  function updateTree(items, key, update, originalMap) {
41
- let node = originalMap.get(key);
42
- if (!node) return {
41
+ let node = key == null ? null : originalMap.get(key);
42
+ if (node == null) return {
43
43
  items: items,
44
44
  nodeMap: originalMap
45
45
  };
@@ -180,6 +180,8 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
180
180
  };
181
181
  // If parentKey is null, insert into the root.
182
182
  if (toParentKey == null) {
183
+ // safe to reuse the original map since no node was actually removed, so we just need to update the one moved node
184
+ newMap = new Map(originalMap);
183
185
  newMap.set(movedNode.key, movedNode);
184
186
  return {
185
187
  items: [
@@ -203,6 +205,35 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
203
205
  }), newMap);
204
206
  });
205
207
  },
208
+ moveBefore (key, keys) {
209
+ setItems((prevState)=>{
210
+ let { items: items, nodeMap: nodeMap } = prevState;
211
+ let node = nodeMap.get(key);
212
+ if (!node) return prevState;
213
+ var _node_parentKey;
214
+ let toParentKey = (_node_parentKey = node.parentKey) !== null && _node_parentKey !== void 0 ? _node_parentKey : null;
215
+ let parent = null;
216
+ var _nodeMap_get;
217
+ if (toParentKey != null) parent = (_nodeMap_get = nodeMap.get(toParentKey)) !== null && _nodeMap_get !== void 0 ? _nodeMap_get : null;
218
+ let toIndex = (parent === null || parent === void 0 ? void 0 : parent.children) ? parent.children.indexOf(node) : items.indexOf(node);
219
+ return $be2ea0343af54212$var$moveItems(prevState, keys, parent, toIndex, updateTree);
220
+ });
221
+ },
222
+ moveAfter (key, keys) {
223
+ setItems((prevState)=>{
224
+ let { items: items, nodeMap: nodeMap } = prevState;
225
+ let node = nodeMap.get(key);
226
+ if (!node) return prevState;
227
+ var _node_parentKey;
228
+ let toParentKey = (_node_parentKey = node.parentKey) !== null && _node_parentKey !== void 0 ? _node_parentKey : null;
229
+ let parent = null;
230
+ var _nodeMap_get;
231
+ if (toParentKey != null) parent = (_nodeMap_get = nodeMap.get(toParentKey)) !== null && _nodeMap_get !== void 0 ? _nodeMap_get : null;
232
+ let toIndex = (parent === null || parent === void 0 ? void 0 : parent.children) ? parent.children.indexOf(node) : items.indexOf(node);
233
+ toIndex++;
234
+ return $be2ea0343af54212$var$moveItems(prevState, keys, parent, toIndex, updateTree);
235
+ });
236
+ },
206
237
  update (oldKey, newValue) {
207
238
  setItems(({ items: items, nodeMap: originalMap })=>updateTree(items, oldKey, (oldNode)=>{
208
239
  let node = {
@@ -218,6 +249,88 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
218
249
  }
219
250
  };
220
251
  }
252
+ function $be2ea0343af54212$var$moveItems(state, keys, toParent, toIndex, updateTree) {
253
+ let { items: items, nodeMap: nodeMap } = state;
254
+ let parent = toParent;
255
+ let removeKeys = new Set(keys);
256
+ while((parent === null || parent === void 0 ? void 0 : parent.parentKey) != null){
257
+ if (removeKeys.has(parent.key)) throw new Error('Cannot move an item to be a child of itself.');
258
+ var _nodeMap_get;
259
+ parent = (_nodeMap_get = nodeMap.get(parent.parentKey)) !== null && _nodeMap_get !== void 0 ? _nodeMap_get : null;
260
+ }
261
+ let originalToIndex = toIndex;
262
+ let keyArray = Array.isArray(keys) ? keys : [
263
+ ...keys
264
+ ];
265
+ // depth first search to put keys in order
266
+ let inOrderKeys = new Map();
267
+ let removedItems = [];
268
+ let newItems = items;
269
+ let newMap = nodeMap;
270
+ let i = 0;
271
+ function traversal(node, { inorder: inorder, postorder: postorder }) {
272
+ inorder === null || inorder === void 0 ? void 0 : inorder(node);
273
+ var _node_children;
274
+ if (node != null) for (let child of (_node_children = node.children) !== null && _node_children !== void 0 ? _node_children : []){
275
+ traversal(child, {
276
+ inorder: inorder,
277
+ postorder: postorder
278
+ });
279
+ postorder === null || postorder === void 0 ? void 0 : postorder(child);
280
+ }
281
+ }
282
+ function inorder(child) {
283
+ // in-order so we add items as we encounter them in the tree, then we can insert them in expected order later
284
+ if (keyArray.includes(child.key)) inOrderKeys.set(child.key, i++);
285
+ }
286
+ function postorder(child) {
287
+ // remove items and update the tree from the leaves and work upwards toward the root, this way
288
+ // we don't copy child node references from parents inadvertently
289
+ if (keyArray.includes(child.key)) {
290
+ var _toParent_key;
291
+ removedItems.push({
292
+ ...newMap.get(child.key),
293
+ parentKey: (_toParent_key = toParent === null || toParent === void 0 ? void 0 : toParent.key) !== null && _toParent_key !== void 0 ? _toParent_key : null
294
+ });
295
+ let { items: nextItems, nodeMap: nextMap } = updateTree(newItems, child.key, ()=>null, newMap);
296
+ newItems = nextItems;
297
+ newMap = nextMap;
298
+ }
299
+ // decrement the index if the child being removed is in the target parent and before the target index
300
+ if (child.parentKey === (toParent === null || toParent === void 0 ? void 0 : toParent.key) && keyArray.includes(child.key) && ((toParent === null || toParent === void 0 ? void 0 : toParent.children) ? toParent.children.indexOf(child) : items.indexOf(child)) < originalToIndex) toIndex--;
301
+ }
302
+ traversal({
303
+ children: items
304
+ }, {
305
+ inorder: inorder,
306
+ postorder: postorder
307
+ });
308
+ let inOrderItems = removedItems.sort((a, b)=>inOrderKeys.get(a.key) > inOrderKeys.get(b.key) ? 1 : -1);
309
+ // If parentKey is null, insert into the root.
310
+ if (!toParent || toParent.key == null) {
311
+ newMap = new Map(nodeMap);
312
+ inOrderItems.forEach((movedNode)=>newMap.set(movedNode.key, movedNode));
313
+ return {
314
+ items: [
315
+ ...newItems.slice(0, toIndex),
316
+ ...inOrderItems,
317
+ ...newItems.slice(toIndex)
318
+ ],
319
+ nodeMap: newMap
320
+ };
321
+ }
322
+ // Otherwise, update the parent node and its ancestors.
323
+ return updateTree(newItems, toParent.key, (parentNode)=>({
324
+ key: parentNode.key,
325
+ parentKey: parentNode.parentKey,
326
+ value: parentNode.value,
327
+ children: [
328
+ ...parentNode.children.slice(0, toIndex),
329
+ ...inOrderItems,
330
+ ...parentNode.children.slice(toIndex)
331
+ ]
332
+ }), newMap);
333
+ }
221
334
 
222
335
 
223
336
  export {$be2ea0343af54212$export$d14e1352e21f4a16 as useTreeData};
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-stately/data/src/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 * 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\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<{items: TreeNode<T>[], nodeMap: Map<Key, TreeNode<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,\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, update: (node: TreeNode<T>) => TreeNode<T> | null, originalMap: Map<Key, TreeNode<T>>) {\n let node = originalMap.get(key);\n if (!node) {\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\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, 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 newMap.set(movedNode.key, movedNode);\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 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"],"names":[],"version":3,"file":"useTreeData.module.js.map"}
1
+ {"mappings":";;AAAA;;;;;;;;;;CAUC;AAkIM,SAAS,0CAA8B,OAAuB;IACnE,IAAI,gBACF,eAAe,EAAE,uBACjB,mBAAmB,UACnB,SAAS,CAAC;YAAc;eAAA,CAAA,WAAA,KAAK,EAAE,cAAP,sBAAA,WAAW,KAAK,GAAG;oBAC3C,cAAc,CAAC,OAAc,KAAK,QAAQ,EAC3C,GAAG;IAEJ,kDAAkD;IAClD,IAAI,CAAC,MAAM,SAAS,GAAG,CAAA,GAAA,eAAO,EAAoB,IAAM,UAAU,cAAc,IAAI;IACpF,IAAI,SAAC,KAAK,WAAE,OAAO,EAAC,GAAG;IAEvB,IAAI,CAAC,cAAc,gBAAgB,GAAG,CAAA,GAAA,eAAO,EAAE,IAAI,IAAS,uBAAuB,EAAE;IAErF,SAAS,UAAU,eAA2B,EAAE,EAAE,GAA0B,EAAE,SAAsB;QAClG,IAAI,gBAAgB,MAClB,eAAe,EAAE;QAEnB,OAAO;YACL,OAAO,aAAa,GAAG,CAAC,CAAA;gBACtB,IAAI,OAAoB;oBACtB,KAAK,OAAO;oBACZ,WAAW,sBAAA,uBAAA,YAAa;oBACxB,OAAO;oBACP,UAAU;gBACZ;gBAEA,KAAK,QAAQ,GAAG,UAAU,YAAY,OAAO,KAAK,KAAK,GAAG,EAAE,KAAK;gBACjE,IAAI,GAAG,CAAC,KAAK,GAAG,EAAE;gBAClB,OAAO;YACT;YACA,SAAS;QACX;IACF;IAEA,SAAS,WAAW,KAAoB,EAAE,GAAe,EAAE,MAAiD,EAAE,WAAkC;QAC9I,IAAI,OAAO,OAAO,OAAO,OAAO,YAAY,GAAG,CAAC;QAChD,IAAI,QAAQ,MACV,OAAO;mBAAC;YAAO,SAAS;QAAW;QAErC,IAAI,MAAM,IAAI,IAAsB;QAEpC,uEAAuE;QACvE,IAAI,UAAU,OAAO;QACrB,IAAI,WAAW,MACb,WAAW,MAAM;aAEjB,QAAQ,SAAS;QAGnB,wEAAwE;QACxE,MAAO,QAAQ,KAAK,SAAS,CAAE;YAC7B,IAAI,aAAa,IAAI,GAAG,CAAC,KAAK,SAAS;YACvC,IAAI,OAAoB;gBACtB,KAAK,WAAW,GAAG;gBACnB,WAAW,WAAW,SAAS;gBAC/B,OAAO,WAAW,KAAK;gBACvB,UAAU;YACZ;YAEA,IAAI,WAAW,WAAW,QAAQ;YAClC,IAAI,WAAW,QAAQ,UACrB,WAAW,SAAS,MAAM,CAAC,CAAA,IAAK,MAAM;gBAGxB;YAAhB,KAAK,QAAQ,GAAG,CAAA,gBAAA,qBAAA,+BAAA,SAAU,GAAG,CAAC,CAAA;gBAC5B,IAAI,UAAU,MACZ,uDAAuD;gBACvD,OAAO;gBAGT,OAAO;YACT,gBAPgB,2BAAA,gBAOV;YAEN,IAAI,GAAG,CAAC,KAAK,GAAG,EAAE;YAElB,UAAU;YACV,OAAO;QACT;QAEA,IAAI,WAAW,MACb,QAAQ,MAAM,MAAM,CAAC,CAAA,IAAK,MAAM;QAGlC,OAAO;YACL,OAAO,MAAM,GAAG,CAAC,CAAA;gBACf,IAAI,SAAS,MACX,uDAAuD;gBACvD,OAAO;gBAGT,OAAO;YACT;YACA,SAAS;QACX;IACF;IAEA,SAAS,QAAQ,IAAiB,EAAE,GAA0B;QAC5D,IAAI,GAAG,CAAC,KAAK,GAAG,EAAE;QAClB,IAAI,KAAK,QAAQ,EACf,KAAK,IAAI,SAAS,KAAK,QAAQ,CAC7B,QAAQ,OAAO;IAGrB;IAEA,SAAS,WAAW,IAAiB,EAAE,GAA0B;QAC/D,IAAI,MAAM,CAAC,KAAK,GAAG;QACnB,IAAI,KAAK,QAAQ,EACf,KAAK,IAAI,SAAS,KAAK,QAAQ,CAC7B,WAAW,OAAO;IAGxB;IACA,OAAO;eACL;sBACA;yBACA;QACA,SAAQ,GAAQ;YACd,OAAO,QAAQ,GAAG,CAAC;QACrB;QACA,QAAO,SAAqB,EAAE,KAAa,EAAE,GAAG,MAAW;YACzD,SAAS,CAAC,SAAC,KAAK,EAAE,SAAS,WAAW,EAAC;gBACrC,IAAI,EAAC,OAAO,QAAQ,EAAE,SAAS,MAAM,EAAC,GAAG,UAAU,QAAQ,aAAa;gBAExE,8CAA8C;gBAC9C,IAAI,aAAa,MACf,OAAO;oBACL,OAAO;2BACF,MAAM,KAAK,CAAC,GAAG;2BACf;2BACA,MAAM,KAAK,CAAC;qBAChB;oBACD,SAAS;gBACX;gBAGF,uDAAuD;gBACvD,OAAO,WAAW,OAAO,WAAW,CAAA,aAAe,CAAA;wBACjD,KAAK,WAAW,GAAG;wBACnB,WAAW,WAAW,SAAS;wBAC/B,OAAO,WAAW,KAAK;wBACvB,UAAU;+BACL,WAAW,QAAQ,CAAE,KAAK,CAAC,GAAG;+BAC9B;+BACA,WAAW,QAAQ,CAAE,KAAK,CAAC;yBAC/B;oBACH,CAAA,GAAI;YACN;QACF;QACA,cAAa,GAAQ,EAAE,GAAG,MAAW;YACnC,IAAI,OAAO,QAAQ,GAAG,CAAC;YACvB,IAAI,CAAC,MACH;YAGF,IAAI,aAAa,QAAQ,GAAG,CAAC,KAAK,SAAS;YAC3C,IAAI,QAAQ,aAAa,WAAW,QAAQ,GAAG;YAC/C,IAAI,QAAQ,MAAO,OAAO,CAAC;gBACf;YAAZ,IAAI,CAAC,MAAM,CAAC,CAAA,kBAAA,uBAAA,iCAAA,WAAY,GAAG,cAAf,6BAAA,kBAAmB,MAAM,UAAU;QACjD;QACA,aAAY,GAAQ,EAAE,GAAG,MAAW;YAClC,IAAI,OAAO,QAAQ,GAAG,CAAC;YACvB,IAAI,CAAC,MACH;YAGF,IAAI,aAAa,QAAQ,GAAG,CAAC,KAAK,SAAS;YAC3C,IAAI,QAAQ,aAAa,WAAW,QAAQ,GAAG;YAC/C,IAAI,QAAQ,MAAO,OAAO,CAAC;gBACf;YAAZ,IAAI,CAAC,MAAM,CAAC,CAAA,kBAAA,uBAAA,iCAAA,WAAY,GAAG,cAAf,6BAAA,kBAAmB,MAAM,QAAQ,MAAM;QACrD;QACA,SAAQ,SAAqB,EAAE,GAAG,MAAW;YAC3C,IAAI,CAAC,MAAM,CAAC,WAAW,MAAM;QAC/B;QACA,QAAO,SAAqB,EAAE,GAAG,MAAW;YAC1C,IAAI,aAAa,MACf,IAAI,CAAC,MAAM,CAAC,MAAM,MAAM,MAAM,KAAK;iBAC9B;gBACL,IAAI,aAAa,QAAQ,GAAG,CAAC;gBAC7B,IAAI,CAAC,YACH;gBAGF,IAAI,CAAC,MAAM,CAAC,WAAW,WAAW,QAAQ,CAAE,MAAM,KAAK;YACzD;QACF;QACA,QAAO,GAAG,IAAW;YACnB,IAAI,KAAK,MAAM,KAAK,GAClB;YAGF,IAAI,WAAW;YACf,IAAI,UAAU;YACd,IAAI;YACJ,KAAK,IAAI,OAAO,KAAM;gBACpB,UAAU,WAAW,UAAU,KAAK,IAAM,MAAM;gBAChD,UAAU,QAAQ,OAAO;gBACzB,WAAW,QAAQ,KAAK;YAC1B;YAEA,SAAS;YAET,IAAI,YAAY,IAAI,IAAI;YACxB,KAAK,IAAI,OAAO,aACd,IAAI,CAAC,QAAQ,OAAO,CAAC,GAAG,CAAC,MACvB,UAAU,MAAM,CAAC;YAIrB,gBAAgB;QAClB;QACA;YACE,IAAI,CAAC,MAAM,IAAI;QACjB;QACA,MAAK,GAAQ,EAAE,WAAuB,EAAE,KAAa;YACnD,SAAS,CAAC,SAAC,KAAK,EAAE,SAAS,WAAW,EAAC;gBACrC,IAAI,OAAO,YAAY,GAAG,CAAC;gBAC3B,IAAI,CAAC,MACH,OAAO;2BAAC;oBAAO,SAAS;gBAAW;gBAGrC,IAAI,EAAC,OAAO,QAAQ,EAAE,SAAS,MAAM,EAAC,GAAG,WAAW,OAAO,KAAK,IAAM,MAAM;gBAG5E,MAAM,YAAY;oBAChB,GAAG,IAAI;oBACP,WAAW;gBACb;gBAEA,8CAA8C;gBAC9C,IAAI,eAAe,MAAM;oBACvB,kHAAkH;oBAClH,SAAS,IAAI,IAAI;oBACjB,OAAO,GAAG,CAAC,UAAU,GAAG,EAAE;oBAC1B,OAAO;wBAAC,OAAO;+BACV,SAAS,KAAK,CAAC,GAAG;4BACrB;+BACG,SAAS,KAAK,CAAC;yBACnB;wBAAE,SAAS;oBAAM;gBACpB;gBAEA,uDAAuD;gBACvD,OAAO,WAAW,UAAU,aAAa,CAAA,aAAe,CAAA;wBACtD,KAAK,WAAW,GAAG;wBACnB,WAAW,WAAW,SAAS;wBAC/B,OAAO,WAAW,KAAK;wBACvB,UAAU;+BACL,WAAW,QAAQ,CAAE,KAAK,CAAC,GAAG;4BACjC;+BACG,WAAW,QAAQ,CAAE,KAAK,CAAC;yBAC/B;oBACH,CAAA,GAAI;YACN;QACF;QACA,YAAW,GAAQ,EAAE,IAAmB;YACtC,SAAS,CAAC;gBACR,IAAI,SAAC,KAAK,WAAE,OAAO,EAAC,GAAG;gBACvB,IAAI,OAAO,QAAQ,GAAG,CAAC;gBACvB,IAAI,CAAC,MACH,OAAO;oBAES;gBAAlB,IAAI,cAAc,CAAA,kBAAA,KAAK,SAAS,cAAd,6BAAA,kBAAkB;gBACpC,IAAI,SAA6B;oBAEtB;gBADX,IAAI,eAAe,MACjB,SAAS,CAAA,eAAA,QAAQ,GAAG,CAAC,0BAAZ,0BAAA,eAA4B;gBAEvC,IAAI,UAAU,CAAA,mBAAA,6BAAA,OAAQ,QAAQ,IAAG,OAAO,QAAQ,CAAC,OAAO,CAAC,QAAQ,MAAM,OAAO,CAAC;gBAC/E,OAAO,gCAAU,WAAW,MAAM,QAAQ,SAAS;YACrD;QACF;QACA,WAAU,GAAQ,EAAE,IAAmB;YACrC,SAAS,CAAC;gBACR,IAAI,SAAC,KAAK,WAAE,OAAO,EAAC,GAAG;gBACvB,IAAI,OAAO,QAAQ,GAAG,CAAC;gBACvB,IAAI,CAAC,MACH,OAAO;oBAES;gBAAlB,IAAI,cAAc,CAAA,kBAAA,KAAK,SAAS,cAAd,6BAAA,kBAAkB;gBACpC,IAAI,SAA6B;oBAEtB;gBADX,IAAI,eAAe,MACjB,SAAS,CAAA,eAAA,QAAQ,GAAG,CAAC,0BAAZ,0BAAA,eAA4B;gBAEvC,IAAI,UAAU,CAAA,mBAAA,6BAAA,OAAQ,QAAQ,IAAG,OAAO,QAAQ,CAAC,OAAO,CAAC,QAAQ,MAAM,OAAO,CAAC;gBAC/E;gBACA,OAAO,gCAAU,WAAW,MAAM,QAAQ,SAAS;YACrD;QACF;QACA,QAAO,MAAW,EAAE,QAAW;YAC7B,SAAS,CAAC,SAAC,KAAK,EAAE,SAAS,WAAW,EAAC,GAAK,WAAW,OAAO,QAAQ,CAAA;oBACpE,IAAI,OAAoB;wBACtB,KAAK,QAAQ,GAAG;wBAChB,WAAW,QAAQ,SAAS;wBAC5B,OAAO;wBACP,UAAU;oBACZ;oBAEA,IAAI,OAAO,UAAU,YAAY,WAAW,aAAa,KAAK,GAAG;oBACjE,KAAK,QAAQ,GAAG,KAAK,KAAK;oBAC1B,OAAO;gBACT,GAAG;QACL;IACF;AACF;AAEA,SAAS,gCACP,KAAuB,EACvB,IAAmB,EACnB,QAA4B,EAC5B,OAAe,EACf,UAKqB;IAErB,IAAI,SAAC,KAAK,WAAE,OAAO,EAAC,GAAG;IAEvB,IAAI,SAAS;IACb,IAAI,aAAa,IAAI,IAAI;IACzB,MAAO,CAAA,mBAAA,6BAAA,OAAQ,SAAS,KAAI,KAAM;QAChC,IAAI,WAAW,GAAG,CAAC,OAAO,GAAG,GAC3B,MAAM,IAAI,MAAM;YAET;QAAT,SAAS,CAAA,eAAA,QAAQ,GAAG,CAAC,OAAO,SAAS,eAA5B,0BAAA,eAAkC;IAC7C;IAEA,IAAI,kBAAkB;IAEtB,IAAI,WAAW,MAAM,OAAO,CAAC,QAAQ,OAAO;WAAI;KAAK;IACrD,0CAA0C;IAC1C,IAAI,cAAgC,IAAI;IACxC,IAAI,eAAmC,EAAE;IACzC,IAAI,WAAW;IACf,IAAI,SAAS;IACb,IAAI,IAAI;IAER,SAAS,UAAU,IAAI,EAAE,WAAC,OAAO,aAAE,SAAS,EAAC;QAC3C,oBAAA,8BAAA,QAAU;YAEU;QADpB,IAAI,QAAQ,MACV,KAAK,IAAI,SAAS,CAAA,iBAAA,KAAK,QAAQ,cAAb,4BAAA,iBAAiB,EAAE,CAAE;YACrC,UAAU,OAAO;yBAAC;2BAAS;YAAS;YACpC,sBAAA,gCAAA,UAAY;QACd;IAEJ;IAEA,SAAS,QAAQ,KAAK;QACpB,6GAA6G;QAC7G,IAAI,SAAS,QAAQ,CAAC,MAAM,GAAG,GAC7B,YAAY,GAAG,CAAC,MAAM,GAAG,EAAE;IAE/B;IAEA,SAAS,UAAU,KAAK;QACtB,8FAA8F;QAC9F,iEAAiE;QACjE,IAAI,SAAS,QAAQ,CAAC,MAAM,GAAG,GAAG;gBACyB;YAAzD,aAAa,IAAI,CAAC;gBAAC,GAAG,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC;gBAAG,WAAW,CAAA,gBAAA,qBAAA,+BAAA,SAAU,GAAG,cAAb,2BAAA,gBAAiB;YAAI;YAC9E,IAAI,EAAC,OAAO,SAAS,EAAE,SAAS,OAAO,EAAC,GAAG,WAAW,UAAU,MAAM,GAAG,EAAE,IAAM,MAAM;YACvF,WAAW;YACX,SAAS;QACX;QACA,qGAAqG;QACrG,IAAI,MAAM,SAAS,MAAK,qBAAA,+BAAA,SAAU,GAAG,KAChC,SAAS,QAAQ,CAAC,MAAM,GAAG,KAC3B,AAAC,CAAA,CAAA,qBAAA,+BAAA,SAAU,QAAQ,IAAG,SAAS,QAAQ,CAAC,OAAO,CAAC,SAAS,MAAM,OAAO,CAAC,MAAK,IAAK,iBACpF;IAEJ;IAEA,UAAU;QAAC,UAAU;IAAK,GAAG;iBAAC;mBAAS;IAAS;IAEhD,IAAI,eAAe,aAAa,IAAI,CAAC,CAAC,GAAG,IAAM,YAAY,GAAG,CAAC,EAAE,GAAG,IAAK,YAAY,GAAG,CAAC,EAAE,GAAG,IAAK,IAAI;IACvG,8CAA8C;IAC9C,IAAI,CAAC,YAAY,SAAS,GAAG,IAAI,MAAM;QACrC,SAAS,IAAI,IAAI;QACjB,aAAa,OAAO,CAAC,CAAA,YAAa,OAAO,GAAG,CAAC,UAAU,GAAG,EAAE;QAC5D,OAAO;YAAC,OAAO;mBACV,SAAS,KAAK,CAAC,GAAG;mBAClB;mBACA,SAAS,KAAK,CAAC;aACnB;YAAE,SAAS;QAAM;IACpB;IAEA,uDAAuD;IACvD,OAAO,WAAW,UAAU,SAAS,GAAG,EAAE,CAAA,aAAe,CAAA;YACvD,KAAK,WAAW,GAAG;YACnB,WAAW,WAAW,SAAS;YAC/B,OAAO,WAAW,KAAK;YACvB,UAAU;mBACL,WAAW,QAAQ,CAAE,KAAK,CAAC,GAAG;mBAC9B;mBACA,WAAW,QAAQ,CAAE,KAAK,CAAC;aAC/B;QACH,CAAA,GAAI;AACN","sources":["packages/@react-stately/data/src/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, 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 // safe to reuse the original map since no node was actually removed, so we just need to update the one moved node\n newMap = new Map(originalMap);\n newMap.set(movedNode.key, movedNode);\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);\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);\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,\n update: (node: TreeNode<T>) => TreeNode<T> | null,\n originalMap: Map<Key, TreeNode<T>>\n ) => TreeDataState<T>\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 if (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 newMap = new Map(nodeMap);\n inOrderItems.forEach(movedNode => newMap.set(movedNode.key, movedNode));\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.module.js.map"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-stately/data",
3
- "version": "3.0.0-nightly-a166aaab8-250421",
3
+ "version": "3.0.0-nightly-e4ec6b4e9-250422",
4
4
  "description": "Spectrum UI components in React",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/main.js",
@@ -22,7 +22,7 @@
22
22
  "url": "https://github.com/adobe/react-spectrum"
23
23
  },
24
24
  "dependencies": {
25
- "@react-types/shared": "3.0.0-nightly-a166aaab8-250421",
25
+ "@react-types/shared": "3.0.0-nightly-e4ec6b4e9-250422",
26
26
  "@swc/helpers": "^0.5.0"
27
27
  },
28
28
  "peerDependencies": {
@@ -107,6 +107,20 @@ export interface TreeData<T extends object> {
107
107
  */
108
108
  move(key: Key, toParentKey: Key | null, index: number): void,
109
109
 
110
+ /**
111
+ * Moves one or more items before a given key.
112
+ * @param key - The key of the item to move the items before.
113
+ * @param keys - The keys of the items to move.
114
+ */
115
+ moveBefore(key: Key, keys: Iterable<Key>): void,
116
+
117
+ /**
118
+ * Moves one or more items after a given key.
119
+ * @param key - The key of the item to move the items after.
120
+ * @param keys - The keys of the items to move.
121
+ */
122
+ moveAfter(key: Key, keys: Iterable<Key>): void,
123
+
110
124
  /**
111
125
  * Updates an item in the tree.
112
126
  * @param key - The key of the item to update.
@@ -115,6 +129,11 @@ export interface TreeData<T extends object> {
115
129
  update(key: Key, newValue: T): void
116
130
  }
117
131
 
132
+ interface TreeDataState<T extends object> {
133
+ items: TreeNode<T>[],
134
+ nodeMap: Map<Key, TreeNode<T>>
135
+ }
136
+
118
137
  /**
119
138
  * Manages state for an immutable tree data structure, and provides convenience methods to
120
139
  * update the data over time.
@@ -128,7 +147,7 @@ export function useTreeData<T extends object>(options: TreeOptions<T>): TreeData
128
147
  } = options;
129
148
 
130
149
  // We only want to compute this on initial render.
131
- let [tree, setItems] = useState<{items: TreeNode<T>[], nodeMap: Map<Key, TreeNode<T>>}>(() => buildTree(initialItems, new Map()));
150
+ let [tree, setItems] = useState<TreeDataState<T>>(() => buildTree(initialItems, new Map()));
132
151
  let {items, nodeMap} = tree;
133
152
 
134
153
  let [selectedKeys, setSelectedKeys] = useState(new Set<Key>(initialSelectedKeys || []));
@@ -141,7 +160,7 @@ export function useTreeData<T extends object>(options: TreeOptions<T>): TreeData
141
160
  items: initialItems.map(item => {
142
161
  let node: TreeNode<T> = {
143
162
  key: getKey(item),
144
- parentKey: parentKey,
163
+ parentKey: parentKey ?? null,
145
164
  value: item,
146
165
  children: null
147
166
  };
@@ -154,9 +173,9 @@ export function useTreeData<T extends object>(options: TreeOptions<T>): TreeData
154
173
  };
155
174
  }
156
175
 
157
- function updateTree(items: TreeNode<T>[], key: Key, update: (node: TreeNode<T>) => TreeNode<T> | null, originalMap: Map<Key, TreeNode<T>>) {
158
- let node = originalMap.get(key);
159
- if (!node) {
176
+ function updateTree(items: TreeNode<T>[], key: Key | null, update: (node: TreeNode<T>) => TreeNode<T> | null, originalMap: Map<Key, TreeNode<T>>) {
177
+ let node = key == null ? null : originalMap.get(key);
178
+ if (node == null) {
160
179
  return {items, nodeMap: originalMap};
161
180
  }
162
181
  let map = new Map<Key, TreeNode<T>>(originalMap);
@@ -233,7 +252,6 @@ export function useTreeData<T extends object>(options: TreeOptions<T>): TreeData
233
252
  }
234
253
  }
235
254
  }
236
-
237
255
  return {
238
256
  items,
239
257
  selectedKeys,
@@ -352,6 +370,8 @@ export function useTreeData<T extends object>(options: TreeOptions<T>): TreeData
352
370
 
353
371
  // If parentKey is null, insert into the root.
354
372
  if (toParentKey == null) {
373
+ // safe to reuse the original map since no node was actually removed, so we just need to update the one moved node
374
+ newMap = new Map(originalMap);
355
375
  newMap.set(movedNode.key, movedNode);
356
376
  return {items: [
357
377
  ...newItems.slice(0, index),
@@ -373,6 +393,39 @@ export function useTreeData<T extends object>(options: TreeOptions<T>): TreeData
373
393
  }), newMap);
374
394
  });
375
395
  },
396
+ moveBefore(key: Key, keys: Iterable<Key>) {
397
+ setItems((prevState) => {
398
+ let {items, nodeMap} = prevState;
399
+ let node = nodeMap.get(key);
400
+ if (!node) {
401
+ return prevState;
402
+ }
403
+ let toParentKey = node.parentKey ?? null;
404
+ let parent: null | TreeNode<T> = null;
405
+ if (toParentKey != null) {
406
+ parent = nodeMap.get(toParentKey) ?? null;
407
+ }
408
+ let toIndex = parent?.children ? parent.children.indexOf(node) : items.indexOf(node);
409
+ return moveItems(prevState, keys, parent, toIndex, updateTree);
410
+ });
411
+ },
412
+ moveAfter(key: Key, keys: Iterable<Key>) {
413
+ setItems((prevState) => {
414
+ let {items, nodeMap} = prevState;
415
+ let node = nodeMap.get(key);
416
+ if (!node) {
417
+ return prevState;
418
+ }
419
+ let toParentKey = node.parentKey ?? null;
420
+ let parent: null | TreeNode<T> = null;
421
+ if (toParentKey != null) {
422
+ parent = nodeMap.get(toParentKey) ?? null;
423
+ }
424
+ let toIndex = parent?.children ? parent.children.indexOf(node) : items.indexOf(node);
425
+ toIndex++;
426
+ return moveItems(prevState, keys, parent, toIndex, updateTree);
427
+ });
428
+ },
376
429
  update(oldKey: Key, newValue: T) {
377
430
  setItems(({items, nodeMap: originalMap}) => updateTree(items, oldKey, oldNode => {
378
431
  let node: TreeNode<T> = {
@@ -389,3 +442,97 @@ export function useTreeData<T extends object>(options: TreeOptions<T>): TreeData
389
442
  }
390
443
  };
391
444
  }
445
+
446
+ function moveItems<T extends object>(
447
+ state: TreeDataState<T>,
448
+ keys: Iterable<Key>,
449
+ toParent: TreeNode<T> | null,
450
+ toIndex: number,
451
+ updateTree: (
452
+ items: TreeNode<T>[],
453
+ key: Key,
454
+ update: (node: TreeNode<T>) => TreeNode<T> | null,
455
+ originalMap: Map<Key, TreeNode<T>>
456
+ ) => TreeDataState<T>
457
+ ): TreeDataState<T> {
458
+ let {items, nodeMap} = state;
459
+
460
+ let parent = toParent;
461
+ let removeKeys = new Set(keys);
462
+ while (parent?.parentKey != null) {
463
+ if (removeKeys.has(parent.key)) {
464
+ throw new Error('Cannot move an item to be a child of itself.');
465
+ }
466
+ parent = nodeMap.get(parent.parentKey!) ?? null;
467
+ }
468
+
469
+ let originalToIndex = toIndex;
470
+
471
+ let keyArray = Array.isArray(keys) ? keys : [...keys];
472
+ // depth first search to put keys in order
473
+ let inOrderKeys: Map<Key, number> = new Map();
474
+ let removedItems: Array<TreeNode<T>> = [];
475
+ let newItems = items;
476
+ let newMap = nodeMap;
477
+ let i = 0;
478
+
479
+ function traversal(node, {inorder, postorder}) {
480
+ inorder?.(node);
481
+ if (node != null) {
482
+ for (let child of node.children ?? []) {
483
+ traversal(child, {inorder, postorder});
484
+ postorder?.(child);
485
+ }
486
+ }
487
+ }
488
+
489
+ function inorder(child) {
490
+ // in-order so we add items as we encounter them in the tree, then we can insert them in expected order later
491
+ if (keyArray.includes(child.key)) {
492
+ inOrderKeys.set(child.key, i++);
493
+ }
494
+ }
495
+
496
+ function postorder(child) {
497
+ // remove items and update the tree from the leaves and work upwards toward the root, this way
498
+ // we don't copy child node references from parents inadvertently
499
+ if (keyArray.includes(child.key)) {
500
+ removedItems.push({...newMap.get(child.key)!, parentKey: toParent?.key ?? null});
501
+ let {items: nextItems, nodeMap: nextMap} = updateTree(newItems, child.key, () => null, newMap);
502
+ newItems = nextItems;
503
+ newMap = nextMap;
504
+ }
505
+ // decrement the index if the child being removed is in the target parent and before the target index
506
+ if (child.parentKey === toParent?.key
507
+ && keyArray.includes(child.key)
508
+ && (toParent?.children ? toParent.children.indexOf(child) : items.indexOf(child)) < originalToIndex) {
509
+ toIndex--;
510
+ }
511
+ }
512
+
513
+ traversal({children: items}, {inorder, postorder});
514
+
515
+ let inOrderItems = removedItems.sort((a, b) => inOrderKeys.get(a.key)! > inOrderKeys.get(b.key)! ? 1 : -1);
516
+ // If parentKey is null, insert into the root.
517
+ if (!toParent || toParent.key == null) {
518
+ newMap = new Map(nodeMap);
519
+ inOrderItems.forEach(movedNode => newMap.set(movedNode.key, movedNode));
520
+ return {items: [
521
+ ...newItems.slice(0, toIndex),
522
+ ...inOrderItems,
523
+ ...newItems.slice(toIndex)
524
+ ], nodeMap: newMap};
525
+ }
526
+
527
+ // Otherwise, update the parent node and its ancestors.
528
+ return updateTree(newItems, toParent.key, parentNode => ({
529
+ key: parentNode.key,
530
+ parentKey: parentNode.parentKey,
531
+ value: parentNode.value,
532
+ children: [
533
+ ...parentNode.children!.slice(0, toIndex),
534
+ ...inOrderItems,
535
+ ...parentNode.children!.slice(toIndex)
536
+ ]
537
+ }), newMap);
538
+ }