diff --git a/packages/@react-aria/selection/src/useSelectableCollection.ts b/packages/@react-aria/selection/src/useSelectableCollection.ts
index 8646efb427c..cddda10c774 100644
--- a/packages/@react-aria/selection/src/useSelectableCollection.ts
+++ b/packages/@react-aria/selection/src/useSelectableCollection.ts
@@ -465,6 +465,11 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions
const didAutoFocusRef = useRef(false);
useEffect(() => {
if (autoFocusRef.current) {
+ // Don't autofocus an empty collection. Wait until items are added.
+ if (manager.collection.size === 0) {
+ return;
+ }
+
let focusedKey: Key | null = null;
// Check focus strategy to determine which item to focus
@@ -493,11 +498,8 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions
focusSafely(ref.current);
}
- // Wait until the collection has items to autofocus.
- if (manager.collection.size > 0) {
- autoFocusRef.current = false;
- didAutoFocusRef.current = true;
- }
+ autoFocusRef.current = false;
+ didAutoFocusRef.current = true;
}
});
@@ -581,7 +583,7 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions
// This will be marshalled to either the first or last item depending on where focus came from.
let tabIndex: number | undefined = undefined;
if (!shouldUseVirtualFocus) {
- tabIndex = manager.focusedKey == null ? 0 : -1;
+ tabIndex = manager.focusedKey == null && manager.collection.size > 0 ? 0 : -1;
}
let collectionId = useCollectionId(manager.collection);
diff --git a/packages/react-aria-components/test/Select.test.js b/packages/react-aria-components/test/Select.test.js
index c5e44c1133b..19920390c3f 100644
--- a/packages/react-aria-components/test/Select.test.js
+++ b/packages/react-aria-components/test/Select.test.js
@@ -192,6 +192,28 @@ describe('Select', () => {
expect(option).toHaveTextContent('No results');
});
+ it('should not allow empty listbox to steal focus from other elements in the popover', async () => {
+ let {getByTestId, getByRole} = render(
+
+ );
+
+ let selectTester = testUtilUser.createTester('Select', {root: getByTestId('select')});
+ await selectTester.open();
+
+ let listbox = getByRole('listbox');
+ expect(listbox).toHaveAttribute('tabIndex', '-1');
+ });
+
it('should support render props', async () => {
let {getByTestId} = render(