@react-stately/data 3.11.7 → 3.12.0
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/LICENSE +201 -0
- package/dist/types.d.ts +9 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/useAsyncList.main.js +24 -18
- package/dist/useAsyncList.main.js.map +1 -1
- package/dist/useAsyncList.mjs +24 -18
- package/dist/useAsyncList.module.js +24 -18
- package/dist/useAsyncList.module.js.map +1 -1
- package/dist/useListData.main.js +2 -2
- package/dist/useListData.main.js.map +1 -1
- package/dist/useListData.mjs +2 -2
- package/dist/useListData.module.js +2 -2
- package/dist/useListData.module.js.map +1 -1
- package/dist/useTreeData.main.js +15 -10
- package/dist/useTreeData.main.js.map +1 -1
- package/dist/useTreeData.mjs +15 -10
- package/dist/useTreeData.module.js +15 -10
- package/dist/useTreeData.module.js.map +1 -1
- package/package.json +6 -5
- package/src/useAsyncList.ts +18 -18
- package/src/useListData.ts +11 -11
- package/src/useTreeData.ts +32 -26
package/dist/useTreeData.main.js
CHANGED
|
@@ -55,7 +55,7 @@ function $2d16d1aab63a81f4$export$d14e1352e21f4a16(options) {
|
|
|
55
55
|
if (newNode == null) deleteNode(node, map);
|
|
56
56
|
else addNode(newNode, map);
|
|
57
57
|
// Walk up the tree and update each parent to refer to the new children.
|
|
58
|
-
while(node.parentKey){
|
|
58
|
+
while(node && node.parentKey){
|
|
59
59
|
let nextParent = map.get(node.parentKey);
|
|
60
60
|
let copy = {
|
|
61
61
|
key: nextParent.key,
|
|
@@ -64,11 +64,13 @@ function $2d16d1aab63a81f4$export$d14e1352e21f4a16(options) {
|
|
|
64
64
|
children: null
|
|
65
65
|
};
|
|
66
66
|
let children = nextParent.children;
|
|
67
|
-
if (newNode == null) children = children.filter((c)=>c !== node);
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
if (newNode == null && children) children = children.filter((c)=>c !== node);
|
|
68
|
+
var _children_map;
|
|
69
|
+
copy.children = (_children_map = children === null || children === void 0 ? void 0 : children.map((child)=>{
|
|
70
|
+
if (child === node) // newNode cannot be null here due to the above filter.
|
|
71
|
+
return newNode;
|
|
70
72
|
return child;
|
|
71
|
-
});
|
|
73
|
+
})) !== null && _children_map !== void 0 ? _children_map : null;
|
|
72
74
|
map.set(copy.key, copy);
|
|
73
75
|
newNode = copy;
|
|
74
76
|
node = nextParent;
|
|
@@ -76,7 +78,8 @@ function $2d16d1aab63a81f4$export$d14e1352e21f4a16(options) {
|
|
|
76
78
|
if (newNode == null) items = items.filter((c)=>c !== node);
|
|
77
79
|
return {
|
|
78
80
|
items: items.map((item)=>{
|
|
79
|
-
if (item === node)
|
|
81
|
+
if (item === node) // newNode cannot be null here due to the above filter.
|
|
82
|
+
return newNode;
|
|
80
83
|
return item;
|
|
81
84
|
}),
|
|
82
85
|
nodeMap: map
|
|
@@ -84,11 +87,11 @@ function $2d16d1aab63a81f4$export$d14e1352e21f4a16(options) {
|
|
|
84
87
|
}
|
|
85
88
|
function addNode(node, map) {
|
|
86
89
|
map.set(node.key, node);
|
|
87
|
-
for (let child of node.children)addNode(child, map);
|
|
90
|
+
if (node.children) for (let child of node.children)addNode(child, map);
|
|
88
91
|
}
|
|
89
92
|
function deleteNode(node, map) {
|
|
90
93
|
map.delete(node.key);
|
|
91
|
-
for (let child of node.children)deleteNode(child, map);
|
|
94
|
+
if (node.children) for (let child of node.children)deleteNode(child, map);
|
|
92
95
|
}
|
|
93
96
|
return {
|
|
94
97
|
items: items,
|
|
@@ -128,7 +131,8 @@ function $2d16d1aab63a81f4$export$d14e1352e21f4a16(options) {
|
|
|
128
131
|
let parentNode = nodeMap.get(node.parentKey);
|
|
129
132
|
let nodes = parentNode ? parentNode.children : items;
|
|
130
133
|
let index = nodes.indexOf(node);
|
|
131
|
-
|
|
134
|
+
var _parentNode_key;
|
|
135
|
+
this.insert((_parentNode_key = parentNode === null || parentNode === void 0 ? void 0 : parentNode.key) !== null && _parentNode_key !== void 0 ? _parentNode_key : null, index, ...values);
|
|
132
136
|
},
|
|
133
137
|
insertAfter (key, ...values) {
|
|
134
138
|
let node = nodeMap.get(key);
|
|
@@ -136,7 +140,8 @@ function $2d16d1aab63a81f4$export$d14e1352e21f4a16(options) {
|
|
|
136
140
|
let parentNode = nodeMap.get(node.parentKey);
|
|
137
141
|
let nodes = parentNode ? parentNode.children : items;
|
|
138
142
|
let index = nodes.indexOf(node);
|
|
139
|
-
|
|
143
|
+
var _parentNode_key;
|
|
144
|
+
this.insert((_parentNode_key = parentNode === null || parentNode === void 0 ? void 0 : parentNode.key) !== null && _parentNode_key !== void 0 ? _parentNode_key : null, index + 1, ...values);
|
|
140
145
|
},
|
|
141
146
|
prepend (parentKey, ...values) {
|
|
142
147
|
this.insert(parentKey, 0, ...values);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;;;AAAA;;;;;;;;;;CAUC;AA+GM,SAAS,0CAA8B,OAAuB;IACnE,IAAI,gBACF,eAAe,EAAE,uBACjB,mBAAmB,UACnB,SAAS,CAAC;YAAc;eAAA,CAAA,WAAA,KAAK,EAAE,cAAP,sBAAA,WAAW,KAAK,GAAG;IAAD,gBAC1C,cAAc,CAAC,OAAc,KAAK,QAAQ,EAC3C,GAAG;IAEJ,kDAAkD;IAClD,IAAI,CAAC,MAAM,SAAS,GAAG,CAAA,GAAA,qBAAO,EAA0D,IAAM,UAAU,cAAc,IAAI;IAC1H,IAAI,SAAC,KAAK,WAAE,OAAO,EAAC,GAAG;IAEvB,IAAI,CAAC,cAAc,gBAAgB,GAAG,CAAA,GAAA,qBAAO,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;oBACX,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,GAAQ,EAAE,MAA0C,EAAE,WAAkC;QAChI,IAAI,OAAO,YAAY,GAAG,CAAC;QAC3B,IAAI,CAAC,MACH,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,KAAK,SAAS,CAAE;YACrB,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,MACb,WAAW,SAAS,MAAM,CAAC,CAAA,IAAK,MAAM;YAGxC,KAAK,QAAQ,GAAG,SAAS,GAAG,CAAC,CAAA;gBAC3B,IAAI,UAAU,MACZ,OAAO;gBAGT,OAAO;YACT;YAEA,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,OAAO;gBAGT,OAAO;YACT;YACA,SAAS;QACX;IACF;IAEA,SAAS,QAAQ,IAAiB,EAAE,GAA0B;QAC5D,IAAI,GAAG,CAAC,KAAK,GAAG,EAAE;QAClB,KAAK,IAAI,SAAS,KAAK,QAAQ,CAC7B,QAAQ,OAAO;IAEnB;IAEA,SAAS,WAAW,IAAiB,EAAE,GAA0B;QAC/D,IAAI,MAAM,CAAC,KAAK,GAAG;QACnB,KAAK,IAAI,SAAS,KAAK,QAAQ,CAC7B,WAAW,OAAO;IAEtB;IAEA,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,CAAC,KAAK,CAAC,GAAG;+BAC7B;+BACA,WAAW,QAAQ,CAAC,KAAK,CAAC;yBAC9B;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,MAAM,OAAO,CAAC;YAC1B,IAAI,CAAC,MAAM,CAAC,uBAAA,iCAAA,WAAY,GAAG,EAAE,UAAU;QACzC;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,MAAM,OAAO,CAAC;YAC1B,IAAI,CAAC,MAAM,CAAC,uBAAA,iCAAA,WAAY,GAAG,EAAE,QAAQ,MAAM;QAC7C;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,CAAC,MAAM,KAAK;YACxD;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,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,CAAC,KAAK,CAAC,GAAG;4BAChC;+BACG,WAAW,QAAQ,CAAC,KAAK,CAAC;yBAC9B;oBACH,CAAA,GAAI;YACN;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","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,\n /** The value object for the tree node. */\n value: T,\n /** Children of the tree node. */\n children: TreeNode<T>[]\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>,\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>, 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.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) {\n children = children.filter(c => c !== node);\n }\n\n copy.children = children.map(child => {\n if (child === node) {\n return newNode;\n }\n\n return child;\n });\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 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 for (let child of node.children) {\n addNode(child, map);\n }\n }\n\n function deleteNode(node: TreeNode<T>, map: Map<Key, TreeNode<T>>) {\n map.delete(node.key);\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, 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, 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 * 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"}
|
package/dist/useTreeData.mjs
CHANGED
|
@@ -49,7 +49,7 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
|
|
|
49
49
|
if (newNode == null) deleteNode(node, map);
|
|
50
50
|
else addNode(newNode, map);
|
|
51
51
|
// Walk up the tree and update each parent to refer to the new children.
|
|
52
|
-
while(node.parentKey){
|
|
52
|
+
while(node && node.parentKey){
|
|
53
53
|
let nextParent = map.get(node.parentKey);
|
|
54
54
|
let copy = {
|
|
55
55
|
key: nextParent.key,
|
|
@@ -58,11 +58,13 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
|
|
|
58
58
|
children: null
|
|
59
59
|
};
|
|
60
60
|
let children = nextParent.children;
|
|
61
|
-
if (newNode == null) children = children.filter((c)=>c !== node);
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
if (newNode == null && children) children = children.filter((c)=>c !== node);
|
|
62
|
+
var _children_map;
|
|
63
|
+
copy.children = (_children_map = children === null || children === void 0 ? void 0 : children.map((child)=>{
|
|
64
|
+
if (child === node) // newNode cannot be null here due to the above filter.
|
|
65
|
+
return newNode;
|
|
64
66
|
return child;
|
|
65
|
-
});
|
|
67
|
+
})) !== null && _children_map !== void 0 ? _children_map : null;
|
|
66
68
|
map.set(copy.key, copy);
|
|
67
69
|
newNode = copy;
|
|
68
70
|
node = nextParent;
|
|
@@ -70,7 +72,8 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
|
|
|
70
72
|
if (newNode == null) items = items.filter((c)=>c !== node);
|
|
71
73
|
return {
|
|
72
74
|
items: items.map((item)=>{
|
|
73
|
-
if (item === node)
|
|
75
|
+
if (item === node) // newNode cannot be null here due to the above filter.
|
|
76
|
+
return newNode;
|
|
74
77
|
return item;
|
|
75
78
|
}),
|
|
76
79
|
nodeMap: map
|
|
@@ -78,11 +81,11 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
|
|
|
78
81
|
}
|
|
79
82
|
function addNode(node, map) {
|
|
80
83
|
map.set(node.key, node);
|
|
81
|
-
for (let child of node.children)addNode(child, map);
|
|
84
|
+
if (node.children) for (let child of node.children)addNode(child, map);
|
|
82
85
|
}
|
|
83
86
|
function deleteNode(node, map) {
|
|
84
87
|
map.delete(node.key);
|
|
85
|
-
for (let child of node.children)deleteNode(child, map);
|
|
88
|
+
if (node.children) for (let child of node.children)deleteNode(child, map);
|
|
86
89
|
}
|
|
87
90
|
return {
|
|
88
91
|
items: items,
|
|
@@ -122,7 +125,8 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
|
|
|
122
125
|
let parentNode = nodeMap.get(node.parentKey);
|
|
123
126
|
let nodes = parentNode ? parentNode.children : items;
|
|
124
127
|
let index = nodes.indexOf(node);
|
|
125
|
-
|
|
128
|
+
var _parentNode_key;
|
|
129
|
+
this.insert((_parentNode_key = parentNode === null || parentNode === void 0 ? void 0 : parentNode.key) !== null && _parentNode_key !== void 0 ? _parentNode_key : null, index, ...values);
|
|
126
130
|
},
|
|
127
131
|
insertAfter (key, ...values) {
|
|
128
132
|
let node = nodeMap.get(key);
|
|
@@ -130,7 +134,8 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
|
|
|
130
134
|
let parentNode = nodeMap.get(node.parentKey);
|
|
131
135
|
let nodes = parentNode ? parentNode.children : items;
|
|
132
136
|
let index = nodes.indexOf(node);
|
|
133
|
-
|
|
137
|
+
var _parentNode_key;
|
|
138
|
+
this.insert((_parentNode_key = parentNode === null || parentNode === void 0 ? void 0 : parentNode.key) !== null && _parentNode_key !== void 0 ? _parentNode_key : null, index + 1, ...values);
|
|
134
139
|
},
|
|
135
140
|
prepend (parentKey, ...values) {
|
|
136
141
|
this.insert(parentKey, 0, ...values);
|
|
@@ -49,7 +49,7 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
|
|
|
49
49
|
if (newNode == null) deleteNode(node, map);
|
|
50
50
|
else addNode(newNode, map);
|
|
51
51
|
// Walk up the tree and update each parent to refer to the new children.
|
|
52
|
-
while(node.parentKey){
|
|
52
|
+
while(node && node.parentKey){
|
|
53
53
|
let nextParent = map.get(node.parentKey);
|
|
54
54
|
let copy = {
|
|
55
55
|
key: nextParent.key,
|
|
@@ -58,11 +58,13 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
|
|
|
58
58
|
children: null
|
|
59
59
|
};
|
|
60
60
|
let children = nextParent.children;
|
|
61
|
-
if (newNode == null) children = children.filter((c)=>c !== node);
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
if (newNode == null && children) children = children.filter((c)=>c !== node);
|
|
62
|
+
var _children_map;
|
|
63
|
+
copy.children = (_children_map = children === null || children === void 0 ? void 0 : children.map((child)=>{
|
|
64
|
+
if (child === node) // newNode cannot be null here due to the above filter.
|
|
65
|
+
return newNode;
|
|
64
66
|
return child;
|
|
65
|
-
});
|
|
67
|
+
})) !== null && _children_map !== void 0 ? _children_map : null;
|
|
66
68
|
map.set(copy.key, copy);
|
|
67
69
|
newNode = copy;
|
|
68
70
|
node = nextParent;
|
|
@@ -70,7 +72,8 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
|
|
|
70
72
|
if (newNode == null) items = items.filter((c)=>c !== node);
|
|
71
73
|
return {
|
|
72
74
|
items: items.map((item)=>{
|
|
73
|
-
if (item === node)
|
|
75
|
+
if (item === node) // newNode cannot be null here due to the above filter.
|
|
76
|
+
return newNode;
|
|
74
77
|
return item;
|
|
75
78
|
}),
|
|
76
79
|
nodeMap: map
|
|
@@ -78,11 +81,11 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
|
|
|
78
81
|
}
|
|
79
82
|
function addNode(node, map) {
|
|
80
83
|
map.set(node.key, node);
|
|
81
|
-
for (let child of node.children)addNode(child, map);
|
|
84
|
+
if (node.children) for (let child of node.children)addNode(child, map);
|
|
82
85
|
}
|
|
83
86
|
function deleteNode(node, map) {
|
|
84
87
|
map.delete(node.key);
|
|
85
|
-
for (let child of node.children)deleteNode(child, map);
|
|
88
|
+
if (node.children) for (let child of node.children)deleteNode(child, map);
|
|
86
89
|
}
|
|
87
90
|
return {
|
|
88
91
|
items: items,
|
|
@@ -122,7 +125,8 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
|
|
|
122
125
|
let parentNode = nodeMap.get(node.parentKey);
|
|
123
126
|
let nodes = parentNode ? parentNode.children : items;
|
|
124
127
|
let index = nodes.indexOf(node);
|
|
125
|
-
|
|
128
|
+
var _parentNode_key;
|
|
129
|
+
this.insert((_parentNode_key = parentNode === null || parentNode === void 0 ? void 0 : parentNode.key) !== null && _parentNode_key !== void 0 ? _parentNode_key : null, index, ...values);
|
|
126
130
|
},
|
|
127
131
|
insertAfter (key, ...values) {
|
|
128
132
|
let node = nodeMap.get(key);
|
|
@@ -130,7 +134,8 @@ function $be2ea0343af54212$export$d14e1352e21f4a16(options) {
|
|
|
130
134
|
let parentNode = nodeMap.get(node.parentKey);
|
|
131
135
|
let nodes = parentNode ? parentNode.children : items;
|
|
132
136
|
let index = nodes.indexOf(node);
|
|
133
|
-
|
|
137
|
+
var _parentNode_key;
|
|
138
|
+
this.insert((_parentNode_key = parentNode === null || parentNode === void 0 ? void 0 : parentNode.key) !== null && _parentNode_key !== void 0 ? _parentNode_key : null, index + 1, ...values);
|
|
134
139
|
},
|
|
135
140
|
prepend (parentKey, ...values) {
|
|
136
141
|
this.insert(parentKey, 0, ...values);
|
|
@@ -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,\n /** The value object for the tree node. */\n value: T,\n /** Children of the tree node. */\n children: TreeNode<T>[]\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>,\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>, 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.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) {\n children = children.filter(c => c !== node);\n }\n\n copy.children = children.map(child => {\n if (child === node) {\n return newNode;\n }\n\n return child;\n });\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 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 for (let child of node.children) {\n addNode(child, map);\n }\n }\n\n function deleteNode(node: TreeNode<T>, map: Map<Key, TreeNode<T>>) {\n map.delete(node.key);\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, 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, 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":"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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-stately/data",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.12.0",
|
|
4
4
|
"description": "Spectrum UI components in React",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -22,13 +22,14 @@
|
|
|
22
22
|
"url": "https://github.com/adobe/react-spectrum"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@react-types/shared": "^3.
|
|
25
|
+
"@react-types/shared": "^3.26.0",
|
|
26
26
|
"@swc/helpers": "^0.5.0"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
|
-
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
|
|
29
|
+
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
|
|
30
30
|
},
|
|
31
31
|
"publishConfig": {
|
|
32
32
|
"access": "public"
|
|
33
|
-
}
|
|
34
|
-
|
|
33
|
+
},
|
|
34
|
+
"gitHead": "71f0ef23053f9e03ee7e97df736e8b083e006849"
|
|
35
|
+
}
|
package/src/useAsyncList.ts
CHANGED
|
@@ -29,10 +29,10 @@ export interface AsyncListOptions<T, C> {
|
|
|
29
29
|
* An optional function that performs sorting. If not provided,
|
|
30
30
|
* then `sortDescriptor` is passed to the `load` function.
|
|
31
31
|
*/
|
|
32
|
-
sort?: AsyncListLoadFunction<T, C>
|
|
32
|
+
sort?: AsyncListLoadFunction<T, C, AsyncListLoadOptions<T, C> & {sortDescriptor: SortDescriptor}>
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
type AsyncListLoadFunction<T, C> =
|
|
35
|
+
type AsyncListLoadFunction<T, C, S extends AsyncListLoadOptions<T, C> = AsyncListLoadOptions<T, C>> = (state: S) => AsyncListStateUpdate<T, C> | Promise<AsyncListStateUpdate<T, C>>;
|
|
36
36
|
|
|
37
37
|
interface AsyncListLoadOptions<T, C> {
|
|
38
38
|
/** The items currently in the list. */
|
|
@@ -40,7 +40,7 @@ interface AsyncListLoadOptions<T, C> {
|
|
|
40
40
|
/** The keys of the currently selected items in the list. */
|
|
41
41
|
selectedKeys: Selection,
|
|
42
42
|
/** The current sort descriptor for the list. */
|
|
43
|
-
sortDescriptor
|
|
43
|
+
sortDescriptor?: SortDescriptor,
|
|
44
44
|
/** An abort signal used to notify the load function that the request has been aborted. */
|
|
45
45
|
signal: AbortSignal,
|
|
46
46
|
/** The pagination cursor returned from the last page load. */
|
|
@@ -133,7 +133,7 @@ function reducer<T, C>(data: AsyncListState<T, C>, action: Action<T, C>): AsyncL
|
|
|
133
133
|
case 'update':
|
|
134
134
|
return {
|
|
135
135
|
...data,
|
|
136
|
-
...action.updater(data)
|
|
136
|
+
...action.updater?.(data)
|
|
137
137
|
};
|
|
138
138
|
case 'success':
|
|
139
139
|
case 'error':
|
|
@@ -158,10 +158,10 @@ function reducer<T, C>(data: AsyncListState<T, C>, action: Action<T, C>): AsyncL
|
|
|
158
158
|
...data,
|
|
159
159
|
filterText: action.filterText ?? data.filterText,
|
|
160
160
|
state: 'idle',
|
|
161
|
-
items: [...action.items],
|
|
161
|
+
items: [...(action.items) ?? []],
|
|
162
162
|
selectedKeys: selectedKeys === 'all' ? 'all' : new Set(selectedKeys),
|
|
163
163
|
sortDescriptor: action.sortDescriptor ?? data.sortDescriptor,
|
|
164
|
-
abortController:
|
|
164
|
+
abortController: undefined,
|
|
165
165
|
cursor: action.cursor
|
|
166
166
|
};
|
|
167
167
|
case 'error':
|
|
@@ -173,7 +173,7 @@ function reducer<T, C>(data: AsyncListState<T, C>, action: Action<T, C>): AsyncL
|
|
|
173
173
|
...data,
|
|
174
174
|
state: 'error',
|
|
175
175
|
error: action.error,
|
|
176
|
-
abortController:
|
|
176
|
+
abortController: undefined
|
|
177
177
|
};
|
|
178
178
|
case 'loading':
|
|
179
179
|
case 'loadingMore':
|
|
@@ -181,7 +181,7 @@ function reducer<T, C>(data: AsyncListState<T, C>, action: Action<T, C>): AsyncL
|
|
|
181
181
|
case 'filtering':
|
|
182
182
|
// We're already loading, and another load was triggered at the same time.
|
|
183
183
|
// We need to abort the previous load and start a new one.
|
|
184
|
-
data.abortController
|
|
184
|
+
data.abortController?.abort();
|
|
185
185
|
return {
|
|
186
186
|
...data,
|
|
187
187
|
filterText: action.filterText ?? data.filterText,
|
|
@@ -195,7 +195,7 @@ function reducer<T, C>(data: AsyncListState<T, C>, action: Action<T, C>): AsyncL
|
|
|
195
195
|
// Update data but don't abort previous load.
|
|
196
196
|
return {
|
|
197
197
|
...data,
|
|
198
|
-
...action.updater(data)
|
|
198
|
+
...action.updater?.(data)
|
|
199
199
|
};
|
|
200
200
|
default:
|
|
201
201
|
throw new Error(`Invalid action "${action.type}" in state "${data.state}"`);
|
|
@@ -210,10 +210,10 @@ function reducer<T, C>(data: AsyncListState<T, C>, action: Action<T, C>): AsyncL
|
|
|
210
210
|
return {
|
|
211
211
|
...data,
|
|
212
212
|
state: 'idle',
|
|
213
|
-
items: [...data.items, ...action.items],
|
|
213
|
+
items: [...data.items, ...(action.items ?? [])],
|
|
214
214
|
selectedKeys,
|
|
215
215
|
sortDescriptor: action.sortDescriptor ?? data.sortDescriptor,
|
|
216
|
-
abortController:
|
|
216
|
+
abortController: undefined,
|
|
217
217
|
cursor: action.cursor
|
|
218
218
|
};
|
|
219
219
|
case 'error':
|
|
@@ -231,7 +231,7 @@ function reducer<T, C>(data: AsyncListState<T, C>, action: Action<T, C>): AsyncL
|
|
|
231
231
|
case 'filtering':
|
|
232
232
|
// We're already loading more, and another load was triggered at the same time.
|
|
233
233
|
// We need to abort the previous load more and start a new one.
|
|
234
|
-
data.abortController
|
|
234
|
+
data.abortController?.abort();
|
|
235
235
|
return {
|
|
236
236
|
...data,
|
|
237
237
|
filterText: action.filterText ?? data.filterText,
|
|
@@ -244,7 +244,7 @@ function reducer<T, C>(data: AsyncListState<T, C>, action: Action<T, C>): AsyncL
|
|
|
244
244
|
// If already loading more and another loading more is triggered, abort the new load more since
|
|
245
245
|
// it is a duplicate request since the cursor hasn't been updated.
|
|
246
246
|
// Do not overwrite the data.abortController
|
|
247
|
-
action.abortController
|
|
247
|
+
action.abortController?.abort();
|
|
248
248
|
|
|
249
249
|
return data;
|
|
250
250
|
case 'update':
|
|
@@ -252,7 +252,7 @@ function reducer<T, C>(data: AsyncListState<T, C>, action: Action<T, C>): AsyncL
|
|
|
252
252
|
// Update data but don't abort previous load.
|
|
253
253
|
return {
|
|
254
254
|
...data,
|
|
255
|
-
...action.updater(data)
|
|
255
|
+
...action.updater?.(data)
|
|
256
256
|
};
|
|
257
257
|
default:
|
|
258
258
|
throw new Error(`Invalid action "${action.type}" in state "${data.state}"`);
|
|
@@ -278,7 +278,7 @@ export function useAsyncList<T, C = string>(options: AsyncListOptions<T, C>): As
|
|
|
278
278
|
|
|
279
279
|
let [data, dispatch] = useReducer<AsyncListState<T, C>, [Action<T, C>]>(reducer, {
|
|
280
280
|
state: 'idle',
|
|
281
|
-
error:
|
|
281
|
+
error: undefined,
|
|
282
282
|
items: [],
|
|
283
283
|
selectedKeys: initialSelectedKeys === 'all' ? 'all' : new Set(initialSelectedKeys),
|
|
284
284
|
sortDescriptor: initialSortDescriptor,
|
|
@@ -296,7 +296,7 @@ export function useAsyncList<T, C = string>(options: AsyncListOptions<T, C>): As
|
|
|
296
296
|
selectedKeys: data.selectedKeys,
|
|
297
297
|
sortDescriptor: action.sortDescriptor ?? data.sortDescriptor,
|
|
298
298
|
signal: abortController.signal,
|
|
299
|
-
cursor: action.type === 'loadingMore' ? data.cursor :
|
|
299
|
+
cursor: action.type === 'loadingMore' ? data.cursor : undefined,
|
|
300
300
|
filterText: previousFilterText
|
|
301
301
|
});
|
|
302
302
|
|
|
@@ -309,7 +309,7 @@ export function useAsyncList<T, C = string>(options: AsyncListOptions<T, C>): As
|
|
|
309
309
|
dispatchFetch({type: 'filtering', filterText}, load);
|
|
310
310
|
}
|
|
311
311
|
} catch (e) {
|
|
312
|
-
dispatch({type: 'error', error: e, abortController});
|
|
312
|
+
dispatch({type: 'error', error: e as Error, abortController});
|
|
313
313
|
}
|
|
314
314
|
};
|
|
315
315
|
|
|
@@ -345,7 +345,7 @@ export function useAsyncList<T, C = string>(options: AsyncListOptions<T, C>): As
|
|
|
345
345
|
dispatchFetch({type: 'loadingMore'}, load);
|
|
346
346
|
},
|
|
347
347
|
sort(sortDescriptor: SortDescriptor) {
|
|
348
|
-
dispatchFetch({type: 'sorting', sortDescriptor}, sort || load);
|
|
348
|
+
dispatchFetch({type: 'sorting', sortDescriptor}, (sort || load) as AsyncListLoadFunction<T, C>);
|
|
349
349
|
},
|
|
350
350
|
...createListActions({...options, getKey, cursor: data.cursor}, fn => {
|
|
351
351
|
dispatch({type: 'update', updater: fn});
|
package/src/useListData.ts
CHANGED
|
@@ -46,7 +46,7 @@ export interface ListData<T> {
|
|
|
46
46
|
* Gets an item from the list by key.
|
|
47
47
|
* @param key - The key of the item to retrieve.
|
|
48
48
|
*/
|
|
49
|
-
getItem(key: Key): T,
|
|
49
|
+
getItem(key: Key): T | undefined,
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* Inserts items into the list at the given index.
|
|
@@ -186,7 +186,7 @@ export function createListActions<T, C>(opts: CreateListOptions<T, C>, dispatch:
|
|
|
186
186
|
},
|
|
187
187
|
insertBefore(key: Key, ...values: T[]) {
|
|
188
188
|
dispatch(state => {
|
|
189
|
-
let index = state.items.findIndex(item => getKey(item) === key);
|
|
189
|
+
let index = state.items.findIndex(item => getKey?.(item) === key);
|
|
190
190
|
if (index === -1) {
|
|
191
191
|
if (state.items.length === 0) {
|
|
192
192
|
index = 0;
|
|
@@ -200,7 +200,7 @@ export function createListActions<T, C>(opts: CreateListOptions<T, C>, dispatch:
|
|
|
200
200
|
},
|
|
201
201
|
insertAfter(key: Key, ...values: T[]) {
|
|
202
202
|
dispatch(state => {
|
|
203
|
-
let index = state.items.findIndex(item => getKey(item) === key);
|
|
203
|
+
let index = state.items.findIndex(item => getKey?.(item) === key);
|
|
204
204
|
if (index === -1) {
|
|
205
205
|
if (state.items.length === 0) {
|
|
206
206
|
index = 0;
|
|
@@ -221,7 +221,7 @@ export function createListActions<T, C>(opts: CreateListOptions<T, C>, dispatch:
|
|
|
221
221
|
remove(...keys: Key[]) {
|
|
222
222
|
dispatch(state => {
|
|
223
223
|
let keySet = new Set(keys);
|
|
224
|
-
let items = state.items.filter(item => !keySet.has(getKey(item)));
|
|
224
|
+
let items = state.items.filter(item => !keySet.has(getKey!(item)));
|
|
225
225
|
|
|
226
226
|
let selection: Selection = 'all';
|
|
227
227
|
if (state.selectedKeys !== 'all') {
|
|
@@ -252,7 +252,7 @@ export function createListActions<T, C>(opts: CreateListOptions<T, C>, dispatch:
|
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
let selectedKeys = state.selectedKeys;
|
|
255
|
-
let items = state.items.filter(item => !selectedKeys.has(getKey(item)));
|
|
255
|
+
let items = state.items.filter(item => !selectedKeys.has(getKey!(item)));
|
|
256
256
|
return {
|
|
257
257
|
...state,
|
|
258
258
|
items,
|
|
@@ -262,7 +262,7 @@ export function createListActions<T, C>(opts: CreateListOptions<T, C>, dispatch:
|
|
|
262
262
|
},
|
|
263
263
|
move(key: Key, toIndex: number) {
|
|
264
264
|
dispatch(state => {
|
|
265
|
-
let index = state.items.findIndex(item => getKey(item) === key);
|
|
265
|
+
let index = state.items.findIndex(item => getKey!(item) === key);
|
|
266
266
|
if (index === -1) {
|
|
267
267
|
return state;
|
|
268
268
|
}
|
|
@@ -278,32 +278,32 @@ export function createListActions<T, C>(opts: CreateListOptions<T, C>, dispatch:
|
|
|
278
278
|
},
|
|
279
279
|
moveBefore(key: Key, keys: Iterable<Key>) {
|
|
280
280
|
dispatch(state => {
|
|
281
|
-
let toIndex = state.items.findIndex(item => getKey(item) === key);
|
|
281
|
+
let toIndex = state.items.findIndex(item => getKey!(item) === key);
|
|
282
282
|
if (toIndex === -1) {
|
|
283
283
|
return state;
|
|
284
284
|
}
|
|
285
285
|
|
|
286
286
|
// Find indices of keys to move. Sort them so that the order in the list is retained.
|
|
287
287
|
let keyArray = Array.isArray(keys) ? keys : [...keys];
|
|
288
|
-
let indices = keyArray.map(key => state.items.findIndex(item => getKey(item) === key)).sort((a, b) => a - b);
|
|
288
|
+
let indices = keyArray.map(key => state.items.findIndex(item => getKey!(item) === key)).sort((a, b) => a - b);
|
|
289
289
|
return move(state, indices, toIndex);
|
|
290
290
|
});
|
|
291
291
|
},
|
|
292
292
|
moveAfter(key: Key, keys: Iterable<Key>) {
|
|
293
293
|
dispatch(state => {
|
|
294
|
-
let toIndex = state.items.findIndex(item => getKey(item) === key);
|
|
294
|
+
let toIndex = state.items.findIndex(item => getKey!(item) === key);
|
|
295
295
|
if (toIndex === -1) {
|
|
296
296
|
return state;
|
|
297
297
|
}
|
|
298
298
|
|
|
299
299
|
let keyArray = Array.isArray(keys) ? keys : [...keys];
|
|
300
|
-
let indices = keyArray.map(key => state.items.findIndex(item => getKey(item) === key)).sort((a, b) => a - b);
|
|
300
|
+
let indices = keyArray.map(key => state.items.findIndex(item => getKey!(item) === key)).sort((a, b) => a - b);
|
|
301
301
|
return move(state, indices, toIndex + 1);
|
|
302
302
|
});
|
|
303
303
|
},
|
|
304
304
|
update(key: Key, newValue: T) {
|
|
305
305
|
dispatch(state => {
|
|
306
|
-
let index = state.items.findIndex(item => getKey(item) === key);
|
|
306
|
+
let index = state.items.findIndex(item => getKey!(item) === key);
|
|
307
307
|
if (index === -1) {
|
|
308
308
|
return state;
|
|
309
309
|
}
|