diff --git a/packages/@react-aria/selection/src/ListKeyboardDelegate.ts b/packages/@react-aria/selection/src/ListKeyboardDelegate.ts index c92e16fc8e1..f76d740f5af 100644 --- a/packages/@react-aria/selection/src/ListKeyboardDelegate.ts +++ b/packages/@react-aria/selection/src/ListKeyboardDelegate.ts @@ -78,7 +78,7 @@ export class ListKeyboardDelegate implements KeyboardDelegate { let nextKey = key; while (nextKey != null) { let item = this.collection.getItem(nextKey); - if (item?.type === 'loader' || (item?.type === 'item' && !this.isDisabled(item))) { + if (item?.type === 'item' && !this.isDisabled(item)) { return nextKey; } diff --git a/packages/react-aria-components/example/index.css b/packages/react-aria-components/example/index.css index b75f3affb7f..d2c97174ef5 100644 --- a/packages/react-aria-components/example/index.css +++ b/packages/react-aria-components/example/index.css @@ -23,7 +23,6 @@ html { } } -.tree-loader, .tree-item { padding: 4px 5px; outline: none; diff --git a/packages/react-aria-components/src/Tree.tsx b/packages/react-aria-components/src/Tree.tsx index 0321841dfe3..58a507b1809 100644 --- a/packages/react-aria-components/src/Tree.tsx +++ b/packages/react-aria-components/src/Tree.tsx @@ -699,7 +699,7 @@ export const TreeItem = /*#__PURE__*/ createBranchComponent('item', { +export interface UNSTABLE_TreeLoadingIndicatorRenderProps { /** * What level the tree item has within the tree. * @selector [data-level] @@ -711,44 +711,36 @@ export interface TreeLoaderProps extends RenderProps(props: TreeLoaderProps, ref: ForwardedRef, item: Node) { let state = useContext(TreeStateContext)!; - ref = useObjectRef(ref); - let {rowProps, gridCellProps, ...states} = useTreeItem({node: item}, state, ref); + // This loader row is is non-interactable, but we want the same aria props calculated as a typical row + // @ts-ignore + let {rowProps} = useTreeItem({node: item}, state, ref); let level = rowProps['aria-level'] || 1; let ariaProps = { - role: 'row', 'aria-level': rowProps['aria-level'], 'aria-posinset': rowProps['aria-posinset'], - 'aria-setsize': rowProps['aria-setsize'], - tabIndex: rowProps.tabIndex + 'aria-setsize': rowProps['aria-setsize'] }; - let {isFocusVisible, focusProps} = useFocusRing(); - let renderProps = useRenderProps({ ...props, id: undefined, children: item.rendered, defaultClassName: 'react-aria-TreeLoader', values: { - level, - isFocused: states.isFocused, - isFocusVisible + level } }); return ( <>
-
+
{renderProps.children}
diff --git a/packages/react-aria-components/stories/Tree.stories.tsx b/packages/react-aria-components/stories/Tree.stories.tsx index e0a6f43bdc8..f089d0ec971 100644 --- a/packages/react-aria-components/stories/Tree.stories.tsx +++ b/packages/react-aria-components/stories/Tree.stories.tsx @@ -208,11 +208,7 @@ let rows = [ const MyTreeLoader = () => { return ( - classNames(styles, 'tree-loader', { - focused: isFocused, - 'focus-visible': isFocusVisible - })}> + {({level}) => { let message = `Level ${level} loading spinner`; if (level === 1) { diff --git a/packages/react-aria-components/test/Tree.test.tsx b/packages/react-aria-components/test/Tree.test.tsx index de26b539368..6640907afd1 100644 --- a/packages/react-aria-components/test/Tree.test.tsx +++ b/packages/react-aria-components/test/Tree.test.tsx @@ -1124,7 +1124,7 @@ describe('Tree', () => { expect(cell).toHaveAttribute('aria-colindex', '1'); }); - it('should focus the load more row when using ArrowDown/ArrowUp', async () => { + it('should not focus the load more row when using ArrowDown/ArrowUp', async () => { let {getAllByRole} = render(); let rows = getAllByRole('row'); @@ -1133,18 +1133,19 @@ describe('Tree', () => { await user.tab(); expect(document.activeElement).toBe(rows[0]); - for (let i = 1; i < 8; i++) { + for (let i = 0; i < 5; i++) { await user.keyboard('{ArrowDown}'); - expect(document.activeElement).toBe(rows[i]); } + expect(document.activeElement).toBe(rows[5]); - for (let i = 6; i >= 0; i--) { - await user.keyboard('{ArrowUp}'); - expect(document.activeElement).toBe(rows[i]); - } + await user.keyboard('{ArrowDown}'); + expect(document.activeElement).toBe(rows[7]); + + await user.keyboard('{ArrowUp}'); + expect(document.activeElement).toBe(rows[5]); }); - it('should focus the load more row when using End', async () => { + it('should not focus the load more row when using End', async () => { let {getAllByRole} = render(); let rows = getAllByRole('row'); @@ -1154,14 +1155,14 @@ describe('Tree', () => { await user.tab(); expect(document.activeElement).toBe(rows[0]); await user.keyboard('{End}'); - expect(document.activeElement).toBe(rows[21]); + expect(document.activeElement).toBe(rows[20]); // Check that it didn't shift the focusedkey to the loader key even if DOM focus didn't shift to the loader await user.keyboard('{ArrowUp}'); - expect(document.activeElement).toBe(rows[20]); + expect(document.activeElement).toBe(rows[19]); }); - it('should focus the load more row when using PageDown', async () => { + it('should not focus the load more row when using PageDown', async () => { let {getAllByRole} = render(); let rows = getAllByRole('row'); @@ -1171,11 +1172,11 @@ describe('Tree', () => { await user.tab(); expect(document.activeElement).toBe(rows[0]); await user.keyboard('{PageDown}'); - expect(document.activeElement).toBe(rows[21]); + expect(document.activeElement).toBe(rows[20]); // Check that it didn't shift the focusedkey to the loader key even if DOM focus didn't shift to the loader await user.keyboard('{ArrowUp}'); - expect(document.activeElement).toBe(rows[20]); + expect(document.activeElement).toBe(rows[19]); }); it('should not render no results state and the loader at the same time', () => {