@react-aria/selection 3.20.1 → 3.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/DOMLayoutDelegate.main.js +9 -6
  2. package/dist/DOMLayoutDelegate.main.js.map +1 -1
  3. package/dist/DOMLayoutDelegate.mjs +9 -6
  4. package/dist/DOMLayoutDelegate.module.js +9 -6
  5. package/dist/DOMLayoutDelegate.module.js.map +1 -1
  6. package/dist/ListKeyboardDelegate.main.js +38 -30
  7. package/dist/ListKeyboardDelegate.main.js.map +1 -1
  8. package/dist/ListKeyboardDelegate.mjs +38 -30
  9. package/dist/ListKeyboardDelegate.module.js +38 -30
  10. package/dist/ListKeyboardDelegate.module.js.map +1 -1
  11. package/dist/types.d.ts +14 -14
  12. package/dist/types.d.ts.map +1 -1
  13. package/dist/useSelectableCollection.main.js +103 -31
  14. package/dist/useSelectableCollection.main.js.map +1 -1
  15. package/dist/useSelectableCollection.mjs +104 -32
  16. package/dist/useSelectableCollection.module.js +104 -32
  17. package/dist/useSelectableCollection.module.js.map +1 -1
  18. package/dist/useSelectableItem.main.js +28 -12
  19. package/dist/useSelectableItem.main.js.map +1 -1
  20. package/dist/useSelectableItem.mjs +30 -14
  21. package/dist/useSelectableItem.module.js +30 -14
  22. package/dist/useSelectableItem.module.js.map +1 -1
  23. package/dist/useTypeSelect.main.js +12 -10
  24. package/dist/useTypeSelect.main.js.map +1 -1
  25. package/dist/useTypeSelect.mjs +12 -10
  26. package/dist/useTypeSelect.module.js +12 -10
  27. package/dist/useTypeSelect.module.js.map +1 -1
  28. package/dist/utils.main.js +0 -5
  29. package/dist/utils.main.js.map +1 -1
  30. package/dist/utils.mjs +2 -6
  31. package/dist/utils.module.js +2 -6
  32. package/dist/utils.module.js.map +1 -1
  33. package/package.json +10 -10
  34. package/src/DOMLayoutDelegate.ts +11 -8
  35. package/src/ListKeyboardDelegate.ts +46 -34
  36. package/src/useSelectableCollection.ts +118 -36
  37. package/src/useSelectableItem.ts +35 -18
  38. package/src/useTypeSelect.ts +16 -14
  39. package/src/utils.ts +1 -9
@@ -1,9 +1,9 @@
1
- import {isCtrlKeyPressed as $feb5ffebff200149$export$16792effe837dba3, isNonContiguousSelectionModifier as $feb5ffebff200149$export$d3e3bd3e26688c04} from "./utils.mjs";
1
+ import {isNonContiguousSelectionModifier as $feb5ffebff200149$export$d3e3bd3e26688c04} from "./utils.mjs";
2
2
  import {useTypeSelect as $fb3050f43d946246$export$e32c88dfddc6e1d8} from "./useTypeSelect.mjs";
3
+ import {useRouter as $3H3GQ$useRouter, isCtrlKeyPressed as $3H3GQ$isCtrlKeyPressed, focusWithoutScrolling as $3H3GQ$focusWithoutScrolling, useEvent as $3H3GQ$useEvent, scrollIntoViewport as $3H3GQ$scrollIntoViewport, FOCUS_EVENT as $3H3GQ$FOCUS_EVENT, useEffectEvent as $3H3GQ$useEffectEvent, UPDATE_ACTIVEDESCENDANT as $3H3GQ$UPDATE_ACTIVEDESCENDANT, useUpdateLayoutEffect as $3H3GQ$useUpdateLayoutEffect, CLEAR_FOCUS_EVENT as $3H3GQ$CLEAR_FOCUS_EVENT, scrollIntoView as $3H3GQ$scrollIntoView, mergeProps as $3H3GQ$mergeProps} from "@react-aria/utils";
3
4
  import {flushSync as $3H3GQ$flushSync} from "react-dom";
4
5
  import {useRef as $3H3GQ$useRef, useEffect as $3H3GQ$useEffect} from "react";
5
6
  import {getFocusableTreeWalker as $3H3GQ$getFocusableTreeWalker, focusSafely as $3H3GQ$focusSafely} from "@react-aria/focus";
6
- import {useRouter as $3H3GQ$useRouter, focusWithoutScrolling as $3H3GQ$focusWithoutScrolling, useEvent as $3H3GQ$useEvent, scrollIntoViewport as $3H3GQ$scrollIntoViewport, scrollIntoView as $3H3GQ$scrollIntoView, mergeProps as $3H3GQ$mergeProps} from "@react-aria/utils";
7
7
  import {getInteractionModality as $3H3GQ$getInteractionModality} from "@react-aria/interactions";
8
8
  import {useLocale as $3H3GQ$useLocale} from "@react-aria/i18n";
9
9
 
@@ -31,21 +31,23 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
31
31
  let { direction: direction } = (0, $3H3GQ$useLocale)();
32
32
  let router = (0, $3H3GQ$useRouter)();
33
33
  let onKeyDown = (e)=>{
34
+ var _ref_current;
34
35
  // Prevent option + tab from doing anything since it doesn't move focus to the cells, only buttons/checkboxes
35
36
  if (e.altKey && e.key === 'Tab') e.preventDefault();
36
37
  // Keyboard events bubble through portals. Don't handle keyboard events
37
38
  // for elements outside the collection (e.g. menus).
38
- if (!ref.current.contains(e.target)) return;
39
+ if (!((_ref_current = ref.current) === null || _ref_current === void 0 ? void 0 : _ref_current.contains(e.target))) return;
39
40
  const navigateToKey = (key, childFocus)=>{
40
41
  if (key != null) {
41
42
  if (manager.isLink(key) && linkBehavior === 'selection' && selectOnFocus && !(0, $feb5ffebff200149$export$d3e3bd3e26688c04)(e)) {
43
+ var _scrollRef_current;
42
44
  // Set focused key and re-render synchronously to bring item into view if needed.
43
45
  (0, $3H3GQ$flushSync)(()=>{
44
46
  manager.setFocusedKey(key, childFocus);
45
47
  });
46
- let item = scrollRef.current.querySelector(`[data-key="${CSS.escape(key.toString())}"]`);
48
+ let item = (_scrollRef_current = scrollRef.current) === null || _scrollRef_current === void 0 ? void 0 : _scrollRef_current.querySelector(`[data-key="${CSS.escape(key.toString())}"]`);
47
49
  let itemProps = manager.getItemProps(key);
48
- router.open(item, e, itemProps.href, itemProps.routerOptions);
50
+ if (item) router.open(item, e, itemProps.href, itemProps.routerOptions);
49
51
  return;
50
52
  }
51
53
  manager.setFocusedKey(key, childFocus);
@@ -80,7 +82,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
80
82
  case 'ArrowLeft':
81
83
  if (delegate.getKeyLeftOf) {
82
84
  var _delegate_getKeyLeftOf, _delegate_getFirstKey2, _delegate_getLastKey2;
83
- let nextKey = (_delegate_getKeyLeftOf = delegate.getKeyLeftOf) === null || _delegate_getKeyLeftOf === void 0 ? void 0 : _delegate_getKeyLeftOf.call(delegate, manager.focusedKey);
85
+ let nextKey = manager.focusedKey != null ? (_delegate_getKeyLeftOf = delegate.getKeyLeftOf) === null || _delegate_getKeyLeftOf === void 0 ? void 0 : _delegate_getKeyLeftOf.call(delegate, manager.focusedKey) : null;
84
86
  if (nextKey == null && shouldFocusWrap) nextKey = direction === 'rtl' ? (_delegate_getFirstKey2 = delegate.getFirstKey) === null || _delegate_getFirstKey2 === void 0 ? void 0 : _delegate_getFirstKey2.call(delegate, manager.focusedKey) : (_delegate_getLastKey2 = delegate.getLastKey) === null || _delegate_getLastKey2 === void 0 ? void 0 : _delegate_getLastKey2.call(delegate, manager.focusedKey);
85
87
  if (nextKey != null) {
86
88
  e.preventDefault();
@@ -91,7 +93,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
91
93
  case 'ArrowRight':
92
94
  if (delegate.getKeyRightOf) {
93
95
  var _delegate_getKeyRightOf, _delegate_getLastKey3, _delegate_getFirstKey3;
94
- let nextKey = (_delegate_getKeyRightOf = delegate.getKeyRightOf) === null || _delegate_getKeyRightOf === void 0 ? void 0 : _delegate_getKeyRightOf.call(delegate, manager.focusedKey);
96
+ let nextKey = manager.focusedKey != null ? (_delegate_getKeyRightOf = delegate.getKeyRightOf) === null || _delegate_getKeyRightOf === void 0 ? void 0 : _delegate_getKeyRightOf.call(delegate, manager.focusedKey) : null;
95
97
  if (nextKey == null && shouldFocusWrap) nextKey = direction === 'rtl' ? (_delegate_getLastKey3 = delegate.getLastKey) === null || _delegate_getLastKey3 === void 0 ? void 0 : _delegate_getLastKey3.call(delegate, manager.focusedKey) : (_delegate_getFirstKey3 = delegate.getFirstKey) === null || _delegate_getFirstKey3 === void 0 ? void 0 : _delegate_getFirstKey3.call(delegate, manager.focusedKey);
96
98
  if (nextKey != null) {
97
99
  e.preventDefault();
@@ -101,24 +103,30 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
101
103
  break;
102
104
  case 'Home':
103
105
  if (delegate.getFirstKey) {
106
+ if (manager.focusedKey === null && e.shiftKey) return;
104
107
  e.preventDefault();
105
- let firstKey = delegate.getFirstKey(manager.focusedKey, (0, $feb5ffebff200149$export$16792effe837dba3)(e));
108
+ let firstKey = delegate.getFirstKey(manager.focusedKey, (0, $3H3GQ$isCtrlKeyPressed)(e));
106
109
  manager.setFocusedKey(firstKey);
107
- if ((0, $feb5ffebff200149$export$16792effe837dba3)(e) && e.shiftKey && manager.selectionMode === 'multiple') manager.extendSelection(firstKey);
108
- else if (selectOnFocus) manager.replaceSelection(firstKey);
110
+ if (firstKey != null) {
111
+ if ((0, $3H3GQ$isCtrlKeyPressed)(e) && e.shiftKey && manager.selectionMode === 'multiple') manager.extendSelection(firstKey);
112
+ else if (selectOnFocus) manager.replaceSelection(firstKey);
113
+ }
109
114
  }
110
115
  break;
111
116
  case 'End':
112
117
  if (delegate.getLastKey) {
118
+ if (manager.focusedKey === null && e.shiftKey) return;
113
119
  e.preventDefault();
114
- let lastKey = delegate.getLastKey(manager.focusedKey, (0, $feb5ffebff200149$export$16792effe837dba3)(e));
120
+ let lastKey = delegate.getLastKey(manager.focusedKey, (0, $3H3GQ$isCtrlKeyPressed)(e));
115
121
  manager.setFocusedKey(lastKey);
116
- if ((0, $feb5ffebff200149$export$16792effe837dba3)(e) && e.shiftKey && manager.selectionMode === 'multiple') manager.extendSelection(lastKey);
117
- else if (selectOnFocus) manager.replaceSelection(lastKey);
122
+ if (lastKey != null) {
123
+ if ((0, $3H3GQ$isCtrlKeyPressed)(e) && e.shiftKey && manager.selectionMode === 'multiple') manager.extendSelection(lastKey);
124
+ else if (selectOnFocus) manager.replaceSelection(lastKey);
125
+ }
118
126
  }
119
127
  break;
120
128
  case 'PageDown':
121
- if (delegate.getKeyPageBelow) {
129
+ if (delegate.getKeyPageBelow && manager.focusedKey != null) {
122
130
  let nextKey = delegate.getKeyPageBelow(manager.focusedKey);
123
131
  if (nextKey != null) {
124
132
  e.preventDefault();
@@ -127,7 +135,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
127
135
  }
128
136
  break;
129
137
  case 'PageUp':
130
- if (delegate.getKeyPageAbove) {
138
+ if (delegate.getKeyPageAbove && manager.focusedKey != null) {
131
139
  let nextKey = delegate.getKeyPageAbove(manager.focusedKey);
132
140
  if (nextKey != null) {
133
141
  e.preventDefault();
@@ -136,7 +144,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
136
144
  }
137
145
  break;
138
146
  case 'a':
139
- if ((0, $feb5ffebff200149$export$16792effe837dba3)(e) && manager.selectionMode === 'multiple' && disallowSelectAll !== true) {
147
+ if ((0, $3H3GQ$isCtrlKeyPressed)(e) && manager.selectionMode === 'multiple' && disallowSelectAll !== true) {
140
148
  e.preventDefault();
141
149
  manager.selectAll();
142
150
  }
@@ -161,7 +169,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
161
169
  let walker = (0, $3H3GQ$getFocusableTreeWalker)(ref.current, {
162
170
  tabbable: true
163
171
  });
164
- let next;
172
+ let next = undefined;
165
173
  let last;
166
174
  do {
167
175
  last = walker.lastChild();
@@ -179,10 +187,12 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
179
187
  top: 0,
180
188
  left: 0
181
189
  });
182
- (0, $3H3GQ$useEvent)(scrollRef, 'scroll', isVirtualized ? null : ()=>{
190
+ (0, $3H3GQ$useEvent)(scrollRef, 'scroll', isVirtualized ? undefined : ()=>{
191
+ var _scrollRef_current, _scrollRef_current1;
192
+ var _scrollRef_current_scrollTop, _scrollRef_current_scrollLeft;
183
193
  scrollPos.current = {
184
- top: scrollRef.current.scrollTop,
185
- left: scrollRef.current.scrollLeft
194
+ top: (_scrollRef_current_scrollTop = (_scrollRef_current = scrollRef.current) === null || _scrollRef_current === void 0 ? void 0 : _scrollRef_current.scrollTop) !== null && _scrollRef_current_scrollTop !== void 0 ? _scrollRef_current_scrollTop : 0,
195
+ left: (_scrollRef_current_scrollLeft = (_scrollRef_current1 = scrollRef.current) === null || _scrollRef_current1 === void 0 ? void 0 : _scrollRef_current1.scrollLeft) !== null && _scrollRef_current_scrollLeft !== void 0 ? _scrollRef_current_scrollLeft : 0
186
196
  };
187
197
  });
188
198
  let onFocus = (e)=>{
@@ -195,6 +205,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
195
205
  if (!e.currentTarget.contains(e.target)) return;
196
206
  manager.setFocused(true);
197
207
  if (manager.focusedKey == null) {
208
+ var _delegate_getLastKey, _delegate_getFirstKey;
198
209
  let navigateToFirstKey = (key)=>{
199
210
  if (key != null) {
200
211
  manager.setFocusedKey(key);
@@ -206,14 +217,14 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
206
217
  // and either focus the first or last item accordingly.
207
218
  let relatedTarget = e.relatedTarget;
208
219
  var _manager_lastSelectedKey, _manager_firstSelectedKey;
209
- if (relatedTarget && e.currentTarget.compareDocumentPosition(relatedTarget) & Node.DOCUMENT_POSITION_FOLLOWING) navigateToFirstKey((_manager_lastSelectedKey = manager.lastSelectedKey) !== null && _manager_lastSelectedKey !== void 0 ? _manager_lastSelectedKey : delegate.getLastKey());
210
- else navigateToFirstKey((_manager_firstSelectedKey = manager.firstSelectedKey) !== null && _manager_firstSelectedKey !== void 0 ? _manager_firstSelectedKey : delegate.getFirstKey());
211
- } else if (!isVirtualized) {
220
+ if (relatedTarget && e.currentTarget.compareDocumentPosition(relatedTarget) & Node.DOCUMENT_POSITION_FOLLOWING) navigateToFirstKey((_manager_lastSelectedKey = manager.lastSelectedKey) !== null && _manager_lastSelectedKey !== void 0 ? _manager_lastSelectedKey : (_delegate_getLastKey = delegate.getLastKey) === null || _delegate_getLastKey === void 0 ? void 0 : _delegate_getLastKey.call(delegate));
221
+ else navigateToFirstKey((_manager_firstSelectedKey = manager.firstSelectedKey) !== null && _manager_firstSelectedKey !== void 0 ? _manager_firstSelectedKey : (_delegate_getFirstKey = delegate.getFirstKey) === null || _delegate_getFirstKey === void 0 ? void 0 : _delegate_getFirstKey.call(delegate));
222
+ } else if (!isVirtualized && scrollRef.current) {
212
223
  // Restore the scroll position to what it was before.
213
224
  scrollRef.current.scrollTop = scrollPos.current.top;
214
225
  scrollRef.current.scrollLeft = scrollPos.current.left;
215
226
  }
216
- if (manager.focusedKey != null) {
227
+ if (manager.focusedKey != null && scrollRef.current) {
217
228
  // Refocus and scroll the focused item into view if it exists within the scrollable region.
218
229
  let element = scrollRef.current.querySelector(`[data-key="${CSS.escape(manager.focusedKey.toString())}"]`);
219
230
  if (element) {
@@ -230,13 +241,75 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
230
241
  // Don't set blurred and then focused again if moving focus within the collection.
231
242
  if (!e.currentTarget.contains(e.relatedTarget)) manager.setFocused(false);
232
243
  };
244
+ // Ref to track whether the first item in the collection should be automatically focused. Specifically used for autocomplete when user types
245
+ // to focus the first key AFTER the collection updates.
246
+ // TODO: potentially expand the usage of this
247
+ let shouldVirtualFocusFirst = (0, $3H3GQ$useRef)(false);
248
+ // Add event listeners for custom virtual events. These handle updating the focused key in response to various keyboard events
249
+ // at the autocomplete level
250
+ // TODO: fix type later
251
+ (0, $3H3GQ$useEvent)(ref, (0, $3H3GQ$FOCUS_EVENT), !shouldUseVirtualFocus ? undefined : (e)=>{
252
+ let { detail: detail } = e;
253
+ e.stopPropagation();
254
+ manager.setFocused(true);
255
+ // If the user is typing forwards, autofocus the first option in the list.
256
+ if ((detail === null || detail === void 0 ? void 0 : detail.focusStrategy) === 'first') shouldVirtualFocusFirst.current = true;
257
+ });
258
+ let updateActiveDescendant = (0, $3H3GQ$useEffectEvent)(()=>{
259
+ var _delegate_getFirstKey;
260
+ var _delegate_getFirstKey1;
261
+ let keyToFocus = (_delegate_getFirstKey1 = (_delegate_getFirstKey = delegate.getFirstKey) === null || _delegate_getFirstKey === void 0 ? void 0 : _delegate_getFirstKey.call(delegate)) !== null && _delegate_getFirstKey1 !== void 0 ? _delegate_getFirstKey1 : null;
262
+ // If no focusable items exist in the list, make sure to clear any activedescendant that may still exist
263
+ if (keyToFocus == null) {
264
+ var _ref_current;
265
+ (_ref_current = ref.current) === null || _ref_current === void 0 ? void 0 : _ref_current.dispatchEvent(new CustomEvent((0, $3H3GQ$UPDATE_ACTIVEDESCENDANT), {
266
+ cancelable: true,
267
+ bubbles: true
268
+ }));
269
+ // 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.
270
+ // Reset shouldVirtualFocusFirst so that we don't erronously autofocus an item when the collection is filtered again.
271
+ if (manager.collection.size > 0) shouldVirtualFocusFirst.current = false;
272
+ } else {
273
+ manager.setFocusedKey(keyToFocus);
274
+ // Only set shouldVirtualFocusFirst to false if we've successfully set the first key as the focused key
275
+ // If there wasn't a key to focus, we might be in a temporary loading state so we'll want to still focus the first key
276
+ // after the collection updates after load
277
+ shouldVirtualFocusFirst.current = false;
278
+ }
279
+ });
280
+ (0, $3H3GQ$useUpdateLayoutEffect)(()=>{
281
+ if (shouldVirtualFocusFirst.current) updateActiveDescendant();
282
+ }, [
283
+ manager.collection,
284
+ updateActiveDescendant
285
+ ]);
286
+ let resetFocusFirstFlag = (0, $3H3GQ$useEffectEvent)(()=>{
287
+ // If user causes the focused key to change in any other way, clear shouldVirtualFocusFirst so we don't
288
+ // accidentally move focus from under them. Skip this if the collection was empty because we might be in a load
289
+ // state and will still want to focus the first item after load
290
+ if (manager.collection.size > 0) shouldVirtualFocusFirst.current = false;
291
+ });
292
+ (0, $3H3GQ$useUpdateLayoutEffect)(()=>{
293
+ resetFocusFirstFlag();
294
+ }, [
295
+ manager.focusedKey,
296
+ resetFocusFirstFlag
297
+ ]);
298
+ (0, $3H3GQ$useEvent)(ref, (0, $3H3GQ$CLEAR_FOCUS_EVENT), !shouldUseVirtualFocus ? undefined : (e)=>{
299
+ e.stopPropagation();
300
+ manager.setFocused(false);
301
+ manager.setFocusedKey(null);
302
+ });
233
303
  const autoFocusRef = (0, $3H3GQ$useRef)(autoFocus);
234
304
  (0, $3H3GQ$useEffect)(()=>{
235
305
  if (autoFocusRef.current) {
306
+ var _delegate_getFirstKey, _delegate_getLastKey;
236
307
  let focusedKey = null;
308
+ var _delegate_getFirstKey1;
237
309
  // Check focus strategy to determine which item to focus
238
- if (autoFocus === 'first') focusedKey = delegate.getFirstKey();
239
- if (autoFocus === 'last') focusedKey = delegate.getLastKey();
310
+ if (autoFocus === 'first') focusedKey = (_delegate_getFirstKey1 = (_delegate_getFirstKey = delegate.getFirstKey) === null || _delegate_getFirstKey === void 0 ? void 0 : _delegate_getFirstKey.call(delegate)) !== null && _delegate_getFirstKey1 !== void 0 ? _delegate_getFirstKey1 : null;
311
+ var _delegate_getLastKey1;
312
+ if (autoFocus === 'last') focusedKey = (_delegate_getLastKey1 = (_delegate_getLastKey = delegate.getLastKey) === null || _delegate_getLastKey === void 0 ? void 0 : _delegate_getLastKey.call(delegate)) !== null && _delegate_getLastKey1 !== void 0 ? _delegate_getLastKey1 : null;
240
313
  // If there are any selected keys, make the first one the new focus target
241
314
  let selectedKeys = manager.selectedKeys;
242
315
  if (selectedKeys.size) {
@@ -248,14 +321,14 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
248
321
  manager.setFocused(true);
249
322
  manager.setFocusedKey(focusedKey);
250
323
  // If no default focus key is selected, focus the collection itself.
251
- if (focusedKey == null && !shouldUseVirtualFocus) (0, $3H3GQ$focusSafely)(ref.current);
324
+ if (focusedKey == null && !shouldUseVirtualFocus && ref.current) (0, $3H3GQ$focusSafely)(ref.current);
252
325
  }
253
326
  // eslint-disable-next-line react-hooks/exhaustive-deps
254
327
  }, []);
255
328
  // Scroll the focused element into view when the focusedKey changes.
256
329
  let lastFocusedKey = (0, $3H3GQ$useRef)(manager.focusedKey);
257
330
  (0, $3H3GQ$useEffect)(()=>{
258
- if (manager.isFocused && manager.focusedKey != null && (manager.focusedKey !== lastFocusedKey.current || autoFocusRef.current) && (scrollRef === null || scrollRef === void 0 ? void 0 : scrollRef.current)) {
331
+ if (manager.isFocused && manager.focusedKey != null && (manager.focusedKey !== lastFocusedKey.current || autoFocusRef.current) && scrollRef.current && ref.current) {
259
332
  let modality = (0, $3H3GQ$getInteractionModality)();
260
333
  let element = ref.current.querySelector(`[data-key="${CSS.escape(manager.focusedKey.toString())}"]`);
261
334
  if (!element) // If item element wasn't found, return early (don't update autoFocusRef and lastFocusedKey).
@@ -270,7 +343,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
270
343
  }
271
344
  }
272
345
  // If the focused key becomes null (e.g. the last item is deleted), focus the whole collection.
273
- if (!shouldUseVirtualFocus && manager.isFocused && manager.focusedKey == null && lastFocusedKey.current != null) (0, $3H3GQ$focusSafely)(ref.current);
346
+ if (!shouldUseVirtualFocus && manager.isFocused && manager.focusedKey == null && lastFocusedKey.current != null && ref.current) (0, $3H3GQ$focusSafely)(ref.current);
274
347
  lastFocusedKey.current = manager.focusedKey;
275
348
  autoFocusRef.current = false;
276
349
  });
@@ -296,10 +369,9 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
296
369
  if (!disallowTypeAhead) handlers = (0, $3H3GQ$mergeProps)(typeSelectProps, handlers);
297
370
  // If nothing is focused within the collection, make the collection itself tabbable.
298
371
  // This will be marshalled to either the first or last item depending on where focus came from.
299
- // If using virtual focus, don't set a tabIndex at all so that VoiceOver on iOS 14 doesn't try
300
- // to move real DOM focus to the element anyway.
301
- let tabIndex;
372
+ let tabIndex = undefined;
302
373
  if (!shouldUseVirtualFocus) tabIndex = manager.focusedKey == null ? 0 : -1;
374
+ else tabIndex = -1;
303
375
  return {
304
376
  collectionProps: {
305
377
  ...handlers,
@@ -1,9 +1,9 @@
1
- import {isCtrlKeyPressed as $feb5ffebff200149$export$16792effe837dba3, isNonContiguousSelectionModifier as $feb5ffebff200149$export$d3e3bd3e26688c04} from "./utils.module.js";
1
+ import {isNonContiguousSelectionModifier as $feb5ffebff200149$export$d3e3bd3e26688c04} from "./utils.module.js";
2
2
  import {useTypeSelect as $fb3050f43d946246$export$e32c88dfddc6e1d8} from "./useTypeSelect.module.js";
3
+ import {useRouter as $3H3GQ$useRouter, isCtrlKeyPressed as $3H3GQ$isCtrlKeyPressed, focusWithoutScrolling as $3H3GQ$focusWithoutScrolling, useEvent as $3H3GQ$useEvent, scrollIntoViewport as $3H3GQ$scrollIntoViewport, FOCUS_EVENT as $3H3GQ$FOCUS_EVENT, useEffectEvent as $3H3GQ$useEffectEvent, UPDATE_ACTIVEDESCENDANT as $3H3GQ$UPDATE_ACTIVEDESCENDANT, useUpdateLayoutEffect as $3H3GQ$useUpdateLayoutEffect, CLEAR_FOCUS_EVENT as $3H3GQ$CLEAR_FOCUS_EVENT, scrollIntoView as $3H3GQ$scrollIntoView, mergeProps as $3H3GQ$mergeProps} from "@react-aria/utils";
3
4
  import {flushSync as $3H3GQ$flushSync} from "react-dom";
4
5
  import {useRef as $3H3GQ$useRef, useEffect as $3H3GQ$useEffect} from "react";
5
6
  import {getFocusableTreeWalker as $3H3GQ$getFocusableTreeWalker, focusSafely as $3H3GQ$focusSafely} from "@react-aria/focus";
6
- import {useRouter as $3H3GQ$useRouter, focusWithoutScrolling as $3H3GQ$focusWithoutScrolling, useEvent as $3H3GQ$useEvent, scrollIntoViewport as $3H3GQ$scrollIntoViewport, scrollIntoView as $3H3GQ$scrollIntoView, mergeProps as $3H3GQ$mergeProps} from "@react-aria/utils";
7
7
  import {getInteractionModality as $3H3GQ$getInteractionModality} from "@react-aria/interactions";
8
8
  import {useLocale as $3H3GQ$useLocale} from "@react-aria/i18n";
9
9
 
@@ -31,21 +31,23 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
31
31
  let { direction: direction } = (0, $3H3GQ$useLocale)();
32
32
  let router = (0, $3H3GQ$useRouter)();
33
33
  let onKeyDown = (e)=>{
34
+ var _ref_current;
34
35
  // Prevent option + tab from doing anything since it doesn't move focus to the cells, only buttons/checkboxes
35
36
  if (e.altKey && e.key === 'Tab') e.preventDefault();
36
37
  // Keyboard events bubble through portals. Don't handle keyboard events
37
38
  // for elements outside the collection (e.g. menus).
38
- if (!ref.current.contains(e.target)) return;
39
+ if (!((_ref_current = ref.current) === null || _ref_current === void 0 ? void 0 : _ref_current.contains(e.target))) return;
39
40
  const navigateToKey = (key, childFocus)=>{
40
41
  if (key != null) {
41
42
  if (manager.isLink(key) && linkBehavior === 'selection' && selectOnFocus && !(0, $feb5ffebff200149$export$d3e3bd3e26688c04)(e)) {
43
+ var _scrollRef_current;
42
44
  // Set focused key and re-render synchronously to bring item into view if needed.
43
45
  (0, $3H3GQ$flushSync)(()=>{
44
46
  manager.setFocusedKey(key, childFocus);
45
47
  });
46
- let item = scrollRef.current.querySelector(`[data-key="${CSS.escape(key.toString())}"]`);
48
+ let item = (_scrollRef_current = scrollRef.current) === null || _scrollRef_current === void 0 ? void 0 : _scrollRef_current.querySelector(`[data-key="${CSS.escape(key.toString())}"]`);
47
49
  let itemProps = manager.getItemProps(key);
48
- router.open(item, e, itemProps.href, itemProps.routerOptions);
50
+ if (item) router.open(item, e, itemProps.href, itemProps.routerOptions);
49
51
  return;
50
52
  }
51
53
  manager.setFocusedKey(key, childFocus);
@@ -80,7 +82,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
80
82
  case 'ArrowLeft':
81
83
  if (delegate.getKeyLeftOf) {
82
84
  var _delegate_getKeyLeftOf, _delegate_getFirstKey2, _delegate_getLastKey2;
83
- let nextKey = (_delegate_getKeyLeftOf = delegate.getKeyLeftOf) === null || _delegate_getKeyLeftOf === void 0 ? void 0 : _delegate_getKeyLeftOf.call(delegate, manager.focusedKey);
85
+ let nextKey = manager.focusedKey != null ? (_delegate_getKeyLeftOf = delegate.getKeyLeftOf) === null || _delegate_getKeyLeftOf === void 0 ? void 0 : _delegate_getKeyLeftOf.call(delegate, manager.focusedKey) : null;
84
86
  if (nextKey == null && shouldFocusWrap) nextKey = direction === 'rtl' ? (_delegate_getFirstKey2 = delegate.getFirstKey) === null || _delegate_getFirstKey2 === void 0 ? void 0 : _delegate_getFirstKey2.call(delegate, manager.focusedKey) : (_delegate_getLastKey2 = delegate.getLastKey) === null || _delegate_getLastKey2 === void 0 ? void 0 : _delegate_getLastKey2.call(delegate, manager.focusedKey);
85
87
  if (nextKey != null) {
86
88
  e.preventDefault();
@@ -91,7 +93,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
91
93
  case 'ArrowRight':
92
94
  if (delegate.getKeyRightOf) {
93
95
  var _delegate_getKeyRightOf, _delegate_getLastKey3, _delegate_getFirstKey3;
94
- let nextKey = (_delegate_getKeyRightOf = delegate.getKeyRightOf) === null || _delegate_getKeyRightOf === void 0 ? void 0 : _delegate_getKeyRightOf.call(delegate, manager.focusedKey);
96
+ let nextKey = manager.focusedKey != null ? (_delegate_getKeyRightOf = delegate.getKeyRightOf) === null || _delegate_getKeyRightOf === void 0 ? void 0 : _delegate_getKeyRightOf.call(delegate, manager.focusedKey) : null;
95
97
  if (nextKey == null && shouldFocusWrap) nextKey = direction === 'rtl' ? (_delegate_getLastKey3 = delegate.getLastKey) === null || _delegate_getLastKey3 === void 0 ? void 0 : _delegate_getLastKey3.call(delegate, manager.focusedKey) : (_delegate_getFirstKey3 = delegate.getFirstKey) === null || _delegate_getFirstKey3 === void 0 ? void 0 : _delegate_getFirstKey3.call(delegate, manager.focusedKey);
96
98
  if (nextKey != null) {
97
99
  e.preventDefault();
@@ -101,24 +103,30 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
101
103
  break;
102
104
  case 'Home':
103
105
  if (delegate.getFirstKey) {
106
+ if (manager.focusedKey === null && e.shiftKey) return;
104
107
  e.preventDefault();
105
- let firstKey = delegate.getFirstKey(manager.focusedKey, (0, $feb5ffebff200149$export$16792effe837dba3)(e));
108
+ let firstKey = delegate.getFirstKey(manager.focusedKey, (0, $3H3GQ$isCtrlKeyPressed)(e));
106
109
  manager.setFocusedKey(firstKey);
107
- if ((0, $feb5ffebff200149$export$16792effe837dba3)(e) && e.shiftKey && manager.selectionMode === 'multiple') manager.extendSelection(firstKey);
108
- else if (selectOnFocus) manager.replaceSelection(firstKey);
110
+ if (firstKey != null) {
111
+ if ((0, $3H3GQ$isCtrlKeyPressed)(e) && e.shiftKey && manager.selectionMode === 'multiple') manager.extendSelection(firstKey);
112
+ else if (selectOnFocus) manager.replaceSelection(firstKey);
113
+ }
109
114
  }
110
115
  break;
111
116
  case 'End':
112
117
  if (delegate.getLastKey) {
118
+ if (manager.focusedKey === null && e.shiftKey) return;
113
119
  e.preventDefault();
114
- let lastKey = delegate.getLastKey(manager.focusedKey, (0, $feb5ffebff200149$export$16792effe837dba3)(e));
120
+ let lastKey = delegate.getLastKey(manager.focusedKey, (0, $3H3GQ$isCtrlKeyPressed)(e));
115
121
  manager.setFocusedKey(lastKey);
116
- if ((0, $feb5ffebff200149$export$16792effe837dba3)(e) && e.shiftKey && manager.selectionMode === 'multiple') manager.extendSelection(lastKey);
117
- else if (selectOnFocus) manager.replaceSelection(lastKey);
122
+ if (lastKey != null) {
123
+ if ((0, $3H3GQ$isCtrlKeyPressed)(e) && e.shiftKey && manager.selectionMode === 'multiple') manager.extendSelection(lastKey);
124
+ else if (selectOnFocus) manager.replaceSelection(lastKey);
125
+ }
118
126
  }
119
127
  break;
120
128
  case 'PageDown':
121
- if (delegate.getKeyPageBelow) {
129
+ if (delegate.getKeyPageBelow && manager.focusedKey != null) {
122
130
  let nextKey = delegate.getKeyPageBelow(manager.focusedKey);
123
131
  if (nextKey != null) {
124
132
  e.preventDefault();
@@ -127,7 +135,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
127
135
  }
128
136
  break;
129
137
  case 'PageUp':
130
- if (delegate.getKeyPageAbove) {
138
+ if (delegate.getKeyPageAbove && manager.focusedKey != null) {
131
139
  let nextKey = delegate.getKeyPageAbove(manager.focusedKey);
132
140
  if (nextKey != null) {
133
141
  e.preventDefault();
@@ -136,7 +144,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
136
144
  }
137
145
  break;
138
146
  case 'a':
139
- if ((0, $feb5ffebff200149$export$16792effe837dba3)(e) && manager.selectionMode === 'multiple' && disallowSelectAll !== true) {
147
+ if ((0, $3H3GQ$isCtrlKeyPressed)(e) && manager.selectionMode === 'multiple' && disallowSelectAll !== true) {
140
148
  e.preventDefault();
141
149
  manager.selectAll();
142
150
  }
@@ -161,7 +169,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
161
169
  let walker = (0, $3H3GQ$getFocusableTreeWalker)(ref.current, {
162
170
  tabbable: true
163
171
  });
164
- let next;
172
+ let next = undefined;
165
173
  let last;
166
174
  do {
167
175
  last = walker.lastChild();
@@ -179,10 +187,12 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
179
187
  top: 0,
180
188
  left: 0
181
189
  });
182
- (0, $3H3GQ$useEvent)(scrollRef, 'scroll', isVirtualized ? null : ()=>{
190
+ (0, $3H3GQ$useEvent)(scrollRef, 'scroll', isVirtualized ? undefined : ()=>{
191
+ var _scrollRef_current, _scrollRef_current1;
192
+ var _scrollRef_current_scrollTop, _scrollRef_current_scrollLeft;
183
193
  scrollPos.current = {
184
- top: scrollRef.current.scrollTop,
185
- left: scrollRef.current.scrollLeft
194
+ top: (_scrollRef_current_scrollTop = (_scrollRef_current = scrollRef.current) === null || _scrollRef_current === void 0 ? void 0 : _scrollRef_current.scrollTop) !== null && _scrollRef_current_scrollTop !== void 0 ? _scrollRef_current_scrollTop : 0,
195
+ left: (_scrollRef_current_scrollLeft = (_scrollRef_current1 = scrollRef.current) === null || _scrollRef_current1 === void 0 ? void 0 : _scrollRef_current1.scrollLeft) !== null && _scrollRef_current_scrollLeft !== void 0 ? _scrollRef_current_scrollLeft : 0
186
196
  };
187
197
  });
188
198
  let onFocus = (e)=>{
@@ -195,6 +205,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
195
205
  if (!e.currentTarget.contains(e.target)) return;
196
206
  manager.setFocused(true);
197
207
  if (manager.focusedKey == null) {
208
+ var _delegate_getLastKey, _delegate_getFirstKey;
198
209
  let navigateToFirstKey = (key)=>{
199
210
  if (key != null) {
200
211
  manager.setFocusedKey(key);
@@ -206,14 +217,14 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
206
217
  // and either focus the first or last item accordingly.
207
218
  let relatedTarget = e.relatedTarget;
208
219
  var _manager_lastSelectedKey, _manager_firstSelectedKey;
209
- if (relatedTarget && e.currentTarget.compareDocumentPosition(relatedTarget) & Node.DOCUMENT_POSITION_FOLLOWING) navigateToFirstKey((_manager_lastSelectedKey = manager.lastSelectedKey) !== null && _manager_lastSelectedKey !== void 0 ? _manager_lastSelectedKey : delegate.getLastKey());
210
- else navigateToFirstKey((_manager_firstSelectedKey = manager.firstSelectedKey) !== null && _manager_firstSelectedKey !== void 0 ? _manager_firstSelectedKey : delegate.getFirstKey());
211
- } else if (!isVirtualized) {
220
+ if (relatedTarget && e.currentTarget.compareDocumentPosition(relatedTarget) & Node.DOCUMENT_POSITION_FOLLOWING) navigateToFirstKey((_manager_lastSelectedKey = manager.lastSelectedKey) !== null && _manager_lastSelectedKey !== void 0 ? _manager_lastSelectedKey : (_delegate_getLastKey = delegate.getLastKey) === null || _delegate_getLastKey === void 0 ? void 0 : _delegate_getLastKey.call(delegate));
221
+ else navigateToFirstKey((_manager_firstSelectedKey = manager.firstSelectedKey) !== null && _manager_firstSelectedKey !== void 0 ? _manager_firstSelectedKey : (_delegate_getFirstKey = delegate.getFirstKey) === null || _delegate_getFirstKey === void 0 ? void 0 : _delegate_getFirstKey.call(delegate));
222
+ } else if (!isVirtualized && scrollRef.current) {
212
223
  // Restore the scroll position to what it was before.
213
224
  scrollRef.current.scrollTop = scrollPos.current.top;
214
225
  scrollRef.current.scrollLeft = scrollPos.current.left;
215
226
  }
216
- if (manager.focusedKey != null) {
227
+ if (manager.focusedKey != null && scrollRef.current) {
217
228
  // Refocus and scroll the focused item into view if it exists within the scrollable region.
218
229
  let element = scrollRef.current.querySelector(`[data-key="${CSS.escape(manager.focusedKey.toString())}"]`);
219
230
  if (element) {
@@ -230,13 +241,75 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
230
241
  // Don't set blurred and then focused again if moving focus within the collection.
231
242
  if (!e.currentTarget.contains(e.relatedTarget)) manager.setFocused(false);
232
243
  };
244
+ // Ref to track whether the first item in the collection should be automatically focused. Specifically used for autocomplete when user types
245
+ // to focus the first key AFTER the collection updates.
246
+ // TODO: potentially expand the usage of this
247
+ let shouldVirtualFocusFirst = (0, $3H3GQ$useRef)(false);
248
+ // Add event listeners for custom virtual events. These handle updating the focused key in response to various keyboard events
249
+ // at the autocomplete level
250
+ // TODO: fix type later
251
+ (0, $3H3GQ$useEvent)(ref, (0, $3H3GQ$FOCUS_EVENT), !shouldUseVirtualFocus ? undefined : (e)=>{
252
+ let { detail: detail } = e;
253
+ e.stopPropagation();
254
+ manager.setFocused(true);
255
+ // If the user is typing forwards, autofocus the first option in the list.
256
+ if ((detail === null || detail === void 0 ? void 0 : detail.focusStrategy) === 'first') shouldVirtualFocusFirst.current = true;
257
+ });
258
+ let updateActiveDescendant = (0, $3H3GQ$useEffectEvent)(()=>{
259
+ var _delegate_getFirstKey;
260
+ var _delegate_getFirstKey1;
261
+ let keyToFocus = (_delegate_getFirstKey1 = (_delegate_getFirstKey = delegate.getFirstKey) === null || _delegate_getFirstKey === void 0 ? void 0 : _delegate_getFirstKey.call(delegate)) !== null && _delegate_getFirstKey1 !== void 0 ? _delegate_getFirstKey1 : null;
262
+ // If no focusable items exist in the list, make sure to clear any activedescendant that may still exist
263
+ if (keyToFocus == null) {
264
+ var _ref_current;
265
+ (_ref_current = ref.current) === null || _ref_current === void 0 ? void 0 : _ref_current.dispatchEvent(new CustomEvent((0, $3H3GQ$UPDATE_ACTIVEDESCENDANT), {
266
+ cancelable: true,
267
+ bubbles: true
268
+ }));
269
+ // 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.
270
+ // Reset shouldVirtualFocusFirst so that we don't erronously autofocus an item when the collection is filtered again.
271
+ if (manager.collection.size > 0) shouldVirtualFocusFirst.current = false;
272
+ } else {
273
+ manager.setFocusedKey(keyToFocus);
274
+ // Only set shouldVirtualFocusFirst to false if we've successfully set the first key as the focused key
275
+ // If there wasn't a key to focus, we might be in a temporary loading state so we'll want to still focus the first key
276
+ // after the collection updates after load
277
+ shouldVirtualFocusFirst.current = false;
278
+ }
279
+ });
280
+ (0, $3H3GQ$useUpdateLayoutEffect)(()=>{
281
+ if (shouldVirtualFocusFirst.current) updateActiveDescendant();
282
+ }, [
283
+ manager.collection,
284
+ updateActiveDescendant
285
+ ]);
286
+ let resetFocusFirstFlag = (0, $3H3GQ$useEffectEvent)(()=>{
287
+ // If user causes the focused key to change in any other way, clear shouldVirtualFocusFirst so we don't
288
+ // accidentally move focus from under them. Skip this if the collection was empty because we might be in a load
289
+ // state and will still want to focus the first item after load
290
+ if (manager.collection.size > 0) shouldVirtualFocusFirst.current = false;
291
+ });
292
+ (0, $3H3GQ$useUpdateLayoutEffect)(()=>{
293
+ resetFocusFirstFlag();
294
+ }, [
295
+ manager.focusedKey,
296
+ resetFocusFirstFlag
297
+ ]);
298
+ (0, $3H3GQ$useEvent)(ref, (0, $3H3GQ$CLEAR_FOCUS_EVENT), !shouldUseVirtualFocus ? undefined : (e)=>{
299
+ e.stopPropagation();
300
+ manager.setFocused(false);
301
+ manager.setFocusedKey(null);
302
+ });
233
303
  const autoFocusRef = (0, $3H3GQ$useRef)(autoFocus);
234
304
  (0, $3H3GQ$useEffect)(()=>{
235
305
  if (autoFocusRef.current) {
306
+ var _delegate_getFirstKey, _delegate_getLastKey;
236
307
  let focusedKey = null;
308
+ var _delegate_getFirstKey1;
237
309
  // Check focus strategy to determine which item to focus
238
- if (autoFocus === 'first') focusedKey = delegate.getFirstKey();
239
- if (autoFocus === 'last') focusedKey = delegate.getLastKey();
310
+ if (autoFocus === 'first') focusedKey = (_delegate_getFirstKey1 = (_delegate_getFirstKey = delegate.getFirstKey) === null || _delegate_getFirstKey === void 0 ? void 0 : _delegate_getFirstKey.call(delegate)) !== null && _delegate_getFirstKey1 !== void 0 ? _delegate_getFirstKey1 : null;
311
+ var _delegate_getLastKey1;
312
+ if (autoFocus === 'last') focusedKey = (_delegate_getLastKey1 = (_delegate_getLastKey = delegate.getLastKey) === null || _delegate_getLastKey === void 0 ? void 0 : _delegate_getLastKey.call(delegate)) !== null && _delegate_getLastKey1 !== void 0 ? _delegate_getLastKey1 : null;
240
313
  // If there are any selected keys, make the first one the new focus target
241
314
  let selectedKeys = manager.selectedKeys;
242
315
  if (selectedKeys.size) {
@@ -248,14 +321,14 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
248
321
  manager.setFocused(true);
249
322
  manager.setFocusedKey(focusedKey);
250
323
  // If no default focus key is selected, focus the collection itself.
251
- if (focusedKey == null && !shouldUseVirtualFocus) (0, $3H3GQ$focusSafely)(ref.current);
324
+ if (focusedKey == null && !shouldUseVirtualFocus && ref.current) (0, $3H3GQ$focusSafely)(ref.current);
252
325
  }
253
326
  // eslint-disable-next-line react-hooks/exhaustive-deps
254
327
  }, []);
255
328
  // Scroll the focused element into view when the focusedKey changes.
256
329
  let lastFocusedKey = (0, $3H3GQ$useRef)(manager.focusedKey);
257
330
  (0, $3H3GQ$useEffect)(()=>{
258
- if (manager.isFocused && manager.focusedKey != null && (manager.focusedKey !== lastFocusedKey.current || autoFocusRef.current) && (scrollRef === null || scrollRef === void 0 ? void 0 : scrollRef.current)) {
331
+ if (manager.isFocused && manager.focusedKey != null && (manager.focusedKey !== lastFocusedKey.current || autoFocusRef.current) && scrollRef.current && ref.current) {
259
332
  let modality = (0, $3H3GQ$getInteractionModality)();
260
333
  let element = ref.current.querySelector(`[data-key="${CSS.escape(manager.focusedKey.toString())}"]`);
261
334
  if (!element) // If item element wasn't found, return early (don't update autoFocusRef and lastFocusedKey).
@@ -270,7 +343,7 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
270
343
  }
271
344
  }
272
345
  // If the focused key becomes null (e.g. the last item is deleted), focus the whole collection.
273
- if (!shouldUseVirtualFocus && manager.isFocused && manager.focusedKey == null && lastFocusedKey.current != null) (0, $3H3GQ$focusSafely)(ref.current);
346
+ if (!shouldUseVirtualFocus && manager.isFocused && manager.focusedKey == null && lastFocusedKey.current != null && ref.current) (0, $3H3GQ$focusSafely)(ref.current);
274
347
  lastFocusedKey.current = manager.focusedKey;
275
348
  autoFocusRef.current = false;
276
349
  });
@@ -296,10 +369,9 @@ function $ae20dd8cbca75726$export$d6daf82dcd84e87c(options) {
296
369
  if (!disallowTypeAhead) handlers = (0, $3H3GQ$mergeProps)(typeSelectProps, handlers);
297
370
  // If nothing is focused within the collection, make the collection itself tabbable.
298
371
  // This will be marshalled to either the first or last item depending on where focus came from.
299
- // If using virtual focus, don't set a tabIndex at all so that VoiceOver on iOS 14 doesn't try
300
- // to move real DOM focus to the element anyway.
301
- let tabIndex;
372
+ let tabIndex = undefined;
302
373
  if (!shouldUseVirtualFocus) tabIndex = manager.focusedKey == null ? 0 : -1;
374
+ else tabIndex = -1;
303
375
  return {
304
376
  collectionProps: {
305
377
  ...handlers,