@react-aria/focus 3.17.0 → 3.18.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.
- package/dist/FocusRing.main.js +2 -2
- package/dist/FocusRing.main.js.map +1 -1
- package/dist/FocusRing.mjs +3 -3
- package/dist/FocusRing.module.js +2 -2
- package/dist/FocusRing.module.js.map +1 -1
- package/dist/FocusScope.main.js +62 -42
- package/dist/FocusScope.main.js.map +1 -1
- package/dist/FocusScope.mjs +63 -43
- package/dist/FocusScope.module.js +62 -42
- package/dist/FocusScope.module.js.map +1 -1
- package/dist/focusSafely.main.js +1 -1
- package/dist/focusSafely.mjs +2 -2
- package/dist/focusSafely.module.js +1 -1
- package/dist/isElementVisible.main.js +5 -5
- package/dist/isElementVisible.mjs +6 -6
- package/dist/isElementVisible.module.js +5 -5
- package/dist/types.d.ts +6 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/useFocusRing.mjs +1 -1
- package/dist/useFocusable.main.js.map +1 -1
- package/dist/useFocusable.mjs +1 -1
- package/dist/useFocusable.module.js.map +1 -1
- package/dist/useHasTabbableChild.main.js +3 -3
- package/dist/useHasTabbableChild.main.js.map +1 -1
- package/dist/useHasTabbableChild.mjs +4 -4
- package/dist/useHasTabbableChild.module.js +3 -3
- package/dist/useHasTabbableChild.module.js.map +1 -1
- package/package.json +6 -6
- package/src/FocusRing.tsx +1 -1
- package/src/FocusScope.tsx +40 -17
- package/src/useFocusable.tsx +4 -4
- package/src/useHasTabbableChild.ts +3 -2
package/dist/FocusScope.mjs
CHANGED
|
@@ -18,6 +18,7 @@ import $cgawC$react, {useRef as $cgawC$useRef, useContext as $cgawC$useContext,
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
const $9bf71ea28793e738$var$FocusContext = /*#__PURE__*/ (0, $cgawC$react).createContext(null);
|
|
21
|
+
const $9bf71ea28793e738$var$RESTORE_FOCUS_EVENT = 'react-aria-focus-scope-restore';
|
|
21
22
|
let $9bf71ea28793e738$var$activeScope = null;
|
|
22
23
|
function $9bf71ea28793e738$export$20e40289641fbbb6(props) {
|
|
23
24
|
let { children: children, contain: contain, restoreFocus: restoreFocus, autoFocus: autoFocus } = props;
|
|
@@ -59,11 +60,17 @@ function $9bf71ea28793e738$export$20e40289641fbbb6(props) {
|
|
|
59
60
|
// Find all rendered nodes between the sentinels and add them to the scope.
|
|
60
61
|
let node = (_startRef_current = startRef.current) === null || _startRef_current === void 0 ? void 0 : _startRef_current.nextSibling;
|
|
61
62
|
let nodes = [];
|
|
63
|
+
let stopPropagation = (e)=>e.stopPropagation();
|
|
62
64
|
while(node && node !== endRef.current){
|
|
63
65
|
nodes.push(node);
|
|
66
|
+
// Stop custom restore focus event from propagating to parent focus scopes.
|
|
67
|
+
node.addEventListener($9bf71ea28793e738$var$RESTORE_FOCUS_EVENT, stopPropagation);
|
|
64
68
|
node = node.nextSibling;
|
|
65
69
|
}
|
|
66
70
|
scopeRef.current = nodes;
|
|
71
|
+
return ()=>{
|
|
72
|
+
for (let node of nodes)node.removeEventListener($9bf71ea28793e738$var$RESTORE_FOCUS_EVENT, stopPropagation);
|
|
73
|
+
};
|
|
67
74
|
}, [
|
|
68
75
|
children
|
|
69
76
|
]);
|
|
@@ -192,21 +199,21 @@ function $9bf71ea28793e738$var$createFocusManagerForScope(scopeRef) {
|
|
|
192
199
|
};
|
|
193
200
|
}
|
|
194
201
|
const $9bf71ea28793e738$var$focusableElements = [
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
202
|
+
'input:not([disabled]):not([type=hidden])',
|
|
203
|
+
'select:not([disabled])',
|
|
204
|
+
'textarea:not([disabled])',
|
|
205
|
+
'button:not([disabled])',
|
|
206
|
+
'a[href]',
|
|
207
|
+
'area[href]',
|
|
208
|
+
'summary',
|
|
209
|
+
'iframe',
|
|
210
|
+
'object',
|
|
211
|
+
'embed',
|
|
212
|
+
'audio[controls]',
|
|
213
|
+
'video[controls]',
|
|
214
|
+
'[contenteditable]'
|
|
208
215
|
];
|
|
209
|
-
const $9bf71ea28793e738$var$FOCUSABLE_ELEMENT_SELECTOR = $9bf71ea28793e738$var$focusableElements.join(
|
|
216
|
+
const $9bf71ea28793e738$var$FOCUSABLE_ELEMENT_SELECTOR = $9bf71ea28793e738$var$focusableElements.join(':not([hidden]),') + ',[tabindex]:not([disabled]):not([hidden])';
|
|
210
217
|
$9bf71ea28793e738$var$focusableElements.push('[tabindex]:not([tabindex="-1"]):not([disabled])');
|
|
211
218
|
const $9bf71ea28793e738$var$TABBABLE_ELEMENT_SELECTOR = $9bf71ea28793e738$var$focusableElements.join(':not([hidden]):not([tabindex="-1"]),');
|
|
212
219
|
function $9bf71ea28793e738$export$4c063cf1350e6fed(element) {
|
|
@@ -224,8 +231,8 @@ function $9bf71ea28793e738$var$shouldContainFocus(scopeRef) {
|
|
|
224
231
|
return true;
|
|
225
232
|
}
|
|
226
233
|
function $9bf71ea28793e738$var$useFocusContainment(scopeRef, contain) {
|
|
227
|
-
let focusedNode = (0, $cgawC$useRef)();
|
|
228
|
-
let raf = (0, $cgawC$useRef)();
|
|
234
|
+
let focusedNode = (0, $cgawC$useRef)(undefined);
|
|
235
|
+
let raf = (0, $cgawC$useRef)(undefined);
|
|
229
236
|
(0, $cgawC$useLayoutEffect)(()=>{
|
|
230
237
|
let scope = scopeRef.current;
|
|
231
238
|
if (!contain) {
|
|
@@ -239,7 +246,7 @@ function $9bf71ea28793e738$var$useFocusContainment(scopeRef, contain) {
|
|
|
239
246
|
const ownerDocument = (0, $cgawC$getOwnerDocument)(scope ? scope[0] : undefined);
|
|
240
247
|
// Handle the Tab key to contain focus within the scope
|
|
241
248
|
let onKeyDown = (e)=>{
|
|
242
|
-
if (e.key !==
|
|
249
|
+
if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey || !$9bf71ea28793e738$var$shouldContainFocus(scopeRef) || e.isComposing) return;
|
|
243
250
|
let focusedElement = ownerDocument.activeElement;
|
|
244
251
|
let scope = scopeRef.current;
|
|
245
252
|
if (!scope || !$9bf71ea28793e738$var$isElementInScope(focusedElement, scope)) return;
|
|
@@ -285,15 +292,15 @@ function $9bf71ea28793e738$var$useFocusContainment(scopeRef, contain) {
|
|
|
285
292
|
}
|
|
286
293
|
});
|
|
287
294
|
};
|
|
288
|
-
ownerDocument.addEventListener(
|
|
289
|
-
ownerDocument.addEventListener(
|
|
290
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener(
|
|
291
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener(
|
|
295
|
+
ownerDocument.addEventListener('keydown', onKeyDown, false);
|
|
296
|
+
ownerDocument.addEventListener('focusin', onFocus, false);
|
|
297
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener('focusin', onFocus, false));
|
|
298
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener('focusout', onBlur, false));
|
|
292
299
|
return ()=>{
|
|
293
|
-
ownerDocument.removeEventListener(
|
|
294
|
-
ownerDocument.removeEventListener(
|
|
295
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener(
|
|
296
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener(
|
|
300
|
+
ownerDocument.removeEventListener('keydown', onKeyDown, false);
|
|
301
|
+
ownerDocument.removeEventListener('focusin', onFocus, false);
|
|
302
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener('focusin', onFocus, false));
|
|
303
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener('focusout', onBlur, false));
|
|
297
304
|
};
|
|
298
305
|
}, [
|
|
299
306
|
scopeRef,
|
|
@@ -319,7 +326,7 @@ function $9bf71ea28793e738$var$isElementInScope(element, scope) {
|
|
|
319
326
|
}
|
|
320
327
|
function $9bf71ea28793e738$var$isElementInChildScope(element, scope = null) {
|
|
321
328
|
// If the element is within a top layer element (e.g. toasts), always allow moving focus there.
|
|
322
|
-
if (element instanceof Element && element.closest(
|
|
329
|
+
if (element instanceof Element && element.closest('[data-react-aria-top-layer]')) return true;
|
|
323
330
|
// node.contains in isElementInScope covers child scopes that are also DOM children,
|
|
324
331
|
// but does not cover child scopes in portals.
|
|
325
332
|
for (let { scopeRef: s } of $9bf71ea28793e738$export$d06fae2ee68b101e.traverse($9bf71ea28793e738$export$d06fae2ee68b101e.getTreeNode(scope))){
|
|
@@ -351,7 +358,7 @@ function $9bf71ea28793e738$var$focusElement(element, scroll = false) {
|
|
|
351
358
|
// ignore
|
|
352
359
|
}
|
|
353
360
|
}
|
|
354
|
-
function $9bf71ea28793e738$var$
|
|
361
|
+
function $9bf71ea28793e738$var$getFirstInScope(scope, tabbable = true) {
|
|
355
362
|
let sentinel = scope[0].previousElementSibling;
|
|
356
363
|
let scopeRoot = $9bf71ea28793e738$var$getScopeRoot(scope);
|
|
357
364
|
let walker = $9bf71ea28793e738$export$2d6ec8fc375ceafa(scopeRoot, {
|
|
@@ -368,7 +375,10 @@ function $9bf71ea28793e738$var$focusFirstInScope(scope, tabbable = true) {
|
|
|
368
375
|
walker.currentNode = sentinel;
|
|
369
376
|
nextNode = walker.nextNode();
|
|
370
377
|
}
|
|
371
|
-
|
|
378
|
+
return nextNode;
|
|
379
|
+
}
|
|
380
|
+
function $9bf71ea28793e738$var$focusFirstInScope(scope, tabbable = true) {
|
|
381
|
+
$9bf71ea28793e738$var$focusElement($9bf71ea28793e738$var$getFirstInScope(scope, tabbable));
|
|
372
382
|
}
|
|
373
383
|
function $9bf71ea28793e738$var$useAutoFocus(scopeRef, autoFocus) {
|
|
374
384
|
const autoFocusRef = (0, $cgawC$react).useRef(autoFocus);
|
|
@@ -395,11 +405,11 @@ function $9bf71ea28793e738$var$useActiveScopeTracker(scopeRef, restore, contain)
|
|
|
395
405
|
if ($9bf71ea28793e738$var$isElementInScope(target, scopeRef.current)) $9bf71ea28793e738$var$activeScope = scopeRef;
|
|
396
406
|
else if (!$9bf71ea28793e738$var$isElementInAnyScope(target)) $9bf71ea28793e738$var$activeScope = null;
|
|
397
407
|
};
|
|
398
|
-
ownerDocument.addEventListener(
|
|
399
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener(
|
|
408
|
+
ownerDocument.addEventListener('focusin', onFocus, false);
|
|
409
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener('focusin', onFocus, false));
|
|
400
410
|
return ()=>{
|
|
401
|
-
ownerDocument.removeEventListener(
|
|
402
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener(
|
|
411
|
+
ownerDocument.removeEventListener('focusin', onFocus, false);
|
|
412
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener('focusin', onFocus, false));
|
|
403
413
|
};
|
|
404
414
|
}, [
|
|
405
415
|
scopeRef,
|
|
@@ -418,7 +428,7 @@ function $9bf71ea28793e738$var$shouldRestoreFocus(scopeRef) {
|
|
|
418
428
|
function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain) {
|
|
419
429
|
// create a ref during render instead of useLayoutEffect so the active element is saved before a child with autoFocus=true mounts.
|
|
420
430
|
// eslint-disable-next-line no-restricted-globals
|
|
421
|
-
const nodeToRestoreRef = (0, $cgawC$useRef)(typeof document !==
|
|
431
|
+
const nodeToRestoreRef = (0, $cgawC$useRef)(typeof document !== 'undefined' ? (0, $cgawC$getOwnerDocument)(scopeRef.current ? scopeRef.current[0] : undefined).activeElement : null);
|
|
422
432
|
// restoring scopes should all track if they are active regardless of contain, but contain already tracks it plus logic to contain the focus
|
|
423
433
|
// restoring-non-containing scopes should only care if they become active so they can perform the restore
|
|
424
434
|
(0, $cgawC$useLayoutEffect)(()=>{
|
|
@@ -430,11 +440,11 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
430
440
|
// Moving out of the active scope to an ancestor is not allowed.
|
|
431
441
|
if ((!$9bf71ea28793e738$var$activeScope || $9bf71ea28793e738$var$isAncestorScope($9bf71ea28793e738$var$activeScope, scopeRef)) && $9bf71ea28793e738$var$isElementInScope(ownerDocument.activeElement, scopeRef.current)) $9bf71ea28793e738$var$activeScope = scopeRef;
|
|
432
442
|
};
|
|
433
|
-
ownerDocument.addEventListener(
|
|
434
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener(
|
|
443
|
+
ownerDocument.addEventListener('focusin', onFocus, false);
|
|
444
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener('focusin', onFocus, false));
|
|
435
445
|
return ()=>{
|
|
436
|
-
ownerDocument.removeEventListener(
|
|
437
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener(
|
|
446
|
+
ownerDocument.removeEventListener('focusin', onFocus, false);
|
|
447
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener('focusin', onFocus, false));
|
|
438
448
|
};
|
|
439
449
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
440
450
|
}, [
|
|
@@ -449,7 +459,7 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
449
459
|
// using portals for overlays, so that focus goes to the expected element when
|
|
450
460
|
// tabbing out of the overlay.
|
|
451
461
|
let onKeyDown = (e)=>{
|
|
452
|
-
if (e.key !==
|
|
462
|
+
if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey || !$9bf71ea28793e738$var$shouldContainFocus(scopeRef) || e.isComposing) return;
|
|
453
463
|
let focusedElement = ownerDocument.activeElement;
|
|
454
464
|
if (!$9bf71ea28793e738$var$isElementInScope(focusedElement, scopeRef.current)) return;
|
|
455
465
|
let treeNode = $9bf71ea28793e738$export$d06fae2ee68b101e.getTreeNode(scopeRef);
|
|
@@ -483,9 +493,9 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
483
493
|
else $9bf71ea28793e738$var$focusElement(nodeToRestore, true);
|
|
484
494
|
}
|
|
485
495
|
};
|
|
486
|
-
if (!contain) ownerDocument.addEventListener(
|
|
496
|
+
if (!contain) ownerDocument.addEventListener('keydown', onKeyDown, true);
|
|
487
497
|
return ()=>{
|
|
488
|
-
if (!contain) ownerDocument.removeEventListener(
|
|
498
|
+
if (!contain) ownerDocument.removeEventListener('keydown', onKeyDown, true);
|
|
489
499
|
};
|
|
490
500
|
}, [
|
|
491
501
|
scopeRef,
|
|
@@ -516,7 +526,7 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
516
526
|
let treeNode = clonedTree.getTreeNode(scopeRef);
|
|
517
527
|
while(treeNode){
|
|
518
528
|
if (treeNode.nodeToRestore && treeNode.nodeToRestore.isConnected) {
|
|
519
|
-
$9bf71ea28793e738$var$
|
|
529
|
+
$9bf71ea28793e738$var$restoreFocusToElement(treeNode.nodeToRestore);
|
|
520
530
|
return;
|
|
521
531
|
}
|
|
522
532
|
treeNode = treeNode.parent;
|
|
@@ -526,7 +536,8 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
526
536
|
treeNode = clonedTree.getTreeNode(scopeRef);
|
|
527
537
|
while(treeNode){
|
|
528
538
|
if (treeNode.scopeRef && treeNode.scopeRef.current && $9bf71ea28793e738$export$d06fae2ee68b101e.getTreeNode(treeNode.scopeRef)) {
|
|
529
|
-
$9bf71ea28793e738$var$
|
|
539
|
+
let node = $9bf71ea28793e738$var$getFirstInScope(treeNode.scopeRef.current, true);
|
|
540
|
+
$9bf71ea28793e738$var$restoreFocusToElement(node);
|
|
530
541
|
return;
|
|
531
542
|
}
|
|
532
543
|
treeNode = treeNode.parent;
|
|
@@ -540,6 +551,15 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
540
551
|
restoreFocus
|
|
541
552
|
]);
|
|
542
553
|
}
|
|
554
|
+
function $9bf71ea28793e738$var$restoreFocusToElement(node) {
|
|
555
|
+
// Dispatch a custom event that parent elements can intercept to customize focus restoration.
|
|
556
|
+
// For example, virtualized collection components reuse DOM elements, so the original element
|
|
557
|
+
// might still exist in the DOM but representing a different item.
|
|
558
|
+
if (node.dispatchEvent(new CustomEvent($9bf71ea28793e738$var$RESTORE_FOCUS_EVENT, {
|
|
559
|
+
bubbles: true,
|
|
560
|
+
cancelable: true
|
|
561
|
+
}))) $9bf71ea28793e738$var$focusElement(node);
|
|
562
|
+
}
|
|
543
563
|
function $9bf71ea28793e738$export$2d6ec8fc375ceafa(root, opts, scope) {
|
|
544
564
|
let selector = (opts === null || opts === void 0 ? void 0 : opts.tabbable) ? $9bf71ea28793e738$var$TABBABLE_ELEMENT_SELECTOR : $9bf71ea28793e738$var$FOCUSABLE_ELEMENT_SELECTOR;
|
|
545
565
|
let walker = (0, $cgawC$getOwnerDocument)(root).createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
|
|
@@ -711,4 +731,4 @@ let $9bf71ea28793e738$export$d06fae2ee68b101e = new $9bf71ea28793e738$var$Tree()
|
|
|
711
731
|
|
|
712
732
|
|
|
713
733
|
export {$9bf71ea28793e738$export$20e40289641fbbb6 as FocusScope, $9bf71ea28793e738$export$d06fae2ee68b101e as focusScopeTree, $9bf71ea28793e738$export$10c5169755ce7bd7 as useFocusManager, $9bf71ea28793e738$export$2d6ec8fc375ceafa as getFocusableTreeWalker, $9bf71ea28793e738$export$4c063cf1350e6fed as isFocusable, $9bf71ea28793e738$export$1258395f99bf9cbf as isElementInChildOfActiveScope, $9bf71ea28793e738$export$c5251b9e124bf29 as createFocusManager};
|
|
714
|
-
//# sourceMappingURL=FocusScope.
|
|
734
|
+
//# sourceMappingURL=FocusScope.module.js.map
|
|
@@ -18,6 +18,7 @@ import $cgawC$react, {useRef as $cgawC$useRef, useContext as $cgawC$useContext,
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
const $9bf71ea28793e738$var$FocusContext = /*#__PURE__*/ (0, $cgawC$react).createContext(null);
|
|
21
|
+
const $9bf71ea28793e738$var$RESTORE_FOCUS_EVENT = 'react-aria-focus-scope-restore';
|
|
21
22
|
let $9bf71ea28793e738$var$activeScope = null;
|
|
22
23
|
function $9bf71ea28793e738$export$20e40289641fbbb6(props) {
|
|
23
24
|
let { children: children, contain: contain, restoreFocus: restoreFocus, autoFocus: autoFocus } = props;
|
|
@@ -59,11 +60,17 @@ function $9bf71ea28793e738$export$20e40289641fbbb6(props) {
|
|
|
59
60
|
// Find all rendered nodes between the sentinels and add them to the scope.
|
|
60
61
|
let node = (_startRef_current = startRef.current) === null || _startRef_current === void 0 ? void 0 : _startRef_current.nextSibling;
|
|
61
62
|
let nodes = [];
|
|
63
|
+
let stopPropagation = (e)=>e.stopPropagation();
|
|
62
64
|
while(node && node !== endRef.current){
|
|
63
65
|
nodes.push(node);
|
|
66
|
+
// Stop custom restore focus event from propagating to parent focus scopes.
|
|
67
|
+
node.addEventListener($9bf71ea28793e738$var$RESTORE_FOCUS_EVENT, stopPropagation);
|
|
64
68
|
node = node.nextSibling;
|
|
65
69
|
}
|
|
66
70
|
scopeRef.current = nodes;
|
|
71
|
+
return ()=>{
|
|
72
|
+
for (let node of nodes)node.removeEventListener($9bf71ea28793e738$var$RESTORE_FOCUS_EVENT, stopPropagation);
|
|
73
|
+
};
|
|
67
74
|
}, [
|
|
68
75
|
children
|
|
69
76
|
]);
|
|
@@ -192,21 +199,21 @@ function $9bf71ea28793e738$var$createFocusManagerForScope(scopeRef) {
|
|
|
192
199
|
};
|
|
193
200
|
}
|
|
194
201
|
const $9bf71ea28793e738$var$focusableElements = [
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
202
|
+
'input:not([disabled]):not([type=hidden])',
|
|
203
|
+
'select:not([disabled])',
|
|
204
|
+
'textarea:not([disabled])',
|
|
205
|
+
'button:not([disabled])',
|
|
206
|
+
'a[href]',
|
|
207
|
+
'area[href]',
|
|
208
|
+
'summary',
|
|
209
|
+
'iframe',
|
|
210
|
+
'object',
|
|
211
|
+
'embed',
|
|
212
|
+
'audio[controls]',
|
|
213
|
+
'video[controls]',
|
|
214
|
+
'[contenteditable]'
|
|
208
215
|
];
|
|
209
|
-
const $9bf71ea28793e738$var$FOCUSABLE_ELEMENT_SELECTOR = $9bf71ea28793e738$var$focusableElements.join(
|
|
216
|
+
const $9bf71ea28793e738$var$FOCUSABLE_ELEMENT_SELECTOR = $9bf71ea28793e738$var$focusableElements.join(':not([hidden]),') + ',[tabindex]:not([disabled]):not([hidden])';
|
|
210
217
|
$9bf71ea28793e738$var$focusableElements.push('[tabindex]:not([tabindex="-1"]):not([disabled])');
|
|
211
218
|
const $9bf71ea28793e738$var$TABBABLE_ELEMENT_SELECTOR = $9bf71ea28793e738$var$focusableElements.join(':not([hidden]):not([tabindex="-1"]),');
|
|
212
219
|
function $9bf71ea28793e738$export$4c063cf1350e6fed(element) {
|
|
@@ -224,8 +231,8 @@ function $9bf71ea28793e738$var$shouldContainFocus(scopeRef) {
|
|
|
224
231
|
return true;
|
|
225
232
|
}
|
|
226
233
|
function $9bf71ea28793e738$var$useFocusContainment(scopeRef, contain) {
|
|
227
|
-
let focusedNode = (0, $cgawC$useRef)();
|
|
228
|
-
let raf = (0, $cgawC$useRef)();
|
|
234
|
+
let focusedNode = (0, $cgawC$useRef)(undefined);
|
|
235
|
+
let raf = (0, $cgawC$useRef)(undefined);
|
|
229
236
|
(0, $cgawC$useLayoutEffect)(()=>{
|
|
230
237
|
let scope = scopeRef.current;
|
|
231
238
|
if (!contain) {
|
|
@@ -239,7 +246,7 @@ function $9bf71ea28793e738$var$useFocusContainment(scopeRef, contain) {
|
|
|
239
246
|
const ownerDocument = (0, $cgawC$getOwnerDocument)(scope ? scope[0] : undefined);
|
|
240
247
|
// Handle the Tab key to contain focus within the scope
|
|
241
248
|
let onKeyDown = (e)=>{
|
|
242
|
-
if (e.key !==
|
|
249
|
+
if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey || !$9bf71ea28793e738$var$shouldContainFocus(scopeRef) || e.isComposing) return;
|
|
243
250
|
let focusedElement = ownerDocument.activeElement;
|
|
244
251
|
let scope = scopeRef.current;
|
|
245
252
|
if (!scope || !$9bf71ea28793e738$var$isElementInScope(focusedElement, scope)) return;
|
|
@@ -285,15 +292,15 @@ function $9bf71ea28793e738$var$useFocusContainment(scopeRef, contain) {
|
|
|
285
292
|
}
|
|
286
293
|
});
|
|
287
294
|
};
|
|
288
|
-
ownerDocument.addEventListener(
|
|
289
|
-
ownerDocument.addEventListener(
|
|
290
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener(
|
|
291
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener(
|
|
295
|
+
ownerDocument.addEventListener('keydown', onKeyDown, false);
|
|
296
|
+
ownerDocument.addEventListener('focusin', onFocus, false);
|
|
297
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener('focusin', onFocus, false));
|
|
298
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener('focusout', onBlur, false));
|
|
292
299
|
return ()=>{
|
|
293
|
-
ownerDocument.removeEventListener(
|
|
294
|
-
ownerDocument.removeEventListener(
|
|
295
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener(
|
|
296
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener(
|
|
300
|
+
ownerDocument.removeEventListener('keydown', onKeyDown, false);
|
|
301
|
+
ownerDocument.removeEventListener('focusin', onFocus, false);
|
|
302
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener('focusin', onFocus, false));
|
|
303
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener('focusout', onBlur, false));
|
|
297
304
|
};
|
|
298
305
|
}, [
|
|
299
306
|
scopeRef,
|
|
@@ -319,7 +326,7 @@ function $9bf71ea28793e738$var$isElementInScope(element, scope) {
|
|
|
319
326
|
}
|
|
320
327
|
function $9bf71ea28793e738$var$isElementInChildScope(element, scope = null) {
|
|
321
328
|
// If the element is within a top layer element (e.g. toasts), always allow moving focus there.
|
|
322
|
-
if (element instanceof Element && element.closest(
|
|
329
|
+
if (element instanceof Element && element.closest('[data-react-aria-top-layer]')) return true;
|
|
323
330
|
// node.contains in isElementInScope covers child scopes that are also DOM children,
|
|
324
331
|
// but does not cover child scopes in portals.
|
|
325
332
|
for (let { scopeRef: s } of $9bf71ea28793e738$export$d06fae2ee68b101e.traverse($9bf71ea28793e738$export$d06fae2ee68b101e.getTreeNode(scope))){
|
|
@@ -351,7 +358,7 @@ function $9bf71ea28793e738$var$focusElement(element, scroll = false) {
|
|
|
351
358
|
// ignore
|
|
352
359
|
}
|
|
353
360
|
}
|
|
354
|
-
function $9bf71ea28793e738$var$
|
|
361
|
+
function $9bf71ea28793e738$var$getFirstInScope(scope, tabbable = true) {
|
|
355
362
|
let sentinel = scope[0].previousElementSibling;
|
|
356
363
|
let scopeRoot = $9bf71ea28793e738$var$getScopeRoot(scope);
|
|
357
364
|
let walker = $9bf71ea28793e738$export$2d6ec8fc375ceafa(scopeRoot, {
|
|
@@ -368,7 +375,10 @@ function $9bf71ea28793e738$var$focusFirstInScope(scope, tabbable = true) {
|
|
|
368
375
|
walker.currentNode = sentinel;
|
|
369
376
|
nextNode = walker.nextNode();
|
|
370
377
|
}
|
|
371
|
-
|
|
378
|
+
return nextNode;
|
|
379
|
+
}
|
|
380
|
+
function $9bf71ea28793e738$var$focusFirstInScope(scope, tabbable = true) {
|
|
381
|
+
$9bf71ea28793e738$var$focusElement($9bf71ea28793e738$var$getFirstInScope(scope, tabbable));
|
|
372
382
|
}
|
|
373
383
|
function $9bf71ea28793e738$var$useAutoFocus(scopeRef, autoFocus) {
|
|
374
384
|
const autoFocusRef = (0, $cgawC$react).useRef(autoFocus);
|
|
@@ -395,11 +405,11 @@ function $9bf71ea28793e738$var$useActiveScopeTracker(scopeRef, restore, contain)
|
|
|
395
405
|
if ($9bf71ea28793e738$var$isElementInScope(target, scopeRef.current)) $9bf71ea28793e738$var$activeScope = scopeRef;
|
|
396
406
|
else if (!$9bf71ea28793e738$var$isElementInAnyScope(target)) $9bf71ea28793e738$var$activeScope = null;
|
|
397
407
|
};
|
|
398
|
-
ownerDocument.addEventListener(
|
|
399
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener(
|
|
408
|
+
ownerDocument.addEventListener('focusin', onFocus, false);
|
|
409
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener('focusin', onFocus, false));
|
|
400
410
|
return ()=>{
|
|
401
|
-
ownerDocument.removeEventListener(
|
|
402
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener(
|
|
411
|
+
ownerDocument.removeEventListener('focusin', onFocus, false);
|
|
412
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener('focusin', onFocus, false));
|
|
403
413
|
};
|
|
404
414
|
}, [
|
|
405
415
|
scopeRef,
|
|
@@ -418,7 +428,7 @@ function $9bf71ea28793e738$var$shouldRestoreFocus(scopeRef) {
|
|
|
418
428
|
function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain) {
|
|
419
429
|
// create a ref during render instead of useLayoutEffect so the active element is saved before a child with autoFocus=true mounts.
|
|
420
430
|
// eslint-disable-next-line no-restricted-globals
|
|
421
|
-
const nodeToRestoreRef = (0, $cgawC$useRef)(typeof document !==
|
|
431
|
+
const nodeToRestoreRef = (0, $cgawC$useRef)(typeof document !== 'undefined' ? (0, $cgawC$getOwnerDocument)(scopeRef.current ? scopeRef.current[0] : undefined).activeElement : null);
|
|
422
432
|
// restoring scopes should all track if they are active regardless of contain, but contain already tracks it plus logic to contain the focus
|
|
423
433
|
// restoring-non-containing scopes should only care if they become active so they can perform the restore
|
|
424
434
|
(0, $cgawC$useLayoutEffect)(()=>{
|
|
@@ -430,11 +440,11 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
430
440
|
// Moving out of the active scope to an ancestor is not allowed.
|
|
431
441
|
if ((!$9bf71ea28793e738$var$activeScope || $9bf71ea28793e738$var$isAncestorScope($9bf71ea28793e738$var$activeScope, scopeRef)) && $9bf71ea28793e738$var$isElementInScope(ownerDocument.activeElement, scopeRef.current)) $9bf71ea28793e738$var$activeScope = scopeRef;
|
|
432
442
|
};
|
|
433
|
-
ownerDocument.addEventListener(
|
|
434
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener(
|
|
443
|
+
ownerDocument.addEventListener('focusin', onFocus, false);
|
|
444
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener('focusin', onFocus, false));
|
|
435
445
|
return ()=>{
|
|
436
|
-
ownerDocument.removeEventListener(
|
|
437
|
-
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener(
|
|
446
|
+
ownerDocument.removeEventListener('focusin', onFocus, false);
|
|
447
|
+
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.removeEventListener('focusin', onFocus, false));
|
|
438
448
|
};
|
|
439
449
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
440
450
|
}, [
|
|
@@ -449,7 +459,7 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
449
459
|
// using portals for overlays, so that focus goes to the expected element when
|
|
450
460
|
// tabbing out of the overlay.
|
|
451
461
|
let onKeyDown = (e)=>{
|
|
452
|
-
if (e.key !==
|
|
462
|
+
if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey || !$9bf71ea28793e738$var$shouldContainFocus(scopeRef) || e.isComposing) return;
|
|
453
463
|
let focusedElement = ownerDocument.activeElement;
|
|
454
464
|
if (!$9bf71ea28793e738$var$isElementInScope(focusedElement, scopeRef.current)) return;
|
|
455
465
|
let treeNode = $9bf71ea28793e738$export$d06fae2ee68b101e.getTreeNode(scopeRef);
|
|
@@ -483,9 +493,9 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
483
493
|
else $9bf71ea28793e738$var$focusElement(nodeToRestore, true);
|
|
484
494
|
}
|
|
485
495
|
};
|
|
486
|
-
if (!contain) ownerDocument.addEventListener(
|
|
496
|
+
if (!contain) ownerDocument.addEventListener('keydown', onKeyDown, true);
|
|
487
497
|
return ()=>{
|
|
488
|
-
if (!contain) ownerDocument.removeEventListener(
|
|
498
|
+
if (!contain) ownerDocument.removeEventListener('keydown', onKeyDown, true);
|
|
489
499
|
};
|
|
490
500
|
}, [
|
|
491
501
|
scopeRef,
|
|
@@ -516,7 +526,7 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
516
526
|
let treeNode = clonedTree.getTreeNode(scopeRef);
|
|
517
527
|
while(treeNode){
|
|
518
528
|
if (treeNode.nodeToRestore && treeNode.nodeToRestore.isConnected) {
|
|
519
|
-
$9bf71ea28793e738$var$
|
|
529
|
+
$9bf71ea28793e738$var$restoreFocusToElement(treeNode.nodeToRestore);
|
|
520
530
|
return;
|
|
521
531
|
}
|
|
522
532
|
treeNode = treeNode.parent;
|
|
@@ -526,7 +536,8 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
526
536
|
treeNode = clonedTree.getTreeNode(scopeRef);
|
|
527
537
|
while(treeNode){
|
|
528
538
|
if (treeNode.scopeRef && treeNode.scopeRef.current && $9bf71ea28793e738$export$d06fae2ee68b101e.getTreeNode(treeNode.scopeRef)) {
|
|
529
|
-
$9bf71ea28793e738$var$
|
|
539
|
+
let node = $9bf71ea28793e738$var$getFirstInScope(treeNode.scopeRef.current, true);
|
|
540
|
+
$9bf71ea28793e738$var$restoreFocusToElement(node);
|
|
530
541
|
return;
|
|
531
542
|
}
|
|
532
543
|
treeNode = treeNode.parent;
|
|
@@ -540,6 +551,15 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
540
551
|
restoreFocus
|
|
541
552
|
]);
|
|
542
553
|
}
|
|
554
|
+
function $9bf71ea28793e738$var$restoreFocusToElement(node) {
|
|
555
|
+
// Dispatch a custom event that parent elements can intercept to customize focus restoration.
|
|
556
|
+
// For example, virtualized collection components reuse DOM elements, so the original element
|
|
557
|
+
// might still exist in the DOM but representing a different item.
|
|
558
|
+
if (node.dispatchEvent(new CustomEvent($9bf71ea28793e738$var$RESTORE_FOCUS_EVENT, {
|
|
559
|
+
bubbles: true,
|
|
560
|
+
cancelable: true
|
|
561
|
+
}))) $9bf71ea28793e738$var$focusElement(node);
|
|
562
|
+
}
|
|
543
563
|
function $9bf71ea28793e738$export$2d6ec8fc375ceafa(root, opts, scope) {
|
|
544
564
|
let selector = (opts === null || opts === void 0 ? void 0 : opts.tabbable) ? $9bf71ea28793e738$var$TABBABLE_ELEMENT_SELECTOR : $9bf71ea28793e738$var$FOCUSABLE_ELEMENT_SELECTOR;
|
|
545
565
|
let walker = (0, $cgawC$getOwnerDocument)(root).createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
|