Skip to content

Commit 1b4b7b5

Browse files
committed
restoring focus back to the tree if the user was focused on the loader
1 parent 7123f7e commit 1b4b7b5

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

packages/@react-stately/tree/src/useTreeState.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,13 @@ export function useTreeState<T extends object>(props: TreeProps<T>): TreeState<T
6565

6666
// Reset focused key if that item is deleted from the collection.
6767
useEffect(() => {
68-
if (selectionState.focusedKey != null && !tree.getItem(selectionState.focusedKey)) {
69-
selectionState.setFocusedKey(null);
68+
if (selectionState.focusedKey != null) {
69+
let focusedItem = tree.getItem(selectionState.focusedKey);
70+
// TODO: do we want to have the same logic as useListState/useGridState where it tries to find the nearest row?
71+
// We could possibly special case this loader case and have it try to find the item just before it/the parent
72+
if (!focusedItem || focusedItem.type === 'loader' && !focusedItem.props.isLoading) {
73+
selectionState.setFocusedKey(null);
74+
}
7075
}
7176
// eslint-disable-next-line react-hooks/exhaustive-deps
7277
}, [tree, selectionState.focusedKey]);

packages/react-aria-components/test/Tree.test.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,6 +1592,27 @@ describe('Tree', () => {
15921592
expect(documentLoader1ParentStyles.top).toBe('900px');
15931593
expect(documentLoader1ParentStyles.height).toBe('30px');
15941594
});
1595+
1596+
it('should restore focus to the tree if the loader is keyboard focused when loading finishes', async () => {
1597+
let tree = render(
1598+
<VirtualizedLoadingSentinelTree rootIsLoading />
1599+
);
1600+
let treeTester = testUtilUser.createTester('Tree', {root: tree.getByRole('treegrid')});
1601+
let rows = treeTester.rows;
1602+
expect(rows).toHaveLength(8);
1603+
let rootLoaderRow = rows[7];
1604+
expect(rootLoaderRow).toHaveTextContent('Loading...');
1605+
1606+
await user.tab();
1607+
await user.keyboard('{End}');
1608+
expect(document.activeElement).toBe(rootLoaderRow);
1609+
1610+
tree.rerender(
1611+
<VirtualizedLoadingSentinelTree />
1612+
);
1613+
1614+
expect(document.activeElement).toBe(treeTester.tree);
1615+
});
15951616
});
15961617
});
15971618

0 commit comments

Comments
 (0)