diff --git a/packages/react-aria-components/test/Tree.test.tsx b/packages/react-aria-components/test/Tree.test.tsx index c0087e78fd9..f56a0df175e 100644 --- a/packages/react-aria-components/test/Tree.test.tsx +++ b/packages/react-aria-components/test/Tree.test.tsx @@ -1479,6 +1479,30 @@ describe('Tree', () => { expect(rows).toHaveLength(17); }); + it('should expand/collapse a row when using Space on the row when selectionMode is none', async () => { + if (type !== 'keyboard') { + return; + } + + let {getAllByRole} = render(); + let rows = getAllByRole('row'); + expect(rows).toHaveLength(20); + + await user.tab(); + expect(document.activeElement).toBe(rows[0]); + expect(rows[0]).toHaveAttribute('data-expanded', 'true'); + + await user.keyboard(' '); + expect(document.activeElement).toBe(rows[0]); + expect(rows[0]).not.toHaveAttribute('data-expanded'); + expect(onExpandedChange).toHaveBeenCalledTimes(1); + + await user.keyboard(' '); + expect(document.activeElement).toBe(rows[0]); + expect(rows[0]).toHaveAttribute('data-expanded', 'true'); + expect(onExpandedChange).toHaveBeenCalledTimes(2); + }); + it('should not expand when clicking/using Enter on the row if the row is selectable', async () => { let {getAllByRole} = render(); let rows = getAllByRole('row'); diff --git a/packages/react-aria/src/selection/useSelectableItem.ts b/packages/react-aria/src/selection/useSelectableItem.ts index b45620fc071..b8e2e3c3815 100644 --- a/packages/react-aria/src/selection/useSelectableItem.ts +++ b/packages/react-aria/src/selection/useSelectableItem.ts @@ -297,7 +297,11 @@ export function useSelectableItem(options: SelectableItemOptions): SelectableIte // oxlint-disable-next-line react/react-compiler itemPressProps.onPress = e => { if (hasPrimaryAction || (hasSecondaryAction && e.pointerType !== 'mouse')) { - if (e.pointerType === 'keyboard' && !isActionKey(e.key)) { + if ( + e.pointerType === 'keyboard' && + !isActionKey(e.key) && + !(!allowsSelection && isSelectionKey(e.key)) + ) { return; } @@ -353,7 +357,9 @@ export function useSelectableItem(options: SelectableItemOptions): SelectableIte e.pointerType === 'touch' || e.pointerType === 'pen' || e.pointerType === 'virtual' || - (e.pointerType === 'keyboard' && hasAction && isActionKey(e.key)) || + (e.pointerType === 'keyboard' && + hasAction && + (isActionKey(e.key) || (!allowsSelection && isSelectionKey(e.key)))) || (e.pointerType === 'mouse' && hadPrimaryActionOnPressStart.current) ) { if (hasAction) {