Skip to content

Commit 4288386

Browse files
committed
Fix edge case where item was getting autofocused when backspacing
1 parent 23aea58 commit 4288386

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

packages/@react-aria/selection/src/useSelectableCollection.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,12 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions
420420
bubbles: true
421421
})
422422
);
423+
424+
// If there wasn't a focusable key but the collection had items, then that means we aren't in an intermediate load state and all keys are disabled.
425+
// Reset shouldVirtualFocusFirst so that we don't erronously autofocus an item when the collection is filtered again.
426+
if (manager.collection.size > 0) {
427+
shouldVirtualFocusFirst.current = false;
428+
}
423429
} else {
424430
manager.setFocusedKey(keyToFocus);
425431
// Only set shouldVirtualFocusFirst to false if we've successfully set the first key as the focused key

packages/react-aria-components/test/AriaAutocomplete.test-util.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,31 @@ export const AriaAutocompleteTests = ({renderers, setup, prefix, ariaPattern = '
395395
expect(actionListener).toHaveBeenCalledTimes(0);
396396
});
397397
});
398+
399+
it('should not autofocus the first item if backspacing from a list state where there are only disabled items', async function () {
400+
let {getByRole} = (renderers.disabledItems!)();
401+
let input = getByRole('searchbox');
402+
let menu = getByRole(collectionNodeRole);
403+
let options = within(menu).getAllByRole(collectionItemRole);
404+
expect(options[1]).toHaveAttribute('aria-disabled', 'true');
405+
406+
await user.tab();
407+
expect(document.activeElement).toBe(input);
408+
await user.keyboard('r');
409+
act(() => jest.runAllTimers());
410+
options = within(menu).getAllByRole(collectionItemRole);
411+
expect(options).toHaveLength(1);
412+
expect(input).not.toHaveAttribute('aria-activedescendant');
413+
expect(options[0]).toHaveAttribute('aria-disabled', 'true');
414+
415+
await user.keyboard('{Backspace}');
416+
act(() => jest.runAllTimers());
417+
options = within(menu).getAllByRole(collectionItemRole);
418+
expect(input).not.toHaveAttribute('aria-activedescendant');
419+
await user.keyboard('{ArrowDown}');
420+
act(() => jest.runAllTimers());
421+
expect(input).toHaveAttribute('aria-activedescendant', options[0].id);
422+
});
398423
}
399424

400425
let filterTests = (renderer) => {

0 commit comments

Comments
 (0)