@react-aria/focus 3.5.0 → 3.5.1

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/module.js CHANGED
@@ -1,33 +1,38 @@
1
- import _babelRuntimeHelpersEsmObjectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
- import _clsx from "clsx";
3
- import _babelRuntimeHelpersEsmExtends from "@babel/runtime/helpers/esm/extends";
4
- import _react, { useContext, useEffect, useRef, useState } from "react";
5
- import { getInteractionModality, isFocusVisible as _isFocusVisible, useFocus, useFocusVisibleListener, useFocusWithin, useKeyboard } from "@react-aria/interactions";
6
- import { focusWithoutScrolling, runAfterTransition, useLayoutEffect, mergeProps, useSyncRef } from "@react-aria/utils";
1
+ import $bmn4K$react, {useRef as $bmn4K$useRef, useContext as $bmn4K$useContext, useEffect as $bmn4K$useEffect, useState as $bmn4K$useState} from "react";
2
+ import {useLayoutEffect as $bmn4K$useLayoutEffect, runAfterTransition as $bmn4K$runAfterTransition, focusWithoutScrolling as $bmn4K$focusWithoutScrolling, mergeProps as $bmn4K$mergeProps, useSyncRef as $bmn4K$useSyncRef} from "@react-aria/utils";
3
+ import {getInteractionModality as $bmn4K$getInteractionModality, isFocusVisible as $bmn4K$isFocusVisible, useFocusVisibleListener as $bmn4K$useFocusVisibleListener, useFocus as $bmn4K$useFocus, useFocusWithin as $bmn4K$useFocusWithin, useKeyboard as $bmn4K$useKeyboard} from "@react-aria/interactions";
4
+ import $bmn4K$clsx from "clsx";
7
5
 
8
- /**
9
- * A utility function that focuses an element while avoiding undesired side effects such
10
- * as page scrolling and screen reader issues with CSS transitions.
11
- */
12
- export function focusSafely(element) {
13
- // If the user is interacting with a virtual cursor, e.g. screen reader, then
14
- // wait until after any animated transitions that are currently occurring on
15
- // the page before shifting focus. This avoids issues with VoiceOver on iOS
16
- // causing the page to scroll when moving focus if the element is transitioning
17
- // from off the screen.
18
- if (getInteractionModality() === 'virtual') {
19
- let lastFocusedElement = document.activeElement;
20
- runAfterTransition(() => {
21
- // If focus did not move and the element is still in the document, focus it.
22
- if (document.activeElement === lastFocusedElement && document.contains(element)) {
23
- focusWithoutScrolling(element);
24
- }
25
- });
26
- } else {
27
- focusWithoutScrolling(element);
28
- }
6
+ function $parcel$export(e, n, v, s) {
7
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
8
+ }
9
+ var $0238e4b796d1715f$exports = {};
10
+
11
+ $parcel$export($0238e4b796d1715f$exports, "FocusScope", () => $0238e4b796d1715f$export$20e40289641fbbb6);
12
+ $parcel$export($0238e4b796d1715f$exports, "useFocusManager", () => $0238e4b796d1715f$export$10c5169755ce7bd7);
13
+ $parcel$export($0238e4b796d1715f$exports, "getFocusableTreeWalker", () => $0238e4b796d1715f$export$2d6ec8fc375ceafa);
14
+ $parcel$export($0238e4b796d1715f$exports, "createFocusManager", () => $0238e4b796d1715f$export$c5251b9e124bf29);
15
+ var $f2c1256fdcfd2c09$exports = {};
16
+
17
+ $parcel$export($f2c1256fdcfd2c09$exports, "focusSafely", () => $f2c1256fdcfd2c09$export$80f3e147d781571c);
18
+
19
+
20
+ function $f2c1256fdcfd2c09$export$80f3e147d781571c(element) {
21
+ // If the user is interacting with a virtual cursor, e.g. screen reader, then
22
+ // wait until after any animated transitions that are currently occurring on
23
+ // the page before shifting focus. This avoids issues with VoiceOver on iOS
24
+ // causing the page to scroll when moving focus if the element is transitioning
25
+ // from off the screen.
26
+ if ($bmn4K$getInteractionModality() === 'virtual') {
27
+ let lastFocusedElement = document.activeElement;
28
+ $bmn4K$runAfterTransition(()=>{
29
+ // If focus did not move and the element is still in the document, focus it.
30
+ if (document.activeElement === lastFocusedElement && document.contains(element)) $bmn4K$focusWithoutScrolling(element);
31
+ });
32
+ } else $bmn4K$focusWithoutScrolling(element);
29
33
  }
30
34
 
35
+
31
36
  /*
32
37
  * Copyright 2021 Adobe. All rights reserved.
33
38
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
@@ -38,818 +43,558 @@ export function focusSafely(element) {
38
43
  * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
39
44
  * OF ANY KIND, either express or implied. See the License for the specific language
40
45
  * governing permissions and limitations under the License.
41
- */
42
- function $ee5e90cbb4a22466973155c14222fa1$var$isStyleVisible(element) {
43
- if (!(element instanceof HTMLElement) && !(element instanceof SVGElement)) {
44
- return false;
45
- }
46
-
47
- let {
48
- display,
49
- visibility
50
- } = element.style;
51
- let isVisible = display !== 'none' && visibility !== 'hidden' && visibility !== 'collapse';
52
-
53
- if (isVisible) {
54
- const {
55
- getComputedStyle
56
- } = element.ownerDocument.defaultView;
57
- let {
58
- display: computedDisplay,
59
- visibility: computedVisibility
60
- } = getComputedStyle(element);
61
- isVisible = computedDisplay !== 'none' && computedVisibility !== 'hidden' && computedVisibility !== 'collapse';
62
- }
63
-
64
- return isVisible;
65
- }
66
-
67
- function $ee5e90cbb4a22466973155c14222fa1$var$isAttributeVisible(element, childElement) {
68
- return !element.hasAttribute('hidden') && (element.nodeName === 'DETAILS' && childElement && childElement.nodeName !== 'SUMMARY' ? element.hasAttribute('open') : true);
69
- }
70
- /**
71
- * Adapted from https://github.com/testing-library/jest-dom and
72
- * https://github.com/vuejs/vue-test-utils-next/.
73
- * Licensed under the MIT License.
74
- * @param element - Element to evaluate for display or visibility.
75
- */
76
-
77
-
78
- function $ee5e90cbb4a22466973155c14222fa1$export$isElementVisible(element, childElement) {
79
- return element.nodeName !== '#comment' && $ee5e90cbb4a22466973155c14222fa1$var$isStyleVisible(element) && $ee5e90cbb4a22466973155c14222fa1$var$isAttributeVisible(element, childElement) && (!element.parentElement || $ee5e90cbb4a22466973155c14222fa1$export$isElementVisible(element.parentElement, element));
80
- }
81
-
82
- const $c9e8f80f5bb1841844f54e4ad30b$var$FocusContext = /*#__PURE__*/_react.createContext(null);
83
-
84
- let $c9e8f80f5bb1841844f54e4ad30b$var$activeScope = null;
85
- let $c9e8f80f5bb1841844f54e4ad30b$var$scopes = new Map(); // This is a hacky DOM-based implementation of a FocusScope until this RFC lands in React:
86
- // https://github.com/reactjs/rfcs/pull/109
87
- // For now, it relies on the DOM tree order rather than the React tree order, and is probably
88
- // less optimized for performance.
89
-
90
- /**
91
- * A FocusScope manages focus for its descendants. It supports containing focus inside
92
- * the scope, restoring focus to the previously focused element on unmount, and auto
93
- * focusing children on mount. It also acts as a container for a programmatic focus
94
- * management interface that can be used to move focus forward and back in response
95
- * to user events.
96
- */
97
-
98
- export function FocusScope(props) {
99
- let {
100
- children,
101
- contain,
102
- restoreFocus,
103
- autoFocus
104
- } = props;
105
- let startRef = useRef();
106
- let endRef = useRef();
107
- let scopeRef = useRef([]);
108
- let ctx = useContext($c9e8f80f5bb1841844f54e4ad30b$var$FocusContext);
109
- let parentScope = ctx == null ? void 0 : ctx.scopeRef;
110
- useLayoutEffect(() => {
111
- // Find all rendered nodes between the sentinels and add them to the scope.
112
- let node = startRef.current.nextSibling;
113
- let nodes = [];
114
-
115
- while (node && node !== endRef.current) {
116
- nodes.push(node);
117
- node = node.nextSibling;
118
- }
119
-
120
- scopeRef.current = nodes;
121
- }, [children, parentScope]);
122
- useLayoutEffect(() => {
123
- $c9e8f80f5bb1841844f54e4ad30b$var$scopes.set(scopeRef, parentScope);
124
- return () => {
125
- // Restore the active scope on unmount if this scope or a descendant scope is active.
126
- // Parent effect cleanups run before children, so we need to check if the
127
- // parent scope actually still exists before restoring the active scope to it.
128
- if ((scopeRef === $c9e8f80f5bb1841844f54e4ad30b$var$activeScope || $c9e8f80f5bb1841844f54e4ad30b$var$isAncestorScope(scopeRef, $c9e8f80f5bb1841844f54e4ad30b$var$activeScope)) && (!parentScope || $c9e8f80f5bb1841844f54e4ad30b$var$scopes.has(parentScope))) {
129
- $c9e8f80f5bb1841844f54e4ad30b$var$activeScope = parentScope;
130
- }
131
-
132
- $c9e8f80f5bb1841844f54e4ad30b$var$scopes.delete(scopeRef);
133
- };
134
- }, [scopeRef, parentScope]);
135
- $c9e8f80f5bb1841844f54e4ad30b$var$useFocusContainment(scopeRef, contain);
136
- $c9e8f80f5bb1841844f54e4ad30b$var$useRestoreFocus(scopeRef, restoreFocus, contain);
137
- $c9e8f80f5bb1841844f54e4ad30b$var$useAutoFocus(scopeRef, autoFocus);
138
- let focusManager = $c9e8f80f5bb1841844f54e4ad30b$var$createFocusManagerForScope(scopeRef);
139
- return /*#__PURE__*/_react.createElement($c9e8f80f5bb1841844f54e4ad30b$var$FocusContext.Provider, {
140
- value: {
141
- scopeRef,
142
- focusManager
46
+ */ function $c5775c2d6be42e6d$var$isStyleVisible(element) {
47
+ if (!(element instanceof HTMLElement) && !(element instanceof SVGElement)) return false;
48
+ let { display: display , visibility: visibility } = element.style;
49
+ let isVisible = display !== 'none' && visibility !== 'hidden' && visibility !== 'collapse';
50
+ if (isVisible) {
51
+ const { getComputedStyle: getComputedStyle } = element.ownerDocument.defaultView;
52
+ let { display: computedDisplay , visibility: computedVisibility } = getComputedStyle(element);
53
+ isVisible = computedDisplay !== 'none' && computedVisibility !== 'hidden' && computedVisibility !== 'collapse';
143
54
  }
144
- }, /*#__PURE__*/_react.createElement("span", {
145
- "data-focus-scope-start": true,
146
- hidden: true,
147
- ref: startRef
148
- }), children, /*#__PURE__*/_react.createElement("span", {
149
- "data-focus-scope-end": true,
150
- hidden: true,
151
- ref: endRef
152
- }));
55
+ return isVisible;
153
56
  }
154
- /**
155
- * Returns a FocusManager interface for the parent FocusScope.
156
- * A FocusManager can be used to programmatically move focus within
157
- * a FocusScope, e.g. in response to user events like keyboard navigation.
158
- */
159
-
160
- export function useFocusManager() {
161
- var _useContext;
162
-
163
- return (_useContext = useContext($c9e8f80f5bb1841844f54e4ad30b$var$FocusContext)) == null ? void 0 : _useContext.focusManager;
57
+ function $c5775c2d6be42e6d$var$isAttributeVisible(element, childElement) {
58
+ return !element.hasAttribute('hidden') && (element.nodeName === 'DETAILS' && childElement && childElement.nodeName !== 'SUMMARY' ? element.hasAttribute('open') : true);
164
59
  }
165
-
166
- function $c9e8f80f5bb1841844f54e4ad30b$var$createFocusManagerForScope(scopeRef) {
167
- return {
168
- focusNext(opts) {
169
- if (opts === void 0) {
170
- opts = {};
171
- }
172
-
173
- let scope = scopeRef.current;
174
- let {
175
- from,
176
- tabbable,
177
- wrap
178
- } = opts;
179
- let node = from || document.activeElement;
180
- let sentinel = scope[0].previousElementSibling;
181
- let walker = getFocusableTreeWalker($c9e8f80f5bb1841844f54e4ad30b$var$getScopeRoot(scope), {
182
- tabbable
183
- }, scope);
184
- walker.currentNode = $c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(node, scope) ? node : sentinel;
185
- let nextNode = walker.nextNode();
186
-
187
- if (!nextNode && wrap) {
188
- walker.currentNode = sentinel;
189
- nextNode = walker.nextNode();
190
- }
191
-
192
- if (nextNode) {
193
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(nextNode, true);
194
- }
195
-
196
- return nextNode;
197
- },
198
-
199
- focusPrevious(opts) {
200
- if (opts === void 0) {
201
- opts = {};
202
- }
203
-
204
- let scope = scopeRef.current;
205
- let {
206
- from,
207
- tabbable,
208
- wrap
209
- } = opts;
210
- let node = from || document.activeElement;
211
- let sentinel = scope[scope.length - 1].nextElementSibling;
212
- let walker = getFocusableTreeWalker($c9e8f80f5bb1841844f54e4ad30b$var$getScopeRoot(scope), {
213
- tabbable
214
- }, scope);
215
- walker.currentNode = $c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(node, scope) ? node : sentinel;
216
- let previousNode = walker.previousNode();
217
-
218
- if (!previousNode && wrap) {
219
- walker.currentNode = sentinel;
220
- previousNode = walker.previousNode();
221
- }
222
-
223
- if (previousNode) {
224
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(previousNode, true);
225
- }
226
-
227
- return previousNode;
228
- },
229
-
230
- focusFirst(opts) {
231
- if (opts === void 0) {
232
- opts = {};
233
- }
234
-
235
- let scope = scopeRef.current;
236
- let {
237
- tabbable
238
- } = opts;
239
- let walker = getFocusableTreeWalker($c9e8f80f5bb1841844f54e4ad30b$var$getScopeRoot(scope), {
240
- tabbable
241
- }, scope);
242
- walker.currentNode = scope[0].previousElementSibling;
243
- let nextNode = walker.nextNode();
244
-
245
- if (nextNode) {
246
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(nextNode, true);
247
- }
248
-
249
- return nextNode;
250
- },
251
-
252
- focusLast(opts) {
253
- if (opts === void 0) {
254
- opts = {};
255
- }
256
-
257
- let scope = scopeRef.current;
258
- let {
259
- tabbable
260
- } = opts;
261
- let walker = getFocusableTreeWalker($c9e8f80f5bb1841844f54e4ad30b$var$getScopeRoot(scope), {
262
- tabbable
263
- }, scope);
264
- walker.currentNode = scope[scope.length - 1].nextElementSibling;
265
- let previousNode = walker.previousNode();
266
-
267
- if (previousNode) {
268
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(previousNode, true);
269
- }
270
-
271
- return previousNode;
272
- }
273
-
274
- };
60
+ function $c5775c2d6be42e6d$export$e989c0fffaa6b27a(element, childElement) {
61
+ return element.nodeName !== '#comment' && $c5775c2d6be42e6d$var$isStyleVisible(element) && $c5775c2d6be42e6d$var$isAttributeVisible(element, childElement) && (!element.parentElement || $c5775c2d6be42e6d$export$e989c0fffaa6b27a(element.parentElement, element));
275
62
  }
276
63
 
277
- const $c9e8f80f5bb1841844f54e4ad30b$var$focusableElements = ['input:not([disabled]):not([type=hidden])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', 'a[href]', 'area[href]', 'summary', 'iframe', 'object', 'embed', 'audio[controls]', 'video[controls]', '[contenteditable]'];
278
- const $c9e8f80f5bb1841844f54e4ad30b$var$FOCUSABLE_ELEMENT_SELECTOR = $c9e8f80f5bb1841844f54e4ad30b$var$focusableElements.join(':not([hidden]),') + ',[tabindex]:not([disabled]):not([hidden])';
279
- $c9e8f80f5bb1841844f54e4ad30b$var$focusableElements.push('[tabindex]:not([tabindex="-1"]):not([disabled])');
280
- const $c9e8f80f5bb1841844f54e4ad30b$var$TABBABLE_ELEMENT_SELECTOR = $c9e8f80f5bb1841844f54e4ad30b$var$focusableElements.join(':not([hidden]):not([tabindex="-1"]),');
281
-
282
- function $c9e8f80f5bb1841844f54e4ad30b$var$getScopeRoot(scope) {
283
- return scope[0].parentElement;
284
- }
285
-
286
- function $c9e8f80f5bb1841844f54e4ad30b$var$useFocusContainment(scopeRef, contain) {
287
- let focusedNode = useRef();
288
- let raf = useRef(null);
289
- useLayoutEffect(() => {
290
- let scope = scopeRef.current;
291
-
292
- if (!contain) {
293
- return;
294
- } // Handle the Tab key to contain focus within the scope
295
64
 
296
65
 
297
- let onKeyDown = e => {
298
- if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey || scopeRef !== $c9e8f80f5bb1841844f54e4ad30b$var$activeScope) {
299
- return;
300
- }
301
66
 
302
- let focusedElement = document.activeElement;
303
- let scope = scopeRef.current;
304
-
305
- if (!$c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(focusedElement, scope)) {
306
- return;
307
- }
308
-
309
- let walker = getFocusableTreeWalker($c9e8f80f5bb1841844f54e4ad30b$var$getScopeRoot(scope), {
310
- tabbable: true
311
- }, scope);
312
- walker.currentNode = focusedElement;
313
- let nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
314
-
315
- if (!nextElement) {
316
- walker.currentNode = e.shiftKey ? scope[scope.length - 1].nextElementSibling : scope[0].previousElementSibling;
317
- nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
318
- }
319
-
320
- e.preventDefault();
321
-
322
- if (nextElement) {
323
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(nextElement, true);
324
- }
325
- };
326
-
327
- let onFocus = e => {
328
- // If focusing an element in a child scope of the currently active scope, the child becomes active.
329
- // Moving out of the active scope to an ancestor is not allowed.
330
- if (!$c9e8f80f5bb1841844f54e4ad30b$var$activeScope || $c9e8f80f5bb1841844f54e4ad30b$var$isAncestorScope($c9e8f80f5bb1841844f54e4ad30b$var$activeScope, scopeRef)) {
331
- $c9e8f80f5bb1841844f54e4ad30b$var$activeScope = scopeRef;
332
- focusedNode.current = e.target;
333
- } else if (scopeRef === $c9e8f80f5bb1841844f54e4ad30b$var$activeScope && !$c9e8f80f5bb1841844f54e4ad30b$var$isElementInChildScope(e.target, scopeRef)) {
334
- // If a focus event occurs outside the active scope (e.g. user tabs from browser location bar),
335
- // restore focus to the previously focused node or the first tabbable element in the active scope.
336
- if (focusedNode.current) {
337
- focusedNode.current.focus();
338
- } else if ($c9e8f80f5bb1841844f54e4ad30b$var$activeScope) {
339
- $c9e8f80f5bb1841844f54e4ad30b$var$focusFirstInScope($c9e8f80f5bb1841844f54e4ad30b$var$activeScope.current);
67
+ const $0238e4b796d1715f$var$FocusContext = /*#__PURE__*/ $bmn4K$react.createContext(null);
68
+ let $0238e4b796d1715f$var$activeScope = null;
69
+ let $0238e4b796d1715f$var$scopes = new Map();
70
+ function $0238e4b796d1715f$export$20e40289641fbbb6(props) {
71
+ let { children: children , contain: contain , restoreFocus: restoreFocus , autoFocus: autoFocus } = props;
72
+ let startRef = $bmn4K$useRef();
73
+ let endRef = $bmn4K$useRef();
74
+ let scopeRef = $bmn4K$useRef([]);
75
+ let ctx = $bmn4K$useContext($0238e4b796d1715f$var$FocusContext);
76
+ let parentScope = ctx?.scopeRef;
77
+ $bmn4K$useLayoutEffect(()=>{
78
+ // Find all rendered nodes between the sentinels and add them to the scope.
79
+ let node = startRef.current.nextSibling;
80
+ let nodes = [];
81
+ while(node && node !== endRef.current){
82
+ nodes.push(node);
83
+ node = node.nextSibling;
340
84
  }
341
- } else if (scopeRef === $c9e8f80f5bb1841844f54e4ad30b$var$activeScope) {
342
- focusedNode.current = e.target;
343
- }
344
- };
345
-
346
- let onBlur = e => {
347
- // Firefox doesn't shift focus back to the Dialog properly without this
348
- raf.current = requestAnimationFrame(() => {
349
- // Use document.activeElement instead of e.relatedTarget so we can tell if user clicked into iframe
350
- if (scopeRef === $c9e8f80f5bb1841844f54e4ad30b$var$activeScope && !$c9e8f80f5bb1841844f54e4ad30b$var$isElementInChildScope(document.activeElement, scopeRef)) {
351
- $c9e8f80f5bb1841844f54e4ad30b$var$activeScope = scopeRef;
352
- focusedNode.current = e.target;
353
- focusedNode.current.focus();
85
+ scopeRef.current = nodes;
86
+ }, [
87
+ children,
88
+ parentScope
89
+ ]);
90
+ $bmn4K$useLayoutEffect(()=>{
91
+ $0238e4b796d1715f$var$scopes.set(scopeRef, parentScope);
92
+ return ()=>{
93
+ // Restore the active scope on unmount if this scope or a descendant scope is active.
94
+ // Parent effect cleanups run before children, so we need to check if the
95
+ // parent scope actually still exists before restoring the active scope to it.
96
+ if ((scopeRef === $0238e4b796d1715f$var$activeScope || $0238e4b796d1715f$var$isAncestorScope(scopeRef, $0238e4b796d1715f$var$activeScope)) && (!parentScope || $0238e4b796d1715f$var$scopes.has(parentScope))) $0238e4b796d1715f$var$activeScope = parentScope;
97
+ $0238e4b796d1715f$var$scopes.delete(scopeRef);
98
+ };
99
+ }, [
100
+ scopeRef,
101
+ parentScope
102
+ ]);
103
+ $0238e4b796d1715f$var$useFocusContainment(scopeRef, contain);
104
+ $0238e4b796d1715f$var$useRestoreFocus(scopeRef, restoreFocus, contain);
105
+ $0238e4b796d1715f$var$useAutoFocus(scopeRef, autoFocus);
106
+ let focusManager = $0238e4b796d1715f$var$createFocusManagerForScope(scopeRef);
107
+ return(/*#__PURE__*/ $bmn4K$react.createElement($0238e4b796d1715f$var$FocusContext.Provider, {
108
+ value: {
109
+ scopeRef: scopeRef,
110
+ focusManager: focusManager
111
+ }
112
+ }, /*#__PURE__*/ $bmn4K$react.createElement("span", {
113
+ "data-focus-scope-start": true,
114
+ hidden: true,
115
+ ref: startRef
116
+ }), children, /*#__PURE__*/ $bmn4K$react.createElement("span", {
117
+ "data-focus-scope-end": true,
118
+ hidden: true,
119
+ ref: endRef
120
+ })));
121
+ }
122
+ function $0238e4b796d1715f$export$10c5169755ce7bd7() {
123
+ return $bmn4K$useContext($0238e4b796d1715f$var$FocusContext)?.focusManager;
124
+ }
125
+ function $0238e4b796d1715f$var$createFocusManagerForScope(scopeRef) {
126
+ return {
127
+ focusNext (opts = {
128
+ }) {
129
+ let scope = scopeRef.current;
130
+ let { from: from , tabbable: tabbable , wrap: wrap } = opts;
131
+ let node = from || document.activeElement;
132
+ let sentinel = scope[0].previousElementSibling;
133
+ let walker = $0238e4b796d1715f$export$2d6ec8fc375ceafa($0238e4b796d1715f$var$getScopeRoot(scope), {
134
+ tabbable: tabbable
135
+ }, scope);
136
+ walker.currentNode = $0238e4b796d1715f$var$isElementInScope(node, scope) ? node : sentinel;
137
+ let nextNode = walker.nextNode();
138
+ if (!nextNode && wrap) {
139
+ walker.currentNode = sentinel;
140
+ nextNode = walker.nextNode();
141
+ }
142
+ if (nextNode) $0238e4b796d1715f$var$focusElement(nextNode, true);
143
+ return nextNode;
144
+ },
145
+ focusPrevious (opts = {
146
+ }) {
147
+ let scope = scopeRef.current;
148
+ let { from: from , tabbable: tabbable , wrap: wrap } = opts;
149
+ let node = from || document.activeElement;
150
+ let sentinel = scope[scope.length - 1].nextElementSibling;
151
+ let walker = $0238e4b796d1715f$export$2d6ec8fc375ceafa($0238e4b796d1715f$var$getScopeRoot(scope), {
152
+ tabbable: tabbable
153
+ }, scope);
154
+ walker.currentNode = $0238e4b796d1715f$var$isElementInScope(node, scope) ? node : sentinel;
155
+ let previousNode = walker.previousNode();
156
+ if (!previousNode && wrap) {
157
+ walker.currentNode = sentinel;
158
+ previousNode = walker.previousNode();
159
+ }
160
+ if (previousNode) $0238e4b796d1715f$var$focusElement(previousNode, true);
161
+ return previousNode;
162
+ },
163
+ focusFirst (opts = {
164
+ }) {
165
+ let scope = scopeRef.current;
166
+ let { tabbable: tabbable } = opts;
167
+ let walker = $0238e4b796d1715f$export$2d6ec8fc375ceafa($0238e4b796d1715f$var$getScopeRoot(scope), {
168
+ tabbable: tabbable
169
+ }, scope);
170
+ walker.currentNode = scope[0].previousElementSibling;
171
+ let nextNode = walker.nextNode();
172
+ if (nextNode) $0238e4b796d1715f$var$focusElement(nextNode, true);
173
+ return nextNode;
174
+ },
175
+ focusLast (opts = {
176
+ }) {
177
+ let scope = scopeRef.current;
178
+ let { tabbable: tabbable } = opts;
179
+ let walker = $0238e4b796d1715f$export$2d6ec8fc375ceafa($0238e4b796d1715f$var$getScopeRoot(scope), {
180
+ tabbable: tabbable
181
+ }, scope);
182
+ walker.currentNode = scope[scope.length - 1].nextElementSibling;
183
+ let previousNode = walker.previousNode();
184
+ if (previousNode) $0238e4b796d1715f$var$focusElement(previousNode, true);
185
+ return previousNode;
354
186
  }
355
- });
356
- };
357
-
358
- document.addEventListener('keydown', onKeyDown, false);
359
- document.addEventListener('focusin', onFocus, false);
360
- scope.forEach(element => element.addEventListener('focusin', onFocus, false));
361
- scope.forEach(element => element.addEventListener('focusout', onBlur, false));
362
- return () => {
363
- document.removeEventListener('keydown', onKeyDown, false);
364
- document.removeEventListener('focusin', onFocus, false);
365
- scope.forEach(element => element.removeEventListener('focusin', onFocus, false));
366
- scope.forEach(element => element.removeEventListener('focusout', onBlur, false));
367
187
  };
368
- }, [scopeRef, contain]); // eslint-disable-next-line arrow-body-style
369
-
370
- useEffect(() => {
371
- return () => cancelAnimationFrame(raf.current);
372
- }, [raf]);
373
188
  }
374
-
375
- function $c9e8f80f5bb1841844f54e4ad30b$var$isElementInAnyScope(element) {
376
- for (let scope of $c9e8f80f5bb1841844f54e4ad30b$var$scopes.keys()) {
377
- if ($c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(element, scope.current)) {
378
- return true;
379
- }
380
- }
381
-
382
- return false;
189
+ const $0238e4b796d1715f$var$focusableElements = [
190
+ 'input:not([disabled]):not([type=hidden])',
191
+ 'select:not([disabled])',
192
+ 'textarea:not([disabled])',
193
+ 'button:not([disabled])',
194
+ 'a[href]',
195
+ 'area[href]',
196
+ 'summary',
197
+ 'iframe',
198
+ 'object',
199
+ 'embed',
200
+ 'audio[controls]',
201
+ 'video[controls]',
202
+ '[contenteditable]'
203
+ ];
204
+ const $0238e4b796d1715f$var$FOCUSABLE_ELEMENT_SELECTOR = $0238e4b796d1715f$var$focusableElements.join(':not([hidden]),') + ',[tabindex]:not([disabled]):not([hidden])';
205
+ $0238e4b796d1715f$var$focusableElements.push('[tabindex]:not([tabindex="-1"]):not([disabled])');
206
+ const $0238e4b796d1715f$var$TABBABLE_ELEMENT_SELECTOR = $0238e4b796d1715f$var$focusableElements.join(':not([hidden]):not([tabindex="-1"]),');
207
+ function $0238e4b796d1715f$var$getScopeRoot(scope) {
208
+ return scope[0].parentElement;
383
209
  }
384
-
385
- function $c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(element, scope) {
386
- return scope.some(node => node.contains(element));
210
+ function $0238e4b796d1715f$var$useFocusContainment(scopeRef, contain) {
211
+ let focusedNode = $bmn4K$useRef();
212
+ let raf = $bmn4K$useRef(null);
213
+ $bmn4K$useLayoutEffect(()=>{
214
+ let scope1 = scopeRef.current;
215
+ if (!contain) return;
216
+ // Handle the Tab key to contain focus within the scope
217
+ let onKeyDown = (e)=>{
218
+ if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey || scopeRef !== $0238e4b796d1715f$var$activeScope) return;
219
+ let focusedElement = document.activeElement;
220
+ let scope = scopeRef.current;
221
+ if (!$0238e4b796d1715f$var$isElementInScope(focusedElement, scope)) return;
222
+ let walker = $0238e4b796d1715f$export$2d6ec8fc375ceafa($0238e4b796d1715f$var$getScopeRoot(scope), {
223
+ tabbable: true
224
+ }, scope);
225
+ walker.currentNode = focusedElement;
226
+ let nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
227
+ if (!nextElement) {
228
+ walker.currentNode = e.shiftKey ? scope[scope.length - 1].nextElementSibling : scope[0].previousElementSibling;
229
+ nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
230
+ }
231
+ e.preventDefault();
232
+ if (nextElement) $0238e4b796d1715f$var$focusElement(nextElement, true);
233
+ };
234
+ let onFocus = (e)=>{
235
+ // If focusing an element in a child scope of the currently active scope, the child becomes active.
236
+ // Moving out of the active scope to an ancestor is not allowed.
237
+ if (!$0238e4b796d1715f$var$activeScope || $0238e4b796d1715f$var$isAncestorScope($0238e4b796d1715f$var$activeScope, scopeRef)) {
238
+ $0238e4b796d1715f$var$activeScope = scopeRef;
239
+ focusedNode.current = e.target;
240
+ } else if (scopeRef === $0238e4b796d1715f$var$activeScope && !$0238e4b796d1715f$var$isElementInChildScope(e.target, scopeRef)) {
241
+ // If a focus event occurs outside the active scope (e.g. user tabs from browser location bar),
242
+ // restore focus to the previously focused node or the first tabbable element in the active scope.
243
+ if (focusedNode.current) focusedNode.current.focus();
244
+ else if ($0238e4b796d1715f$var$activeScope) $0238e4b796d1715f$var$focusFirstInScope($0238e4b796d1715f$var$activeScope.current);
245
+ } else if (scopeRef === $0238e4b796d1715f$var$activeScope) focusedNode.current = e.target;
246
+ };
247
+ let onBlur = (e)=>{
248
+ // Firefox doesn't shift focus back to the Dialog properly without this
249
+ raf.current = requestAnimationFrame(()=>{
250
+ // Use document.activeElement instead of e.relatedTarget so we can tell if user clicked into iframe
251
+ if (scopeRef === $0238e4b796d1715f$var$activeScope && !$0238e4b796d1715f$var$isElementInChildScope(document.activeElement, scopeRef)) {
252
+ $0238e4b796d1715f$var$activeScope = scopeRef;
253
+ focusedNode.current = e.target;
254
+ focusedNode.current.focus();
255
+ }
256
+ });
257
+ };
258
+ document.addEventListener('keydown', onKeyDown, false);
259
+ document.addEventListener('focusin', onFocus, false);
260
+ scope1.forEach((element)=>element.addEventListener('focusin', onFocus, false)
261
+ );
262
+ scope1.forEach((element)=>element.addEventListener('focusout', onBlur, false)
263
+ );
264
+ return ()=>{
265
+ document.removeEventListener('keydown', onKeyDown, false);
266
+ document.removeEventListener('focusin', onFocus, false);
267
+ scope1.forEach((element)=>element.removeEventListener('focusin', onFocus, false)
268
+ );
269
+ scope1.forEach((element)=>element.removeEventListener('focusout', onBlur, false)
270
+ );
271
+ };
272
+ }, [
273
+ scopeRef,
274
+ contain
275
+ ]);
276
+ // eslint-disable-next-line arrow-body-style
277
+ $bmn4K$useEffect(()=>{
278
+ return ()=>cancelAnimationFrame(raf.current)
279
+ ;
280
+ }, [
281
+ raf
282
+ ]);
387
283
  }
388
-
389
- function $c9e8f80f5bb1841844f54e4ad30b$var$isElementInChildScope(element, scope) {
390
- // node.contains in isElementInScope covers child scopes that are also DOM children,
391
- // but does not cover child scopes in portals.
392
- for (let s of $c9e8f80f5bb1841844f54e4ad30b$var$scopes.keys()) {
393
- if ((s === scope || $c9e8f80f5bb1841844f54e4ad30b$var$isAncestorScope(scope, s)) && $c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(element, s.current)) {
394
- return true;
284
+ function $0238e4b796d1715f$var$isElementInAnyScope(element) {
285
+ for (let scope of $0238e4b796d1715f$var$scopes.keys()){
286
+ if ($0238e4b796d1715f$var$isElementInScope(element, scope.current)) return true;
395
287
  }
396
- }
397
-
398
- return false;
399
- }
400
-
401
- function $c9e8f80f5bb1841844f54e4ad30b$var$isAncestorScope(ancestor, scope) {
402
- let parent = $c9e8f80f5bb1841844f54e4ad30b$var$scopes.get(scope);
403
-
404
- if (!parent) {
405
288
  return false;
406
- }
407
-
408
- if (parent === ancestor) {
409
- return true;
410
- }
411
-
412
- return $c9e8f80f5bb1841844f54e4ad30b$var$isAncestorScope(ancestor, parent);
413
289
  }
414
-
415
- function $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(element, scroll) {
416
- if (scroll === void 0) {
417
- scroll = false;
418
- }
419
-
420
- if (element != null && !scroll) {
421
- try {
422
- focusSafely(element);
423
- } catch (err) {// ignore
424
- }
425
- } else if (element != null) {
426
- try {
427
- element.focus();
428
- } catch (err) {// ignore
290
+ function $0238e4b796d1715f$var$isElementInScope(element, scope) {
291
+ return scope.some((node)=>node.contains(element)
292
+ );
293
+ }
294
+ function $0238e4b796d1715f$var$isElementInChildScope(element, scope) {
295
+ // node.contains in isElementInScope covers child scopes that are also DOM children,
296
+ // but does not cover child scopes in portals.
297
+ for (let s of $0238e4b796d1715f$var$scopes.keys()){
298
+ if ((s === scope || $0238e4b796d1715f$var$isAncestorScope(scope, s)) && $0238e4b796d1715f$var$isElementInScope(element, s.current)) return true;
429
299
  }
430
- }
300
+ return false;
431
301
  }
432
-
433
- function $c9e8f80f5bb1841844f54e4ad30b$var$focusFirstInScope(scope) {
434
- let sentinel = scope[0].previousElementSibling;
435
- let walker = getFocusableTreeWalker($c9e8f80f5bb1841844f54e4ad30b$var$getScopeRoot(scope), {
436
- tabbable: true
437
- }, scope);
438
- walker.currentNode = sentinel;
439
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(walker.nextNode());
302
+ function $0238e4b796d1715f$var$isAncestorScope(ancestor, scope) {
303
+ let parent = $0238e4b796d1715f$var$scopes.get(scope);
304
+ if (!parent) return false;
305
+ if (parent === ancestor) return true;
306
+ return $0238e4b796d1715f$var$isAncestorScope(ancestor, parent);
440
307
  }
441
-
442
- function $c9e8f80f5bb1841844f54e4ad30b$var$useAutoFocus(scopeRef, autoFocus) {
443
- const autoFocusRef = _react.useRef(autoFocus);
444
-
445
- useEffect(() => {
446
- if (autoFocusRef.current) {
447
- $c9e8f80f5bb1841844f54e4ad30b$var$activeScope = scopeRef;
448
-
449
- if (!$c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(document.activeElement, $c9e8f80f5bb1841844f54e4ad30b$var$activeScope.current)) {
450
- $c9e8f80f5bb1841844f54e4ad30b$var$focusFirstInScope(scopeRef.current);
451
- }
308
+ function $0238e4b796d1715f$var$focusElement(element, scroll = false) {
309
+ if (element != null && !scroll) try {
310
+ $f2c1256fdcfd2c09$export$80f3e147d781571c(element);
311
+ } catch (err) {
312
+ // ignore
452
313
  }
453
-
454
- autoFocusRef.current = false;
455
- }, []);
456
- }
457
-
458
- function $c9e8f80f5bb1841844f54e4ad30b$var$useRestoreFocus(scopeRef, restoreFocus, contain) {
459
- // useLayoutEffect instead of useEffect so the active element is saved synchronously instead of asynchronously.
460
- useLayoutEffect(() => {
461
- if (!restoreFocus) {
462
- return;
314
+ else if (element != null) try {
315
+ element.focus();
316
+ } catch (err1) {
317
+ // ignore
463
318
  }
464
-
465
- let scope = scopeRef.current;
466
- let nodeToRestore = document.activeElement; // Handle the Tab key so that tabbing out of the scope goes to the next element
467
- // after the node that had focus when the scope mounted. This is important when
468
- // using portals for overlays, so that focus goes to the expected element when
469
- // tabbing out of the overlay.
470
-
471
- let onKeyDown = e => {
472
- if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey) {
473
- return;
474
- }
475
-
476
- let focusedElement = document.activeElement;
477
-
478
- if (!$c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(focusedElement, scope)) {
479
- return;
480
- } // Create a DOM tree walker that matches all tabbable elements
481
-
482
-
483
- let walker = getFocusableTreeWalker(document.body, {
319
+ }
320
+ function $0238e4b796d1715f$var$focusFirstInScope(scope) {
321
+ let sentinel = scope[0].previousElementSibling;
322
+ let walker = $0238e4b796d1715f$export$2d6ec8fc375ceafa($0238e4b796d1715f$var$getScopeRoot(scope), {
484
323
  tabbable: true
485
- }); // Find the next tabbable element after the currently focused element
486
-
487
- walker.currentNode = focusedElement;
488
- let nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
489
-
490
- if (!document.body.contains(nodeToRestore) || nodeToRestore === document.body) {
491
- nodeToRestore = null;
492
- } // If there is no next element, or it is outside the current scope, move focus to the
493
- // next element after the node to restore to instead.
494
-
495
-
496
- if ((!nextElement || !$c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(nextElement, scope)) && nodeToRestore) {
497
- walker.currentNode = nodeToRestore; // Skip over elements within the scope, in case the scope immediately follows the node to restore.
498
-
499
- do {
500
- nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
501
- } while ($c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(nextElement, scope));
502
-
503
- e.preventDefault();
504
- e.stopPropagation();
505
-
506
- if (nextElement) {
507
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(nextElement, true);
508
- } else {
509
- // If there is no next element and the nodeToRestore isn't within a FocusScope (i.e. we are leaving the top level focus scope)
510
- // then move focus to the body.
511
- // Otherwise restore focus to the nodeToRestore (e.g menu within a popover -> tabbing to close the menu should move focus to menu trigger)
512
- if (!$c9e8f80f5bb1841844f54e4ad30b$var$isElementInAnyScope(nodeToRestore)) {
513
- focusedElement.blur();
514
- } else {
515
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(nodeToRestore, true);
516
- }
324
+ }, scope);
325
+ walker.currentNode = sentinel;
326
+ $0238e4b796d1715f$var$focusElement(walker.nextNode());
327
+ }
328
+ function $0238e4b796d1715f$var$useAutoFocus(scopeRef, autoFocus) {
329
+ const autoFocusRef = $bmn4K$react.useRef(autoFocus);
330
+ $bmn4K$useEffect(()=>{
331
+ if (autoFocusRef.current) {
332
+ $0238e4b796d1715f$var$activeScope = scopeRef;
333
+ if (!$0238e4b796d1715f$var$isElementInScope(document.activeElement, $0238e4b796d1715f$var$activeScope.current)) $0238e4b796d1715f$var$focusFirstInScope(scopeRef.current);
334
+ }
335
+ autoFocusRef.current = false;
336
+ }, []);
337
+ }
338
+ function $0238e4b796d1715f$var$useRestoreFocus(scopeRef, restoreFocus, contain) {
339
+ // create a ref during render instead of useLayoutEffect so the active element is saved before a child with autoFocus=true mounts.
340
+ const nodeToRestoreRef = $bmn4K$useRef(typeof document !== 'undefined' ? document.activeElement : null);
341
+ // useLayoutEffect instead of useEffect so the active element is saved synchronously instead of asynchronously.
342
+ $bmn4K$useLayoutEffect(()=>{
343
+ let nodeToRestore = nodeToRestoreRef.current;
344
+ if (!restoreFocus) return;
345
+ // Handle the Tab key so that tabbing out of the scope goes to the next element
346
+ // after the node that had focus when the scope mounted. This is important when
347
+ // using portals for overlays, so that focus goes to the expected element when
348
+ // tabbing out of the overlay.
349
+ let onKeyDown = (e)=>{
350
+ if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey) return;
351
+ let focusedElement = document.activeElement;
352
+ if (!$0238e4b796d1715f$var$isElementInScope(focusedElement, scopeRef.current)) return;
353
+ // Create a DOM tree walker that matches all tabbable elements
354
+ let walker = $0238e4b796d1715f$export$2d6ec8fc375ceafa(document.body, {
355
+ tabbable: true
356
+ });
357
+ // Find the next tabbable element after the currently focused element
358
+ walker.currentNode = focusedElement;
359
+ let nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
360
+ if (!document.body.contains(nodeToRestore) || nodeToRestore === document.body) nodeToRestore = null;
361
+ // If there is no next element, or it is outside the current scope, move focus to the
362
+ // next element after the node to restore to instead.
363
+ if ((!nextElement || !$0238e4b796d1715f$var$isElementInScope(nextElement, scopeRef.current)) && nodeToRestore) {
364
+ walker.currentNode = nodeToRestore;
365
+ // Skip over elements within the scope, in case the scope immediately follows the node to restore.
366
+ do nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
367
+ while ($0238e4b796d1715f$var$isElementInScope(nextElement, scopeRef.current))
368
+ e.preventDefault();
369
+ e.stopPropagation();
370
+ if (nextElement) $0238e4b796d1715f$var$focusElement(nextElement, true);
371
+ else // If there is no next element and the nodeToRestore isn't within a FocusScope (i.e. we are leaving the top level focus scope)
372
+ // then move focus to the body.
373
+ // Otherwise restore focus to the nodeToRestore (e.g menu within a popover -> tabbing to close the menu should move focus to menu trigger)
374
+ if (!$0238e4b796d1715f$var$isElementInAnyScope(nodeToRestore)) focusedElement.blur();
375
+ else $0238e4b796d1715f$var$focusElement(nodeToRestore, true);
376
+ }
377
+ };
378
+ if (!contain) document.addEventListener('keydown', onKeyDown, true);
379
+ return ()=>{
380
+ if (!contain) document.removeEventListener('keydown', onKeyDown, true);
381
+ if (restoreFocus && nodeToRestore && $0238e4b796d1715f$var$isElementInScope(document.activeElement, scopeRef.current)) requestAnimationFrame(()=>{
382
+ if (document.body.contains(nodeToRestore)) $0238e4b796d1715f$var$focusElement(nodeToRestore);
383
+ });
384
+ };
385
+ }, [
386
+ scopeRef,
387
+ restoreFocus,
388
+ contain
389
+ ]);
390
+ }
391
+ function $0238e4b796d1715f$export$2d6ec8fc375ceafa(root, opts, scope) {
392
+ let selector = opts?.tabbable ? $0238e4b796d1715f$var$TABBABLE_ELEMENT_SELECTOR : $0238e4b796d1715f$var$FOCUSABLE_ELEMENT_SELECTOR;
393
+ let walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
394
+ acceptNode (node) {
395
+ // Skip nodes inside the starting node.
396
+ if (opts?.from?.contains(node)) return NodeFilter.FILTER_REJECT;
397
+ if (node.matches(selector) && $c5775c2d6be42e6d$export$e989c0fffaa6b27a(node) && (!scope || $0238e4b796d1715f$var$isElementInScope(node, scope))) return NodeFilter.FILTER_ACCEPT;
398
+ return NodeFilter.FILTER_SKIP;
399
+ }
400
+ });
401
+ if (opts?.from) walker.currentNode = opts.from;
402
+ return walker;
403
+ }
404
+ function $0238e4b796d1715f$export$c5251b9e124bf29(ref) {
405
+ return {
406
+ focusNext (opts = {
407
+ }) {
408
+ let root = ref.current;
409
+ let { from: from , tabbable: tabbable , wrap: wrap } = opts;
410
+ let node = from || document.activeElement;
411
+ let walker = $0238e4b796d1715f$export$2d6ec8fc375ceafa(root, {
412
+ tabbable: tabbable
413
+ });
414
+ if (root.contains(node)) walker.currentNode = node;
415
+ let nextNode = walker.nextNode();
416
+ if (!nextNode && wrap) {
417
+ walker.currentNode = root;
418
+ nextNode = walker.nextNode();
419
+ }
420
+ if (nextNode) $0238e4b796d1715f$var$focusElement(nextNode, true);
421
+ return nextNode;
422
+ },
423
+ focusPrevious (opts = {
424
+ }) {
425
+ let root = ref.current;
426
+ let { from: from , tabbable: tabbable , wrap: wrap } = opts;
427
+ let node = from || document.activeElement;
428
+ let walker = $0238e4b796d1715f$export$2d6ec8fc375ceafa(root, {
429
+ tabbable: tabbable
430
+ });
431
+ if (root.contains(node)) walker.currentNode = node;
432
+ else {
433
+ let next = $0238e4b796d1715f$var$last(walker);
434
+ if (next) $0238e4b796d1715f$var$focusElement(next, true);
435
+ return next;
436
+ }
437
+ let previousNode = walker.previousNode();
438
+ if (!previousNode && wrap) {
439
+ walker.currentNode = root;
440
+ previousNode = $0238e4b796d1715f$var$last(walker);
441
+ }
442
+ if (previousNode) $0238e4b796d1715f$var$focusElement(previousNode, true);
443
+ return previousNode;
444
+ },
445
+ focusFirst (opts = {
446
+ }) {
447
+ let root = ref.current;
448
+ let { tabbable: tabbable } = opts;
449
+ let walker = $0238e4b796d1715f$export$2d6ec8fc375ceafa(root, {
450
+ tabbable: tabbable
451
+ });
452
+ let nextNode = walker.nextNode();
453
+ if (nextNode) $0238e4b796d1715f$var$focusElement(nextNode, true);
454
+ return nextNode;
455
+ },
456
+ focusLast (opts = {
457
+ }) {
458
+ let root = ref.current;
459
+ let { tabbable: tabbable } = opts;
460
+ let walker = $0238e4b796d1715f$export$2d6ec8fc375ceafa(root, {
461
+ tabbable: tabbable
462
+ });
463
+ let next = $0238e4b796d1715f$var$last(walker);
464
+ if (next) $0238e4b796d1715f$var$focusElement(next, true);
465
+ return next;
517
466
  }
518
- }
519
- };
520
-
521
- if (!contain) {
522
- document.addEventListener('keydown', onKeyDown, true);
523
- }
524
-
525
- return () => {
526
- if (!contain) {
527
- document.removeEventListener('keydown', onKeyDown, true);
528
- }
529
-
530
- if (restoreFocus && nodeToRestore && $c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(document.activeElement, scope)) {
531
- requestAnimationFrame(() => {
532
- if (document.body.contains(nodeToRestore)) {
533
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(nodeToRestore);
534
- }
535
- });
536
- }
537
467
  };
538
- }, [scopeRef, restoreFocus, contain]);
539
468
  }
540
- /**
541
- * Create a [TreeWalker]{@link https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker}
542
- * that matches all focusable/tabbable elements.
543
- */
469
+ function $0238e4b796d1715f$var$last(walker) {
470
+ let next;
471
+ let last;
472
+ do {
473
+ last = walker.lastChild();
474
+ if (last) next = last;
475
+ }while (last)
476
+ return next;
477
+ }
544
478
 
545
479
 
546
- export function getFocusableTreeWalker(root, opts, scope) {
547
- let selector = opts != null && opts.tabbable ? $c9e8f80f5bb1841844f54e4ad30b$var$TABBABLE_ELEMENT_SELECTOR : $c9e8f80f5bb1841844f54e4ad30b$var$FOCUSABLE_ELEMENT_SELECTOR;
548
- let walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
549
- acceptNode(node) {
550
- var _opts$from;
480
+ var $db88f84346fe3322$exports = {};
551
481
 
552
- // Skip nodes inside the starting node.
553
- if (opts != null && (_opts$from = opts.from) != null && _opts$from.contains(node)) {
554
- return NodeFilter.FILTER_REJECT;
555
- }
482
+ $parcel$export($db88f84346fe3322$exports, "FocusRing", () => $db88f84346fe3322$export$1a38b4ad7f578e1d);
556
483
 
557
- if (node.matches(selector) && $ee5e90cbb4a22466973155c14222fa1$export$isElementVisible(node) && (!scope || $c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(node, scope))) {
558
- return NodeFilter.FILTER_ACCEPT;
559
- }
560
484
 
561
- return NodeFilter.FILTER_SKIP;
562
- }
563
485
 
564
- });
486
+ var $e974583017b16a4e$exports = {};
565
487
 
566
- if (opts != null && opts.from) {
567
- walker.currentNode = opts.from;
568
- }
488
+ $parcel$export($e974583017b16a4e$exports, "useFocusRing", () => $e974583017b16a4e$export$4e328f61c538687f);
569
489
 
570
- return walker;
571
- }
572
- /**
573
- * Creates a FocusManager object that can be used to move focus within an element.
574
- */
575
-
576
- export function createFocusManager(ref) {
577
- return {
578
- focusNext(opts) {
579
- if (opts === void 0) {
580
- opts = {};
581
- }
582
-
583
- let root = ref.current;
584
- let {
585
- from,
586
- tabbable,
587
- wrap
588
- } = opts;
589
- let node = from || document.activeElement;
590
- let walker = getFocusableTreeWalker(root, {
591
- tabbable
592
- });
593
-
594
- if (root.contains(node)) {
595
- walker.currentNode = node;
596
- }
597
-
598
- let nextNode = walker.nextNode();
599
-
600
- if (!nextNode && wrap) {
601
- walker.currentNode = root;
602
- nextNode = walker.nextNode();
603
- }
604
-
605
- if (nextNode) {
606
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(nextNode, true);
607
- }
608
-
609
- return nextNode;
610
- },
611
-
612
- focusPrevious(opts) {
613
- if (opts === void 0) {
614
- opts = {};
615
- }
616
-
617
- let root = ref.current;
618
- let {
619
- from,
620
- tabbable,
621
- wrap
622
- } = opts;
623
- let node = from || document.activeElement;
624
- let walker = getFocusableTreeWalker(root, {
625
- tabbable
626
- });
627
-
628
- if (root.contains(node)) {
629
- walker.currentNode = node;
630
- } else {
631
- let next = $c9e8f80f5bb1841844f54e4ad30b$var$last(walker);
632
-
633
- if (next) {
634
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(next, true);
635
- }
636
490
 
637
- return next;
638
- }
639
-
640
- let previousNode = walker.previousNode();
641
-
642
- if (!previousNode && wrap) {
643
- walker.currentNode = root;
644
- previousNode = $c9e8f80f5bb1841844f54e4ad30b$var$last(walker);
645
- }
646
-
647
- if (previousNode) {
648
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(previousNode, true);
649
- }
650
-
651
- return previousNode;
652
- },
653
-
654
- focusFirst(opts) {
655
- if (opts === void 0) {
656
- opts = {};
657
- }
658
-
659
- let root = ref.current;
660
- let {
661
- tabbable
662
- } = opts;
663
- let walker = getFocusableTreeWalker(root, {
664
- tabbable
665
- });
666
- let nextNode = walker.nextNode();
667
-
668
- if (nextNode) {
669
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(nextNode, true);
670
- }
671
-
672
- return nextNode;
673
- },
674
-
675
- focusLast(opts) {
676
- if (opts === void 0) {
677
- opts = {};
678
- }
679
-
680
- let root = ref.current;
681
- let {
682
- tabbable
683
- } = opts;
684
- let walker = getFocusableTreeWalker(root, {
685
- tabbable
686
- });
687
- let next = $c9e8f80f5bb1841844f54e4ad30b$var$last(walker);
688
-
689
- if (next) {
690
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(next, true);
691
- }
692
-
693
- return next;
694
- }
695
491
 
696
- };
492
+ function $e974583017b16a4e$export$4e328f61c538687f(props = {
493
+ }) {
494
+ let { autoFocus: autoFocus = false , isTextInput: isTextInput , within: within } = props;
495
+ let state = $bmn4K$useRef({
496
+ isFocused: false,
497
+ isFocusVisible: autoFocus || $bmn4K$isFocusVisible()
498
+ }).current;
499
+ let [isFocused1, setFocused] = $bmn4K$useState(false);
500
+ let [isFocusVisibleState, setFocusVisible] = $bmn4K$useState(()=>state.isFocused && state.isFocusVisible
501
+ );
502
+ let updateState = ()=>setFocusVisible(state.isFocused && state.isFocusVisible)
503
+ ;
504
+ let onFocusChange = (isFocused)=>{
505
+ state.isFocused = isFocused;
506
+ setFocused(isFocused);
507
+ updateState();
508
+ };
509
+ $bmn4K$useFocusVisibleListener((isFocusVisible)=>{
510
+ state.isFocusVisible = isFocusVisible;
511
+ updateState();
512
+ }, [], {
513
+ isTextInput: isTextInput
514
+ });
515
+ let { focusProps: focusProps } = $bmn4K$useFocus({
516
+ isDisabled: within,
517
+ onFocusChange: onFocusChange
518
+ });
519
+ let { focusWithinProps: focusWithinProps } = $bmn4K$useFocusWithin({
520
+ isDisabled: !within,
521
+ onFocusWithinChange: onFocusChange
522
+ });
523
+ return {
524
+ isFocused: isFocused1,
525
+ isFocusVisible: state.isFocused && isFocusVisibleState,
526
+ focusProps: within ? focusWithinProps : focusProps
527
+ };
697
528
  }
698
529
 
699
- function $c9e8f80f5bb1841844f54e4ad30b$var$last(walker) {
700
- let next;
701
- let last;
702
-
703
- do {
704
- last = walker.lastChild();
705
-
706
- if (last) {
707
- next = last;
708
- }
709
- } while (last);
710
530
 
711
- return next;
531
+ function $db88f84346fe3322$export$1a38b4ad7f578e1d(props) {
532
+ let { children: children , focusClass: focusClass , focusRingClass: focusRingClass } = props;
533
+ let { isFocused: isFocused , isFocusVisible: isFocusVisible , focusProps: focusProps } = $e974583017b16a4e$export$4e328f61c538687f(props);
534
+ let child = $bmn4K$react.Children.only(children);
535
+ return(/*#__PURE__*/ $bmn4K$react.cloneElement(child, $bmn4K$mergeProps(child.props, {
536
+ ...focusProps,
537
+ className: $bmn4K$clsx({
538
+ [focusClass || '']: isFocused,
539
+ [focusRingClass || '']: isFocusVisible
540
+ })
541
+ })));
712
542
  }
713
543
 
714
- /**
715
- * Determines whether a focus ring should be shown to indicate keyboard focus.
716
- * Focus rings are visible only when the user is interacting with a keyboard,
717
- * not with a mouse, touch, or other input methods.
718
- */
719
- export function useFocusRing(props) {
720
- if (props === void 0) {
721
- props = {};
722
- }
723
-
724
- let {
725
- autoFocus = false,
726
- isTextInput,
727
- within
728
- } = props;
729
- let state = useRef({
730
- isFocused: false,
731
- isFocusVisible: autoFocus || _isFocusVisible()
732
- }).current;
733
- let [isFocused, setFocused] = useState(false);
734
- let [isFocusVisibleState, setFocusVisible] = useState(() => state.isFocused && state.isFocusVisible);
735
-
736
- let updateState = () => setFocusVisible(state.isFocused && state.isFocusVisible);
737
-
738
- let onFocusChange = isFocused => {
739
- state.isFocused = isFocused;
740
- setFocused(isFocused);
741
- updateState();
742
- };
743
-
744
- useFocusVisibleListener(isFocusVisible => {
745
- state.isFocusVisible = isFocusVisible;
746
- updateState();
747
- }, [], {
748
- isTextInput
749
- });
750
- let {
751
- focusProps
752
- } = useFocus({
753
- isDisabled: within,
754
- onFocusChange
755
- });
756
- let {
757
- focusWithinProps
758
- } = useFocusWithin({
759
- isDisabled: !within,
760
- onFocusWithinChange: onFocusChange
761
- });
762
- return {
763
- isFocused,
764
- isFocusVisible: state.isFocused && isFocusVisibleState,
765
- focusProps: within ? focusWithinProps : focusProps
766
- };
767
- }
768
544
 
769
- /**
770
- * A utility component that applies a CSS class when an element has keyboard focus.
771
- * Focus rings are visible only when the user is interacting with a keyboard,
772
- * not with a mouse, touch, or other input methods.
773
- */
774
- export function FocusRing(props) {
775
- let {
776
- children,
777
- focusClass,
778
- focusRingClass
779
- } = props;
780
- let {
781
- isFocused,
782
- isFocusVisible,
783
- focusProps
784
- } = useFocusRing(props);
785
-
786
- let child = _react.Children.only(children);
787
-
788
- return /*#__PURE__*/_react.cloneElement(child, mergeProps(child.props, _babelRuntimeHelpersEsmExtends({}, focusProps, {
789
- className: _clsx({
790
- [focusClass || '']: isFocused,
791
- [focusRingClass || '']: isFocusVisible
792
- })
793
- })));
794
- }
545
+ var $e82d8245213b3ebf$exports = {};
795
546
 
796
- let $e11539c8317b2d21639df611cb5658f$var$FocusableContext = /*#__PURE__*/_react.createContext(null);
547
+ $parcel$export($e82d8245213b3ebf$exports, "FocusableProvider", () => $e82d8245213b3ebf$export$13f3202a3e5ddd5);
548
+ $parcel$export($e82d8245213b3ebf$exports, "useFocusable", () => $e82d8245213b3ebf$export$4c014de7c8940b4c);
797
549
 
798
- function $e11539c8317b2d21639df611cb5658f$var$useFocusableContext(ref) {
799
- let context = useContext($e11539c8317b2d21639df611cb5658f$var$FocusableContext) || {};
800
- useSyncRef(context, ref); // eslint-disable-next-line
801
550
 
802
- let otherProps = _babelRuntimeHelpersEsmObjectWithoutPropertiesLoose(context, ["ref"]);
803
551
 
804
- return otherProps;
552
+ let $e82d8245213b3ebf$var$FocusableContext = /*#__PURE__*/ $bmn4K$react.createContext(null);
553
+ function $e82d8245213b3ebf$var$useFocusableContext(ref) {
554
+ let context = $bmn4K$useContext($e82d8245213b3ebf$var$FocusableContext) || {
555
+ };
556
+ $bmn4K$useSyncRef(context, ref);
557
+ // eslint-disable-next-line
558
+ let { ref: _ , ...otherProps } = context;
559
+ return otherProps;
805
560
  }
806
561
  /**
807
562
  * Provides DOM props to the nearest focusable child.
808
- */
809
-
563
+ */ function $e82d8245213b3ebf$var$FocusableProvider(props, ref) {
564
+ let { children: children , ...otherProps } = props;
565
+ let context = {
566
+ ...otherProps,
567
+ ref: ref
568
+ };
569
+ return(/*#__PURE__*/ $bmn4K$react.createElement($e82d8245213b3ebf$var$FocusableContext.Provider, {
570
+ value: context
571
+ }, children));
572
+ }
573
+ let $e82d8245213b3ebf$export$13f3202a3e5ddd5 = /*#__PURE__*/ $bmn4K$react.forwardRef($e82d8245213b3ebf$var$FocusableProvider);
574
+ function $e82d8245213b3ebf$export$4c014de7c8940b4c(props, domRef) {
575
+ let { focusProps: focusProps } = $bmn4K$useFocus(props);
576
+ let { keyboardProps: keyboardProps } = $bmn4K$useKeyboard(props);
577
+ let interactions = $bmn4K$mergeProps(focusProps, keyboardProps);
578
+ let domProps = $e82d8245213b3ebf$var$useFocusableContext(domRef);
579
+ let interactionProps = props.isDisabled ? {
580
+ } : domProps;
581
+ let autoFocusRef = $bmn4K$useRef(props.autoFocus);
582
+ $bmn4K$useEffect(()=>{
583
+ if (autoFocusRef.current && domRef.current) domRef.current.focus();
584
+ autoFocusRef.current = false;
585
+ }, []);
586
+ return {
587
+ focusableProps: $bmn4K$mergeProps({
588
+ ...interactions,
589
+ tabIndex: props.excludeFromTabOrder && !props.isDisabled ? -1 : undefined
590
+ }, interactionProps)
591
+ };
592
+ }
810
593
 
811
- function $e11539c8317b2d21639df611cb5658f$var$FocusableProvider(props, ref) {
812
- let {
813
- children
814
- } = props,
815
- otherProps = _babelRuntimeHelpersEsmObjectWithoutPropertiesLoose(props, ["children"]);
816
594
 
817
- let context = _babelRuntimeHelpersEsmExtends({}, otherProps, {
818
- ref
819
- });
820
595
 
821
- return /*#__PURE__*/_react.createElement($e11539c8317b2d21639df611cb5658f$var$FocusableContext.Provider, {
822
- value: context
823
- }, children);
824
- }
825
596
 
826
- export let FocusableProvider = /*#__PURE__*/_react.forwardRef($e11539c8317b2d21639df611cb5658f$var$FocusableProvider);
827
597
 
828
- /**
829
- * Used to make an element focusable and capable of auto focus.
830
- */
831
- export function useFocusable(props, domRef) {
832
- let {
833
- focusProps
834
- } = useFocus(props);
835
- let {
836
- keyboardProps
837
- } = useKeyboard(props);
838
- let interactions = mergeProps(focusProps, keyboardProps);
839
- let domProps = $e11539c8317b2d21639df611cb5658f$var$useFocusableContext(domRef);
840
- let interactionProps = props.isDisabled ? {} : domProps;
841
- let autoFocusRef = useRef(props.autoFocus);
842
- useEffect(() => {
843
- if (autoFocusRef.current && domRef.current) {
844
- domRef.current.focus();
845
- }
846
598
 
847
- autoFocusRef.current = false;
848
- }, []);
849
- return {
850
- focusableProps: mergeProps(_babelRuntimeHelpersEsmExtends({}, interactions, {
851
- tabIndex: props.excludeFromTabOrder && !props.isDisabled ? -1 : undefined
852
- }), interactionProps)
853
- };
854
- }
599
+ export {$0238e4b796d1715f$export$20e40289641fbbb6 as FocusScope, $0238e4b796d1715f$export$10c5169755ce7bd7 as useFocusManager, $0238e4b796d1715f$export$2d6ec8fc375ceafa as getFocusableTreeWalker, $0238e4b796d1715f$export$c5251b9e124bf29 as createFocusManager, $db88f84346fe3322$export$1a38b4ad7f578e1d as FocusRing, $e82d8245213b3ebf$export$13f3202a3e5ddd5 as FocusableProvider, $e82d8245213b3ebf$export$4c014de7c8940b4c as useFocusable, $e974583017b16a4e$export$4e328f61c538687f as useFocusRing, $f2c1256fdcfd2c09$export$80f3e147d781571c as focusSafely};
855
600
  //# sourceMappingURL=module.js.map