diff --git a/packages/@react-stately/data/docs/useListData.mdx b/packages/@react-stately/data/docs/useListData.mdx index c902a0812ed..f463ea4018a 100644 --- a/packages/@react-stately/data/docs/useListData.mdx +++ b/packages/@react-stately/data/docs/useListData.mdx @@ -150,3 +150,9 @@ list.move('Snake', 0); ```tsx list.update('Snake', {name: 'Rattle Snake'}); ``` + +### Replacing the tree + +``` +list.replaceAll([{name: 'Fox', children: [{name: 'Rabbit'}]}]) +``` \ No newline at end of file diff --git a/packages/@react-stately/data/src/useTreeData.ts b/packages/@react-stately/data/src/useTreeData.ts index 5bcaa98b9f3..84b0ce1097f 100644 --- a/packages/@react-stately/data/src/useTreeData.ts +++ b/packages/@react-stately/data/src/useTreeData.ts @@ -50,7 +50,12 @@ export interface TreeData { * @param key - The key of the item to retrieve. */ getItem(key: Key): TreeNode | undefined, - + + /** + * Replace the whole tree. + * @param newItems - The new items to replace the tree with. + */ + setRootItems(newItems: T[]): void, /** * Inserts an item into a parent node as a child. * @param parentKey - The key of the parent item to insert into. `null` for the root. @@ -257,6 +262,9 @@ export function useTreeData(options: TreeOptions): TreeData getItem(key: Key) { return nodeMap.get(key); }, + setRootItems(newItems: T[]) { + setItems(buildTree(newItems, new Map())); + }, insert(parentKey: Key | null, index: number, ...values: T[]) { setItems(({items, nodeMap: originalMap}) => { let {items: newNodes, nodeMap: newMap} = buildTree(values, originalMap, parentKey); diff --git a/packages/@react-stately/data/test/useTreeData.test.js b/packages/@react-stately/data/test/useTreeData.test.js index eaffc8ad200..b6b1447e005 100644 --- a/packages/@react-stately/data/test/useTreeData.test.js +++ b/packages/@react-stately/data/test/useTreeData.test.js @@ -745,4 +745,19 @@ describe('useTreeData', function () { expect(result.current.items[1].key).toEqual('Emily'); expect(result.current.items.length).toEqual(2); }); + + it('Should replace the tree with new nodes', function () { + const initialItems = [...initial, {name: 'Emily'}, {name: 'Eli'}]; + let {result} = renderHook(() => + useTreeData({initialItems, getChildren, getKey}) + ); + act(() => { + result.current.replaceAll([{name: 'Robert', children: [{name: 'Linh'}]}, {name: 'Stanley'}]); + }); + expect(result.current.items[0].key).toEqual('Robert'); + + expect(result.current.items[0].children[0].key).toEqual('Linh'); + expect(result.current.items[1].key).toEqual('Stanley'); + expect(result.current.items.length).toEqual(2); + }); });