@react-aria/focus 3.19.0 → 3.20.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/FocusScope.main.js +39 -46
- package/dist/FocusScope.main.js.map +1 -1
- package/dist/FocusScope.mjs +41 -47
- package/dist/FocusScope.module.js +41 -47
- package/dist/FocusScope.module.js.map +1 -1
- package/dist/import.mjs +6 -4
- package/dist/main.js +13 -6
- package/dist/main.js.map +1 -1
- package/dist/module.js +6 -4
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +10 -25
- package/dist/types.d.ts.map +1 -1
- package/dist/virtualFocus.main.js +46 -0
- package/dist/virtualFocus.main.js.map +1 -0
- package/dist/virtualFocus.mjs +38 -0
- package/dist/virtualFocus.module.js +38 -0
- package/dist/virtualFocus.module.js.map +1 -0
- package/package.json +7 -6
- package/src/FocusScope.tsx +66 -62
- package/src/index.ts +6 -4
- package/src/virtualFocus.ts +33 -0
- package/dist/focusSafely.main.js +0 -39
- package/dist/focusSafely.main.js.map +0 -1
- package/dist/focusSafely.mjs +0 -34
- package/dist/focusSafely.module.js +0 -34
- package/dist/focusSafely.module.js.map +0 -1
- package/dist/useFocusable.main.js +0 -75
- package/dist/useFocusable.main.js.map +0 -1
- package/dist/useFocusable.mjs +0 -65
- package/dist/useFocusable.module.js +0 -65
- package/dist/useFocusable.module.js.map +0 -1
- package/src/focusSafely.ts +0 -39
- package/src/useFocusable.tsx +0 -97
package/dist/FocusScope.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {focusSafely as $6a99195332edec8b$export$80f3e147d781571c} from "./focusSafely.mjs";
|
|
2
1
|
import {isElementVisible as $645f2e67b85a24c9$export$e989c0fffaa6b27a} from "./isElementVisible.mjs";
|
|
3
|
-
import {useLayoutEffect as $cgawC$useLayoutEffect, getOwnerDocument as $cgawC$getOwnerDocument} from "@react-aria/utils";
|
|
2
|
+
import {useLayoutEffect as $cgawC$useLayoutEffect, getActiveElement as $cgawC$getActiveElement, getOwnerDocument as $cgawC$getOwnerDocument, getEventTarget as $cgawC$getEventTarget, isAndroid as $cgawC$isAndroid, isChrome as $cgawC$isChrome, isTabbable as $cgawC$isTabbable, isFocusable as $cgawC$isFocusable, createShadowTreeWalker as $cgawC$createShadowTreeWalker} from "@react-aria/utils";
|
|
3
|
+
import {getInteractionModality as $cgawC$getInteractionModality, focusSafely as $cgawC$focusSafely} from "@react-aria/interactions";
|
|
4
4
|
import $cgawC$react, {useRef as $cgawC$useRef, useContext as $cgawC$useContext, useMemo as $cgawC$useMemo, useEffect as $cgawC$useEffect} from "react";
|
|
5
5
|
|
|
6
6
|
/*
|
|
@@ -81,7 +81,7 @@ function $9bf71ea28793e738$export$20e40289641fbbb6(props) {
|
|
|
81
81
|
// This needs to be an effect so that activeScope is updated after the FocusScope tree is complete.
|
|
82
82
|
// It cannot be a useLayoutEffect because the parent of this node hasn't been attached in the tree yet.
|
|
83
83
|
(0, $cgawC$useEffect)(()=>{
|
|
84
|
-
const activeElement = (0, $cgawC$getOwnerDocument)(scopeRef.current ? scopeRef.current[0] : undefined)
|
|
84
|
+
const activeElement = (0, $cgawC$getActiveElement)((0, $cgawC$getOwnerDocument)(scopeRef.current ? scopeRef.current[0] : undefined));
|
|
85
85
|
let scope = null;
|
|
86
86
|
if ($9bf71ea28793e738$var$isElementInScope(activeElement, scopeRef.current)) {
|
|
87
87
|
// We need to traverse the focusScope tree and find the bottom most scope that
|
|
@@ -135,7 +135,8 @@ function $9bf71ea28793e738$var$createFocusManagerForScope(scopeRef) {
|
|
|
135
135
|
focusNext (opts = {}) {
|
|
136
136
|
let scope = scopeRef.current;
|
|
137
137
|
let { from: from, tabbable: tabbable, wrap: wrap, accept: accept } = opts;
|
|
138
|
-
|
|
138
|
+
var _scope_;
|
|
139
|
+
let node = from || (0, $cgawC$getActiveElement)((0, $cgawC$getOwnerDocument)((_scope_ = scope[0]) !== null && _scope_ !== void 0 ? _scope_ : undefined));
|
|
139
140
|
let sentinel = scope[0].previousElementSibling;
|
|
140
141
|
let scopeRoot = $9bf71ea28793e738$var$getScopeRoot(scope);
|
|
141
142
|
let walker = $9bf71ea28793e738$export$2d6ec8fc375ceafa(scopeRoot, {
|
|
@@ -154,7 +155,8 @@ function $9bf71ea28793e738$var$createFocusManagerForScope(scopeRef) {
|
|
|
154
155
|
focusPrevious (opts = {}) {
|
|
155
156
|
let scope = scopeRef.current;
|
|
156
157
|
let { from: from, tabbable: tabbable, wrap: wrap, accept: accept } = opts;
|
|
157
|
-
|
|
158
|
+
var _scope_;
|
|
159
|
+
let node = from || (0, $cgawC$getActiveElement)((0, $cgawC$getOwnerDocument)((_scope_ = scope[0]) !== null && _scope_ !== void 0 ? _scope_ : undefined));
|
|
158
160
|
let sentinel = scope[scope.length - 1].nextElementSibling;
|
|
159
161
|
let scopeRoot = $9bf71ea28793e738$var$getScopeRoot(scope);
|
|
160
162
|
let walker = $9bf71ea28793e738$export$2d6ec8fc375ceafa(scopeRoot, {
|
|
@@ -198,27 +200,6 @@ function $9bf71ea28793e738$var$createFocusManagerForScope(scopeRef) {
|
|
|
198
200
|
}
|
|
199
201
|
};
|
|
200
202
|
}
|
|
201
|
-
const $9bf71ea28793e738$var$focusableElements = [
|
|
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]'
|
|
215
|
-
];
|
|
216
|
-
const $9bf71ea28793e738$var$FOCUSABLE_ELEMENT_SELECTOR = $9bf71ea28793e738$var$focusableElements.join(':not([hidden]),') + ',[tabindex]:not([disabled]):not([hidden])';
|
|
217
|
-
$9bf71ea28793e738$var$focusableElements.push('[tabindex]:not([tabindex="-1"]):not([disabled])');
|
|
218
|
-
const $9bf71ea28793e738$var$TABBABLE_ELEMENT_SELECTOR = $9bf71ea28793e738$var$focusableElements.join(':not([hidden]):not([tabindex="-1"]),');
|
|
219
|
-
function $9bf71ea28793e738$export$4c063cf1350e6fed(element) {
|
|
220
|
-
return element.matches($9bf71ea28793e738$var$FOCUSABLE_ELEMENT_SELECTOR);
|
|
221
|
-
}
|
|
222
203
|
function $9bf71ea28793e738$var$getScopeRoot(scope) {
|
|
223
204
|
return scope[0].parentElement;
|
|
224
205
|
}
|
|
@@ -247,7 +228,7 @@ function $9bf71ea28793e738$var$useFocusContainment(scopeRef, contain) {
|
|
|
247
228
|
// Handle the Tab key to contain focus within the scope
|
|
248
229
|
let onKeyDown = (e)=>{
|
|
249
230
|
if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey || !$9bf71ea28793e738$var$shouldContainFocus(scopeRef) || e.isComposing) return;
|
|
250
|
-
let focusedElement = ownerDocument
|
|
231
|
+
let focusedElement = (0, $cgawC$getActiveElement)(ownerDocument);
|
|
251
232
|
let scope = scopeRef.current;
|
|
252
233
|
if (!scope || !$9bf71ea28793e738$var$isElementInScope(focusedElement, scope)) return;
|
|
253
234
|
let scopeRoot = $9bf71ea28793e738$var$getScopeRoot(scope);
|
|
@@ -267,26 +248,33 @@ function $9bf71ea28793e738$var$useFocusContainment(scopeRef, contain) {
|
|
|
267
248
|
let onFocus = (e)=>{
|
|
268
249
|
// If focusing an element in a child scope of the currently active scope, the child becomes active.
|
|
269
250
|
// Moving out of the active scope to an ancestor is not allowed.
|
|
270
|
-
if ((!$9bf71ea28793e738$var$activeScope || $9bf71ea28793e738$var$isAncestorScope($9bf71ea28793e738$var$activeScope, scopeRef)) && $9bf71ea28793e738$var$isElementInScope(e
|
|
251
|
+
if ((!$9bf71ea28793e738$var$activeScope || $9bf71ea28793e738$var$isAncestorScope($9bf71ea28793e738$var$activeScope, scopeRef)) && $9bf71ea28793e738$var$isElementInScope((0, $cgawC$getEventTarget)(e), scopeRef.current)) {
|
|
271
252
|
$9bf71ea28793e738$var$activeScope = scopeRef;
|
|
272
|
-
focusedNode.current = e
|
|
273
|
-
} else if ($9bf71ea28793e738$var$shouldContainFocus(scopeRef) && !$9bf71ea28793e738$var$isElementInChildScope(e
|
|
253
|
+
focusedNode.current = (0, $cgawC$getEventTarget)(e);
|
|
254
|
+
} else if ($9bf71ea28793e738$var$shouldContainFocus(scopeRef) && !$9bf71ea28793e738$var$isElementInChildScope((0, $cgawC$getEventTarget)(e), scopeRef)) {
|
|
274
255
|
// If a focus event occurs outside the active scope (e.g. user tabs from browser location bar),
|
|
275
256
|
// restore focus to the previously focused node or the first tabbable element in the active scope.
|
|
276
257
|
if (focusedNode.current) focusedNode.current.focus();
|
|
277
258
|
else if ($9bf71ea28793e738$var$activeScope && $9bf71ea28793e738$var$activeScope.current) $9bf71ea28793e738$var$focusFirstInScope($9bf71ea28793e738$var$activeScope.current);
|
|
278
|
-
} else if ($9bf71ea28793e738$var$shouldContainFocus(scopeRef)) focusedNode.current = e
|
|
259
|
+
} else if ($9bf71ea28793e738$var$shouldContainFocus(scopeRef)) focusedNode.current = (0, $cgawC$getEventTarget)(e);
|
|
279
260
|
};
|
|
280
261
|
let onBlur = (e)=>{
|
|
281
262
|
// Firefox doesn't shift focus back to the Dialog properly without this
|
|
282
263
|
if (raf.current) cancelAnimationFrame(raf.current);
|
|
283
264
|
raf.current = requestAnimationFrame(()=>{
|
|
265
|
+
// Patches infinite focus coersion loop for Android Talkback where the user isn't able to move the virtual cursor
|
|
266
|
+
// if within a containing focus scope. Bug filed against Chrome: https://issuetracker.google.com/issues/384844019.
|
|
267
|
+
// Note that this means focus can leave focus containing modals due to this, but it is isolated to Chrome Talkback.
|
|
268
|
+
let modality = (0, $cgawC$getInteractionModality)();
|
|
269
|
+
let shouldSkipFocusRestore = (modality === 'virtual' || modality === null) && (0, $cgawC$isAndroid)() && (0, $cgawC$isChrome)();
|
|
284
270
|
// Use document.activeElement instead of e.relatedTarget so we can tell if user clicked into iframe
|
|
285
|
-
|
|
271
|
+
let activeElement = (0, $cgawC$getActiveElement)(ownerDocument);
|
|
272
|
+
if (!shouldSkipFocusRestore && activeElement && $9bf71ea28793e738$var$shouldContainFocus(scopeRef) && !$9bf71ea28793e738$var$isElementInChildScope(activeElement, scopeRef)) {
|
|
286
273
|
$9bf71ea28793e738$var$activeScope = scopeRef;
|
|
287
|
-
|
|
274
|
+
let target = (0, $cgawC$getEventTarget)(e);
|
|
275
|
+
if (target && target.isConnected) {
|
|
288
276
|
var _focusedNode_current;
|
|
289
|
-
focusedNode.current =
|
|
277
|
+
focusedNode.current = target;
|
|
290
278
|
(_focusedNode_current = focusedNode.current) === null || _focusedNode_current === void 0 ? void 0 : _focusedNode_current.focus();
|
|
291
279
|
} else if ($9bf71ea28793e738$var$activeScope.current) $9bf71ea28793e738$var$focusFirstInScope($9bf71ea28793e738$var$activeScope.current);
|
|
292
280
|
}
|
|
@@ -347,7 +335,7 @@ function $9bf71ea28793e738$var$isAncestorScope(ancestor, scope) {
|
|
|
347
335
|
}
|
|
348
336
|
function $9bf71ea28793e738$var$focusElement(element, scroll = false) {
|
|
349
337
|
if (element != null && !scroll) try {
|
|
350
|
-
(0, $
|
|
338
|
+
(0, $cgawC$focusSafely)(element);
|
|
351
339
|
} catch {
|
|
352
340
|
// ignore
|
|
353
341
|
}
|
|
@@ -385,7 +373,7 @@ function $9bf71ea28793e738$var$useAutoFocus(scopeRef, autoFocus) {
|
|
|
385
373
|
if (autoFocusRef.current) {
|
|
386
374
|
$9bf71ea28793e738$var$activeScope = scopeRef;
|
|
387
375
|
const ownerDocument = (0, $cgawC$getOwnerDocument)(scopeRef.current ? scopeRef.current[0] : undefined);
|
|
388
|
-
if (!$9bf71ea28793e738$var$isElementInScope(ownerDocument
|
|
376
|
+
if (!$9bf71ea28793e738$var$isElementInScope((0, $cgawC$getActiveElement)(ownerDocument), $9bf71ea28793e738$var$activeScope.current) && scopeRef.current) $9bf71ea28793e738$var$focusFirstInScope(scopeRef.current);
|
|
389
377
|
}
|
|
390
378
|
autoFocusRef.current = false;
|
|
391
379
|
}, [
|
|
@@ -400,7 +388,7 @@ function $9bf71ea28793e738$var$useActiveScopeTracker(scopeRef, restore, contain)
|
|
|
400
388
|
let scope = scopeRef.current;
|
|
401
389
|
const ownerDocument = (0, $cgawC$getOwnerDocument)(scope ? scope[0] : undefined);
|
|
402
390
|
let onFocus = (e)=>{
|
|
403
|
-
let target = e
|
|
391
|
+
let target = (0, $cgawC$getEventTarget)(e);
|
|
404
392
|
if ($9bf71ea28793e738$var$isElementInScope(target, scopeRef.current)) $9bf71ea28793e738$var$activeScope = scopeRef;
|
|
405
393
|
else if (!$9bf71ea28793e738$var$isElementInAnyScope(target)) $9bf71ea28793e738$var$activeScope = null;
|
|
406
394
|
};
|
|
@@ -427,7 +415,7 @@ function $9bf71ea28793e738$var$shouldRestoreFocus(scopeRef) {
|
|
|
427
415
|
function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain) {
|
|
428
416
|
// create a ref during render instead of useLayoutEffect so the active element is saved before a child with autoFocus=true mounts.
|
|
429
417
|
// eslint-disable-next-line no-restricted-globals
|
|
430
|
-
const nodeToRestoreRef = (0, $cgawC$useRef)(typeof document !== 'undefined' ? (0, $cgawC$getOwnerDocument)(scopeRef.current ? scopeRef.current[0] : undefined)
|
|
418
|
+
const nodeToRestoreRef = (0, $cgawC$useRef)(typeof document !== 'undefined' ? (0, $cgawC$getActiveElement)((0, $cgawC$getOwnerDocument)(scopeRef.current ? scopeRef.current[0] : undefined)) : null);
|
|
431
419
|
// restoring scopes should all track if they are active regardless of contain, but contain already tracks it plus logic to contain the focus
|
|
432
420
|
// restoring-non-containing scopes should only care if they become active so they can perform the restore
|
|
433
421
|
(0, $cgawC$useLayoutEffect)(()=>{
|
|
@@ -437,7 +425,7 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
437
425
|
let onFocus = ()=>{
|
|
438
426
|
// If focusing an element in a child scope of the currently active scope, the child becomes active.
|
|
439
427
|
// Moving out of the active scope to an ancestor is not allowed.
|
|
440
|
-
if ((!$9bf71ea28793e738$var$activeScope || $9bf71ea28793e738$var$isAncestorScope($9bf71ea28793e738$var$activeScope, scopeRef)) && $9bf71ea28793e738$var$isElementInScope(ownerDocument
|
|
428
|
+
if ((!$9bf71ea28793e738$var$activeScope || $9bf71ea28793e738$var$isAncestorScope($9bf71ea28793e738$var$activeScope, scopeRef)) && $9bf71ea28793e738$var$isElementInScope((0, $cgawC$getActiveElement)(ownerDocument), scopeRef.current)) $9bf71ea28793e738$var$activeScope = scopeRef;
|
|
441
429
|
};
|
|
442
430
|
ownerDocument.addEventListener('focusin', onFocus, false);
|
|
443
431
|
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener('focusin', onFocus, false));
|
|
@@ -471,7 +459,7 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
471
459
|
// Find the next tabbable element after the currently focused element
|
|
472
460
|
walker.currentNode = focusedElement;
|
|
473
461
|
let nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
|
|
474
|
-
if (!nodeToRestore || !
|
|
462
|
+
if (!nodeToRestore || !nodeToRestore.isConnected || nodeToRestore === ownerDocument.body) {
|
|
475
463
|
nodeToRestore = undefined;
|
|
476
464
|
treeNode.nodeToRestore = undefined;
|
|
477
465
|
}
|
|
@@ -514,7 +502,8 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
514
502
|
if (!treeNode) return;
|
|
515
503
|
let nodeToRestore = treeNode.nodeToRestore;
|
|
516
504
|
// if we already lost focus to the body and this was the active scope, then we should attempt to restore
|
|
517
|
-
|
|
505
|
+
let activeElement = (0, $cgawC$getActiveElement)(ownerDocument);
|
|
506
|
+
if (restoreFocus && nodeToRestore && (activeElement && $9bf71ea28793e738$var$isElementInChildScope(activeElement, scopeRef) || activeElement === ownerDocument.body && $9bf71ea28793e738$var$shouldRestoreFocus(scopeRef))) {
|
|
518
507
|
// freeze the focusScopeTree so it persists after the raf, otherwise during unmount nodes are removed from it
|
|
519
508
|
let clonedTree = $9bf71ea28793e738$export$d06fae2ee68b101e.clone();
|
|
520
509
|
requestAnimationFrame(()=>{
|
|
@@ -559,13 +548,18 @@ function $9bf71ea28793e738$var$restoreFocusToElement(node) {
|
|
|
559
548
|
}))) $9bf71ea28793e738$var$focusElement(node);
|
|
560
549
|
}
|
|
561
550
|
function $9bf71ea28793e738$export$2d6ec8fc375ceafa(root, opts, scope) {
|
|
562
|
-
let
|
|
563
|
-
|
|
551
|
+
let filter = (opts === null || opts === void 0 ? void 0 : opts.tabbable) ? (0, $cgawC$isTabbable) : (0, $cgawC$isFocusable);
|
|
552
|
+
// Ensure that root is an Element or fall back appropriately
|
|
553
|
+
let rootElement = (root === null || root === void 0 ? void 0 : root.nodeType) === Node.ELEMENT_NODE ? root : null;
|
|
554
|
+
// Determine the document to use
|
|
555
|
+
let doc = (0, $cgawC$getOwnerDocument)(rootElement);
|
|
556
|
+
// Create a TreeWalker, ensuring the root is an Element or Document
|
|
557
|
+
let walker = (0, $cgawC$createShadowTreeWalker)(doc, root || doc, NodeFilter.SHOW_ELEMENT, {
|
|
564
558
|
acceptNode (node) {
|
|
565
559
|
var _opts_from;
|
|
566
560
|
// Skip nodes inside the starting node.
|
|
567
561
|
if (opts === null || opts === void 0 ? void 0 : (_opts_from = opts.from) === null || _opts_from === void 0 ? void 0 : _opts_from.contains(node)) return NodeFilter.FILTER_REJECT;
|
|
568
|
-
if (node
|
|
562
|
+
if (filter(node) && (0, $645f2e67b85a24c9$export$e989c0fffaa6b27a)(node) && (!scope || $9bf71ea28793e738$var$isElementInScope(node, scope)) && (!(opts === null || opts === void 0 ? void 0 : opts.accept) || opts.accept(node))) return NodeFilter.FILTER_ACCEPT;
|
|
569
563
|
return NodeFilter.FILTER_SKIP;
|
|
570
564
|
}
|
|
571
565
|
});
|
|
@@ -578,7 +572,7 @@ function $9bf71ea28793e738$export$c5251b9e124bf29(ref, defaultOptions = {}) {
|
|
|
578
572
|
let root = ref.current;
|
|
579
573
|
if (!root) return null;
|
|
580
574
|
let { from: from, tabbable: tabbable = defaultOptions.tabbable, wrap: wrap = defaultOptions.wrap, accept: accept = defaultOptions.accept } = opts;
|
|
581
|
-
let node = from || (0, $cgawC$getOwnerDocument)(root)
|
|
575
|
+
let node = from || (0, $cgawC$getActiveElement)((0, $cgawC$getOwnerDocument)(root));
|
|
582
576
|
let walker = $9bf71ea28793e738$export$2d6ec8fc375ceafa(root, {
|
|
583
577
|
tabbable: tabbable,
|
|
584
578
|
accept: accept
|
|
@@ -596,7 +590,7 @@ function $9bf71ea28793e738$export$c5251b9e124bf29(ref, defaultOptions = {}) {
|
|
|
596
590
|
let root = ref.current;
|
|
597
591
|
if (!root) return null;
|
|
598
592
|
let { from: from, tabbable: tabbable = defaultOptions.tabbable, wrap: wrap = defaultOptions.wrap, accept: accept = defaultOptions.accept } = opts;
|
|
599
|
-
let node = from || (0, $cgawC$getOwnerDocument)(root)
|
|
593
|
+
let node = from || (0, $cgawC$getActiveElement)((0, $cgawC$getOwnerDocument)(root));
|
|
600
594
|
let walker = $9bf71ea28793e738$export$2d6ec8fc375ceafa(root, {
|
|
601
595
|
tabbable: tabbable,
|
|
602
596
|
accept: accept
|
|
@@ -728,5 +722,5 @@ class $9bf71ea28793e738$var$TreeNode {
|
|
|
728
722
|
let $9bf71ea28793e738$export$d06fae2ee68b101e = new $9bf71ea28793e738$var$Tree();
|
|
729
723
|
|
|
730
724
|
|
|
731
|
-
export {$9bf71ea28793e738$export$20e40289641fbbb6 as FocusScope, $9bf71ea28793e738$export$d06fae2ee68b101e as focusScopeTree, $9bf71ea28793e738$export$10c5169755ce7bd7 as useFocusManager, $9bf71ea28793e738$export$2d6ec8fc375ceafa as getFocusableTreeWalker, $9bf71ea28793e738$export$
|
|
725
|
+
export {$9bf71ea28793e738$export$20e40289641fbbb6 as FocusScope, $9bf71ea28793e738$export$d06fae2ee68b101e as focusScopeTree, $9bf71ea28793e738$export$10c5169755ce7bd7 as useFocusManager, $9bf71ea28793e738$export$2d6ec8fc375ceafa as getFocusableTreeWalker, $9bf71ea28793e738$export$1258395f99bf9cbf as isElementInChildOfActiveScope, $9bf71ea28793e738$export$c5251b9e124bf29 as createFocusManager};
|
|
732
726
|
//# sourceMappingURL=FocusScope.module.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {focusSafely as $6a99195332edec8b$export$80f3e147d781571c} from "./focusSafely.module.js";
|
|
2
1
|
import {isElementVisible as $645f2e67b85a24c9$export$e989c0fffaa6b27a} from "./isElementVisible.module.js";
|
|
3
|
-
import {useLayoutEffect as $cgawC$useLayoutEffect, getOwnerDocument as $cgawC$getOwnerDocument} from "@react-aria/utils";
|
|
2
|
+
import {useLayoutEffect as $cgawC$useLayoutEffect, getActiveElement as $cgawC$getActiveElement, getOwnerDocument as $cgawC$getOwnerDocument, getEventTarget as $cgawC$getEventTarget, isAndroid as $cgawC$isAndroid, isChrome as $cgawC$isChrome, isTabbable as $cgawC$isTabbable, isFocusable as $cgawC$isFocusable, createShadowTreeWalker as $cgawC$createShadowTreeWalker} from "@react-aria/utils";
|
|
3
|
+
import {getInteractionModality as $cgawC$getInteractionModality, focusSafely as $cgawC$focusSafely} from "@react-aria/interactions";
|
|
4
4
|
import $cgawC$react, {useRef as $cgawC$useRef, useContext as $cgawC$useContext, useMemo as $cgawC$useMemo, useEffect as $cgawC$useEffect} from "react";
|
|
5
5
|
|
|
6
6
|
/*
|
|
@@ -81,7 +81,7 @@ function $9bf71ea28793e738$export$20e40289641fbbb6(props) {
|
|
|
81
81
|
// This needs to be an effect so that activeScope is updated after the FocusScope tree is complete.
|
|
82
82
|
// It cannot be a useLayoutEffect because the parent of this node hasn't been attached in the tree yet.
|
|
83
83
|
(0, $cgawC$useEffect)(()=>{
|
|
84
|
-
const activeElement = (0, $cgawC$getOwnerDocument)(scopeRef.current ? scopeRef.current[0] : undefined)
|
|
84
|
+
const activeElement = (0, $cgawC$getActiveElement)((0, $cgawC$getOwnerDocument)(scopeRef.current ? scopeRef.current[0] : undefined));
|
|
85
85
|
let scope = null;
|
|
86
86
|
if ($9bf71ea28793e738$var$isElementInScope(activeElement, scopeRef.current)) {
|
|
87
87
|
// We need to traverse the focusScope tree and find the bottom most scope that
|
|
@@ -135,7 +135,8 @@ function $9bf71ea28793e738$var$createFocusManagerForScope(scopeRef) {
|
|
|
135
135
|
focusNext (opts = {}) {
|
|
136
136
|
let scope = scopeRef.current;
|
|
137
137
|
let { from: from, tabbable: tabbable, wrap: wrap, accept: accept } = opts;
|
|
138
|
-
|
|
138
|
+
var _scope_;
|
|
139
|
+
let node = from || (0, $cgawC$getActiveElement)((0, $cgawC$getOwnerDocument)((_scope_ = scope[0]) !== null && _scope_ !== void 0 ? _scope_ : undefined));
|
|
139
140
|
let sentinel = scope[0].previousElementSibling;
|
|
140
141
|
let scopeRoot = $9bf71ea28793e738$var$getScopeRoot(scope);
|
|
141
142
|
let walker = $9bf71ea28793e738$export$2d6ec8fc375ceafa(scopeRoot, {
|
|
@@ -154,7 +155,8 @@ function $9bf71ea28793e738$var$createFocusManagerForScope(scopeRef) {
|
|
|
154
155
|
focusPrevious (opts = {}) {
|
|
155
156
|
let scope = scopeRef.current;
|
|
156
157
|
let { from: from, tabbable: tabbable, wrap: wrap, accept: accept } = opts;
|
|
157
|
-
|
|
158
|
+
var _scope_;
|
|
159
|
+
let node = from || (0, $cgawC$getActiveElement)((0, $cgawC$getOwnerDocument)((_scope_ = scope[0]) !== null && _scope_ !== void 0 ? _scope_ : undefined));
|
|
158
160
|
let sentinel = scope[scope.length - 1].nextElementSibling;
|
|
159
161
|
let scopeRoot = $9bf71ea28793e738$var$getScopeRoot(scope);
|
|
160
162
|
let walker = $9bf71ea28793e738$export$2d6ec8fc375ceafa(scopeRoot, {
|
|
@@ -198,27 +200,6 @@ function $9bf71ea28793e738$var$createFocusManagerForScope(scopeRef) {
|
|
|
198
200
|
}
|
|
199
201
|
};
|
|
200
202
|
}
|
|
201
|
-
const $9bf71ea28793e738$var$focusableElements = [
|
|
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]'
|
|
215
|
-
];
|
|
216
|
-
const $9bf71ea28793e738$var$FOCUSABLE_ELEMENT_SELECTOR = $9bf71ea28793e738$var$focusableElements.join(':not([hidden]),') + ',[tabindex]:not([disabled]):not([hidden])';
|
|
217
|
-
$9bf71ea28793e738$var$focusableElements.push('[tabindex]:not([tabindex="-1"]):not([disabled])');
|
|
218
|
-
const $9bf71ea28793e738$var$TABBABLE_ELEMENT_SELECTOR = $9bf71ea28793e738$var$focusableElements.join(':not([hidden]):not([tabindex="-1"]),');
|
|
219
|
-
function $9bf71ea28793e738$export$4c063cf1350e6fed(element) {
|
|
220
|
-
return element.matches($9bf71ea28793e738$var$FOCUSABLE_ELEMENT_SELECTOR);
|
|
221
|
-
}
|
|
222
203
|
function $9bf71ea28793e738$var$getScopeRoot(scope) {
|
|
223
204
|
return scope[0].parentElement;
|
|
224
205
|
}
|
|
@@ -247,7 +228,7 @@ function $9bf71ea28793e738$var$useFocusContainment(scopeRef, contain) {
|
|
|
247
228
|
// Handle the Tab key to contain focus within the scope
|
|
248
229
|
let onKeyDown = (e)=>{
|
|
249
230
|
if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey || !$9bf71ea28793e738$var$shouldContainFocus(scopeRef) || e.isComposing) return;
|
|
250
|
-
let focusedElement = ownerDocument
|
|
231
|
+
let focusedElement = (0, $cgawC$getActiveElement)(ownerDocument);
|
|
251
232
|
let scope = scopeRef.current;
|
|
252
233
|
if (!scope || !$9bf71ea28793e738$var$isElementInScope(focusedElement, scope)) return;
|
|
253
234
|
let scopeRoot = $9bf71ea28793e738$var$getScopeRoot(scope);
|
|
@@ -267,26 +248,33 @@ function $9bf71ea28793e738$var$useFocusContainment(scopeRef, contain) {
|
|
|
267
248
|
let onFocus = (e)=>{
|
|
268
249
|
// If focusing an element in a child scope of the currently active scope, the child becomes active.
|
|
269
250
|
// Moving out of the active scope to an ancestor is not allowed.
|
|
270
|
-
if ((!$9bf71ea28793e738$var$activeScope || $9bf71ea28793e738$var$isAncestorScope($9bf71ea28793e738$var$activeScope, scopeRef)) && $9bf71ea28793e738$var$isElementInScope(e
|
|
251
|
+
if ((!$9bf71ea28793e738$var$activeScope || $9bf71ea28793e738$var$isAncestorScope($9bf71ea28793e738$var$activeScope, scopeRef)) && $9bf71ea28793e738$var$isElementInScope((0, $cgawC$getEventTarget)(e), scopeRef.current)) {
|
|
271
252
|
$9bf71ea28793e738$var$activeScope = scopeRef;
|
|
272
|
-
focusedNode.current = e
|
|
273
|
-
} else if ($9bf71ea28793e738$var$shouldContainFocus(scopeRef) && !$9bf71ea28793e738$var$isElementInChildScope(e
|
|
253
|
+
focusedNode.current = (0, $cgawC$getEventTarget)(e);
|
|
254
|
+
} else if ($9bf71ea28793e738$var$shouldContainFocus(scopeRef) && !$9bf71ea28793e738$var$isElementInChildScope((0, $cgawC$getEventTarget)(e), scopeRef)) {
|
|
274
255
|
// If a focus event occurs outside the active scope (e.g. user tabs from browser location bar),
|
|
275
256
|
// restore focus to the previously focused node or the first tabbable element in the active scope.
|
|
276
257
|
if (focusedNode.current) focusedNode.current.focus();
|
|
277
258
|
else if ($9bf71ea28793e738$var$activeScope && $9bf71ea28793e738$var$activeScope.current) $9bf71ea28793e738$var$focusFirstInScope($9bf71ea28793e738$var$activeScope.current);
|
|
278
|
-
} else if ($9bf71ea28793e738$var$shouldContainFocus(scopeRef)) focusedNode.current = e
|
|
259
|
+
} else if ($9bf71ea28793e738$var$shouldContainFocus(scopeRef)) focusedNode.current = (0, $cgawC$getEventTarget)(e);
|
|
279
260
|
};
|
|
280
261
|
let onBlur = (e)=>{
|
|
281
262
|
// Firefox doesn't shift focus back to the Dialog properly without this
|
|
282
263
|
if (raf.current) cancelAnimationFrame(raf.current);
|
|
283
264
|
raf.current = requestAnimationFrame(()=>{
|
|
265
|
+
// Patches infinite focus coersion loop for Android Talkback where the user isn't able to move the virtual cursor
|
|
266
|
+
// if within a containing focus scope. Bug filed against Chrome: https://issuetracker.google.com/issues/384844019.
|
|
267
|
+
// Note that this means focus can leave focus containing modals due to this, but it is isolated to Chrome Talkback.
|
|
268
|
+
let modality = (0, $cgawC$getInteractionModality)();
|
|
269
|
+
let shouldSkipFocusRestore = (modality === 'virtual' || modality === null) && (0, $cgawC$isAndroid)() && (0, $cgawC$isChrome)();
|
|
284
270
|
// Use document.activeElement instead of e.relatedTarget so we can tell if user clicked into iframe
|
|
285
|
-
|
|
271
|
+
let activeElement = (0, $cgawC$getActiveElement)(ownerDocument);
|
|
272
|
+
if (!shouldSkipFocusRestore && activeElement && $9bf71ea28793e738$var$shouldContainFocus(scopeRef) && !$9bf71ea28793e738$var$isElementInChildScope(activeElement, scopeRef)) {
|
|
286
273
|
$9bf71ea28793e738$var$activeScope = scopeRef;
|
|
287
|
-
|
|
274
|
+
let target = (0, $cgawC$getEventTarget)(e);
|
|
275
|
+
if (target && target.isConnected) {
|
|
288
276
|
var _focusedNode_current;
|
|
289
|
-
focusedNode.current =
|
|
277
|
+
focusedNode.current = target;
|
|
290
278
|
(_focusedNode_current = focusedNode.current) === null || _focusedNode_current === void 0 ? void 0 : _focusedNode_current.focus();
|
|
291
279
|
} else if ($9bf71ea28793e738$var$activeScope.current) $9bf71ea28793e738$var$focusFirstInScope($9bf71ea28793e738$var$activeScope.current);
|
|
292
280
|
}
|
|
@@ -347,7 +335,7 @@ function $9bf71ea28793e738$var$isAncestorScope(ancestor, scope) {
|
|
|
347
335
|
}
|
|
348
336
|
function $9bf71ea28793e738$var$focusElement(element, scroll = false) {
|
|
349
337
|
if (element != null && !scroll) try {
|
|
350
|
-
(0, $
|
|
338
|
+
(0, $cgawC$focusSafely)(element);
|
|
351
339
|
} catch {
|
|
352
340
|
// ignore
|
|
353
341
|
}
|
|
@@ -385,7 +373,7 @@ function $9bf71ea28793e738$var$useAutoFocus(scopeRef, autoFocus) {
|
|
|
385
373
|
if (autoFocusRef.current) {
|
|
386
374
|
$9bf71ea28793e738$var$activeScope = scopeRef;
|
|
387
375
|
const ownerDocument = (0, $cgawC$getOwnerDocument)(scopeRef.current ? scopeRef.current[0] : undefined);
|
|
388
|
-
if (!$9bf71ea28793e738$var$isElementInScope(ownerDocument
|
|
376
|
+
if (!$9bf71ea28793e738$var$isElementInScope((0, $cgawC$getActiveElement)(ownerDocument), $9bf71ea28793e738$var$activeScope.current) && scopeRef.current) $9bf71ea28793e738$var$focusFirstInScope(scopeRef.current);
|
|
389
377
|
}
|
|
390
378
|
autoFocusRef.current = false;
|
|
391
379
|
}, [
|
|
@@ -400,7 +388,7 @@ function $9bf71ea28793e738$var$useActiveScopeTracker(scopeRef, restore, contain)
|
|
|
400
388
|
let scope = scopeRef.current;
|
|
401
389
|
const ownerDocument = (0, $cgawC$getOwnerDocument)(scope ? scope[0] : undefined);
|
|
402
390
|
let onFocus = (e)=>{
|
|
403
|
-
let target = e
|
|
391
|
+
let target = (0, $cgawC$getEventTarget)(e);
|
|
404
392
|
if ($9bf71ea28793e738$var$isElementInScope(target, scopeRef.current)) $9bf71ea28793e738$var$activeScope = scopeRef;
|
|
405
393
|
else if (!$9bf71ea28793e738$var$isElementInAnyScope(target)) $9bf71ea28793e738$var$activeScope = null;
|
|
406
394
|
};
|
|
@@ -427,7 +415,7 @@ function $9bf71ea28793e738$var$shouldRestoreFocus(scopeRef) {
|
|
|
427
415
|
function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain) {
|
|
428
416
|
// create a ref during render instead of useLayoutEffect so the active element is saved before a child with autoFocus=true mounts.
|
|
429
417
|
// eslint-disable-next-line no-restricted-globals
|
|
430
|
-
const nodeToRestoreRef = (0, $cgawC$useRef)(typeof document !== 'undefined' ? (0, $cgawC$getOwnerDocument)(scopeRef.current ? scopeRef.current[0] : undefined)
|
|
418
|
+
const nodeToRestoreRef = (0, $cgawC$useRef)(typeof document !== 'undefined' ? (0, $cgawC$getActiveElement)((0, $cgawC$getOwnerDocument)(scopeRef.current ? scopeRef.current[0] : undefined)) : null);
|
|
431
419
|
// restoring scopes should all track if they are active regardless of contain, but contain already tracks it plus logic to contain the focus
|
|
432
420
|
// restoring-non-containing scopes should only care if they become active so they can perform the restore
|
|
433
421
|
(0, $cgawC$useLayoutEffect)(()=>{
|
|
@@ -437,7 +425,7 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
437
425
|
let onFocus = ()=>{
|
|
438
426
|
// If focusing an element in a child scope of the currently active scope, the child becomes active.
|
|
439
427
|
// Moving out of the active scope to an ancestor is not allowed.
|
|
440
|
-
if ((!$9bf71ea28793e738$var$activeScope || $9bf71ea28793e738$var$isAncestorScope($9bf71ea28793e738$var$activeScope, scopeRef)) && $9bf71ea28793e738$var$isElementInScope(ownerDocument
|
|
428
|
+
if ((!$9bf71ea28793e738$var$activeScope || $9bf71ea28793e738$var$isAncestorScope($9bf71ea28793e738$var$activeScope, scopeRef)) && $9bf71ea28793e738$var$isElementInScope((0, $cgawC$getActiveElement)(ownerDocument), scopeRef.current)) $9bf71ea28793e738$var$activeScope = scopeRef;
|
|
441
429
|
};
|
|
442
430
|
ownerDocument.addEventListener('focusin', onFocus, false);
|
|
443
431
|
scope === null || scope === void 0 ? void 0 : scope.forEach((element)=>element.addEventListener('focusin', onFocus, false));
|
|
@@ -471,7 +459,7 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
471
459
|
// Find the next tabbable element after the currently focused element
|
|
472
460
|
walker.currentNode = focusedElement;
|
|
473
461
|
let nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
|
|
474
|
-
if (!nodeToRestore || !
|
|
462
|
+
if (!nodeToRestore || !nodeToRestore.isConnected || nodeToRestore === ownerDocument.body) {
|
|
475
463
|
nodeToRestore = undefined;
|
|
476
464
|
treeNode.nodeToRestore = undefined;
|
|
477
465
|
}
|
|
@@ -514,7 +502,8 @@ function $9bf71ea28793e738$var$useRestoreFocus(scopeRef, restoreFocus, contain)
|
|
|
514
502
|
if (!treeNode) return;
|
|
515
503
|
let nodeToRestore = treeNode.nodeToRestore;
|
|
516
504
|
// if we already lost focus to the body and this was the active scope, then we should attempt to restore
|
|
517
|
-
|
|
505
|
+
let activeElement = (0, $cgawC$getActiveElement)(ownerDocument);
|
|
506
|
+
if (restoreFocus && nodeToRestore && (activeElement && $9bf71ea28793e738$var$isElementInChildScope(activeElement, scopeRef) || activeElement === ownerDocument.body && $9bf71ea28793e738$var$shouldRestoreFocus(scopeRef))) {
|
|
518
507
|
// freeze the focusScopeTree so it persists after the raf, otherwise during unmount nodes are removed from it
|
|
519
508
|
let clonedTree = $9bf71ea28793e738$export$d06fae2ee68b101e.clone();
|
|
520
509
|
requestAnimationFrame(()=>{
|
|
@@ -559,13 +548,18 @@ function $9bf71ea28793e738$var$restoreFocusToElement(node) {
|
|
|
559
548
|
}))) $9bf71ea28793e738$var$focusElement(node);
|
|
560
549
|
}
|
|
561
550
|
function $9bf71ea28793e738$export$2d6ec8fc375ceafa(root, opts, scope) {
|
|
562
|
-
let
|
|
563
|
-
|
|
551
|
+
let filter = (opts === null || opts === void 0 ? void 0 : opts.tabbable) ? (0, $cgawC$isTabbable) : (0, $cgawC$isFocusable);
|
|
552
|
+
// Ensure that root is an Element or fall back appropriately
|
|
553
|
+
let rootElement = (root === null || root === void 0 ? void 0 : root.nodeType) === Node.ELEMENT_NODE ? root : null;
|
|
554
|
+
// Determine the document to use
|
|
555
|
+
let doc = (0, $cgawC$getOwnerDocument)(rootElement);
|
|
556
|
+
// Create a TreeWalker, ensuring the root is an Element or Document
|
|
557
|
+
let walker = (0, $cgawC$createShadowTreeWalker)(doc, root || doc, NodeFilter.SHOW_ELEMENT, {
|
|
564
558
|
acceptNode (node) {
|
|
565
559
|
var _opts_from;
|
|
566
560
|
// Skip nodes inside the starting node.
|
|
567
561
|
if (opts === null || opts === void 0 ? void 0 : (_opts_from = opts.from) === null || _opts_from === void 0 ? void 0 : _opts_from.contains(node)) return NodeFilter.FILTER_REJECT;
|
|
568
|
-
if (node
|
|
562
|
+
if (filter(node) && (0, $645f2e67b85a24c9$export$e989c0fffaa6b27a)(node) && (!scope || $9bf71ea28793e738$var$isElementInScope(node, scope)) && (!(opts === null || opts === void 0 ? void 0 : opts.accept) || opts.accept(node))) return NodeFilter.FILTER_ACCEPT;
|
|
569
563
|
return NodeFilter.FILTER_SKIP;
|
|
570
564
|
}
|
|
571
565
|
});
|
|
@@ -578,7 +572,7 @@ function $9bf71ea28793e738$export$c5251b9e124bf29(ref, defaultOptions = {}) {
|
|
|
578
572
|
let root = ref.current;
|
|
579
573
|
if (!root) return null;
|
|
580
574
|
let { from: from, tabbable: tabbable = defaultOptions.tabbable, wrap: wrap = defaultOptions.wrap, accept: accept = defaultOptions.accept } = opts;
|
|
581
|
-
let node = from || (0, $cgawC$getOwnerDocument)(root)
|
|
575
|
+
let node = from || (0, $cgawC$getActiveElement)((0, $cgawC$getOwnerDocument)(root));
|
|
582
576
|
let walker = $9bf71ea28793e738$export$2d6ec8fc375ceafa(root, {
|
|
583
577
|
tabbable: tabbable,
|
|
584
578
|
accept: accept
|
|
@@ -596,7 +590,7 @@ function $9bf71ea28793e738$export$c5251b9e124bf29(ref, defaultOptions = {}) {
|
|
|
596
590
|
let root = ref.current;
|
|
597
591
|
if (!root) return null;
|
|
598
592
|
let { from: from, tabbable: tabbable = defaultOptions.tabbable, wrap: wrap = defaultOptions.wrap, accept: accept = defaultOptions.accept } = opts;
|
|
599
|
-
let node = from || (0, $cgawC$getOwnerDocument)(root)
|
|
593
|
+
let node = from || (0, $cgawC$getActiveElement)((0, $cgawC$getOwnerDocument)(root));
|
|
600
594
|
let walker = $9bf71ea28793e738$export$2d6ec8fc375ceafa(root, {
|
|
601
595
|
tabbable: tabbable,
|
|
602
596
|
accept: accept
|
|
@@ -728,5 +722,5 @@ class $9bf71ea28793e738$var$TreeNode {
|
|
|
728
722
|
let $9bf71ea28793e738$export$d06fae2ee68b101e = new $9bf71ea28793e738$var$Tree();
|
|
729
723
|
|
|
730
724
|
|
|
731
|
-
export {$9bf71ea28793e738$export$20e40289641fbbb6 as FocusScope, $9bf71ea28793e738$export$d06fae2ee68b101e as focusScopeTree, $9bf71ea28793e738$export$10c5169755ce7bd7 as useFocusManager, $9bf71ea28793e738$export$2d6ec8fc375ceafa as getFocusableTreeWalker, $9bf71ea28793e738$export$
|
|
725
|
+
export {$9bf71ea28793e738$export$20e40289641fbbb6 as FocusScope, $9bf71ea28793e738$export$d06fae2ee68b101e as focusScopeTree, $9bf71ea28793e738$export$10c5169755ce7bd7 as useFocusManager, $9bf71ea28793e738$export$2d6ec8fc375ceafa as getFocusableTreeWalker, $9bf71ea28793e738$export$1258395f99bf9cbf as isElementInChildOfActiveScope, $9bf71ea28793e738$export$c5251b9e124bf29 as createFocusManager};
|
|
732
726
|
//# sourceMappingURL=FocusScope.module.js.map
|