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) {