@react-aria/focus 3.4.0 → 3.5.2

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 $6saFI$react, {useRef as $6saFI$useRef, useContext as $6saFI$useContext, useEffect as $6saFI$useEffect, useState as $6saFI$useState} from "react";
2
+ import {useLayoutEffect as $6saFI$useLayoutEffect, runAfterTransition as $6saFI$runAfterTransition, focusWithoutScrolling as $6saFI$focusWithoutScrolling, mergeProps as $6saFI$mergeProps, useSyncRef as $6saFI$useSyncRef} from "@react-aria/utils";
3
+ import {getInteractionModality as $6saFI$getInteractionModality, isFocusVisible as $6saFI$isFocusVisible, useFocusVisibleListener as $6saFI$useFocusVisibleListener, useFocus as $6saFI$useFocus, useFocusWithin as $6saFI$useFocusWithin, useKeyboard as $6saFI$useKeyboard} from "@react-aria/interactions";
4
+ import $6saFI$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 $14e5c84cbc2e6e2e$exports = {};
10
+
11
+ $parcel$export($14e5c84cbc2e6e2e$exports, "FocusScope", () => $14e5c84cbc2e6e2e$export$20e40289641fbbb6);
12
+ $parcel$export($14e5c84cbc2e6e2e$exports, "useFocusManager", () => $14e5c84cbc2e6e2e$export$10c5169755ce7bd7);
13
+ $parcel$export($14e5c84cbc2e6e2e$exports, "getFocusableTreeWalker", () => $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa);
14
+ $parcel$export($14e5c84cbc2e6e2e$exports, "createFocusManager", () => $14e5c84cbc2e6e2e$export$c5251b9e124bf29);
15
+ var $1159c3b6ba210e4f$exports = {};
16
+
17
+ $parcel$export($1159c3b6ba210e4f$exports, "focusSafely", () => $1159c3b6ba210e4f$export$80f3e147d781571c);
18
+
19
+
20
+ function $1159c3b6ba210e4f$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 ($6saFI$getInteractionModality() === 'virtual') {
27
+ let lastFocusedElement = document.activeElement;
28
+ $6saFI$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)) $6saFI$focusWithoutScrolling(element);
31
+ });
32
+ } else $6saFI$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,665 +43,560 @@ 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;
46
+ */ function $985a2847ebcbb615$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';
54
+ }
55
+ return isVisible;
65
56
  }
66
-
67
- function $ee5e90cbb4a22466973155c14222fa1$var$isAttributeVisible(element, childElement) {
68
- return !element.hasAttribute('hidden') && (element.nodeName === 'DETAILS' && childElement && childElement.nodeName !== 'SUMMARY' ? element.hasAttribute('open') : true);
57
+ function $985a2847ebcbb615$var$isAttributeVisible(element, childElement) {
58
+ return !element.hasAttribute('hidden') && (element.nodeName === 'DETAILS' && childElement && childElement.nodeName !== 'SUMMARY' ? element.hasAttribute('open') : true);
69
59
  }
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));
60
+ function $985a2847ebcbb615$export$e989c0fffaa6b27a(element, childElement) {
61
+ return element.nodeName !== '#comment' && $985a2847ebcbb615$var$isStyleVisible(element) && $985a2847ebcbb615$var$isAttributeVisible(element, childElement) && (!element.parentElement || $985a2847ebcbb615$export$e989c0fffaa6b27a(element.parentElement, element));
80
62
  }
81
63
 
82
- const $c9e8f80f5bb1841844f54e4ad30b$var$FocusContext = /*#__PURE__*/_react.createContext(null);
83
64
 
84
- let $c9e8f80f5bb1841844f54e4ad30b$var$activeScope = null;
85
- let $c9e8f80f5bb1841844f54e4ad30b$var$scopes = new Set(); // 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
65
 
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
- useLayoutEffect(() => {
109
- // Find all rendered nodes between the sentinels and add them to the scope.
110
- let node = startRef.current.nextSibling;
111
- let nodes = [];
112
-
113
- while (node && node !== endRef.current) {
114
- nodes.push(node);
115
- node = node.nextSibling;
116
- }
117
66
 
118
- scopeRef.current = nodes;
119
- $c9e8f80f5bb1841844f54e4ad30b$var$scopes.add(scopeRef);
120
- return () => {
121
- $c9e8f80f5bb1841844f54e4ad30b$var$scopes.delete(scopeRef);
67
+ const $14e5c84cbc2e6e2e$var$FocusContext = /*#__PURE__*/ $6saFI$react.createContext(null);
68
+ let $14e5c84cbc2e6e2e$var$activeScope = null;
69
+ let $14e5c84cbc2e6e2e$var$scopes = new Map();
70
+ function $14e5c84cbc2e6e2e$export$20e40289641fbbb6(props) {
71
+ let { children: children , contain: contain , restoreFocus: restoreFocus , autoFocus: autoFocus } = props;
72
+ let startRef = $6saFI$useRef();
73
+ let endRef = $6saFI$useRef();
74
+ let scopeRef = $6saFI$useRef([]);
75
+ let ctx = $6saFI$useContext($14e5c84cbc2e6e2e$var$FocusContext);
76
+ let parentScope = ctx === null || ctx === void 0 ? void 0 : ctx.scopeRef;
77
+ $6saFI$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;
84
+ }
85
+ scopeRef.current = nodes;
86
+ }, [
87
+ children,
88
+ parentScope
89
+ ]);
90
+ $6saFI$useLayoutEffect(()=>{
91
+ $14e5c84cbc2e6e2e$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 === $14e5c84cbc2e6e2e$var$activeScope || $14e5c84cbc2e6e2e$var$isAncestorScope(scopeRef, $14e5c84cbc2e6e2e$var$activeScope)) && (!parentScope || $14e5c84cbc2e6e2e$var$scopes.has(parentScope))) $14e5c84cbc2e6e2e$var$activeScope = parentScope;
97
+ $14e5c84cbc2e6e2e$var$scopes.delete(scopeRef);
98
+ };
99
+ }, [
100
+ scopeRef,
101
+ parentScope
102
+ ]);
103
+ $14e5c84cbc2e6e2e$var$useFocusContainment(scopeRef, contain);
104
+ $14e5c84cbc2e6e2e$var$useRestoreFocus(scopeRef, restoreFocus, contain);
105
+ $14e5c84cbc2e6e2e$var$useAutoFocus(scopeRef, autoFocus);
106
+ let focusManager = $14e5c84cbc2e6e2e$var$createFocusManagerForScope(scopeRef);
107
+ return(/*#__PURE__*/ $6saFI$react.createElement($14e5c84cbc2e6e2e$var$FocusContext.Provider, {
108
+ value: {
109
+ scopeRef: scopeRef,
110
+ focusManager: focusManager
111
+ }
112
+ }, /*#__PURE__*/ $6saFI$react.createElement("span", {
113
+ "data-focus-scope-start": true,
114
+ hidden: true,
115
+ ref: startRef
116
+ }), children, /*#__PURE__*/ $6saFI$react.createElement("span", {
117
+ "data-focus-scope-end": true,
118
+ hidden: true,
119
+ ref: endRef
120
+ })));
121
+ }
122
+ function $14e5c84cbc2e6e2e$export$10c5169755ce7bd7() {
123
+ var ref;
124
+ return (ref = $6saFI$useContext($14e5c84cbc2e6e2e$var$FocusContext)) === null || ref === void 0 ? void 0 : ref.focusManager;
125
+ }
126
+ function $14e5c84cbc2e6e2e$var$createFocusManagerForScope(scopeRef) {
127
+ return {
128
+ focusNext (opts = {
129
+ }) {
130
+ let scope = scopeRef.current;
131
+ let { from: from , tabbable: tabbable , wrap: wrap } = opts;
132
+ let node = from || document.activeElement;
133
+ let sentinel = scope[0].previousElementSibling;
134
+ let walker = $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa($14e5c84cbc2e6e2e$var$getScopeRoot(scope), {
135
+ tabbable: tabbable
136
+ }, scope);
137
+ walker.currentNode = $14e5c84cbc2e6e2e$var$isElementInScope(node, scope) ? node : sentinel;
138
+ let nextNode = walker.nextNode();
139
+ if (!nextNode && wrap) {
140
+ walker.currentNode = sentinel;
141
+ nextNode = walker.nextNode();
142
+ }
143
+ if (nextNode) $14e5c84cbc2e6e2e$var$focusElement(nextNode, true);
144
+ return nextNode;
145
+ },
146
+ focusPrevious (opts = {
147
+ }) {
148
+ let scope = scopeRef.current;
149
+ let { from: from , tabbable: tabbable , wrap: wrap } = opts;
150
+ let node = from || document.activeElement;
151
+ let sentinel = scope[scope.length - 1].nextElementSibling;
152
+ let walker = $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa($14e5c84cbc2e6e2e$var$getScopeRoot(scope), {
153
+ tabbable: tabbable
154
+ }, scope);
155
+ walker.currentNode = $14e5c84cbc2e6e2e$var$isElementInScope(node, scope) ? node : sentinel;
156
+ let previousNode = walker.previousNode();
157
+ if (!previousNode && wrap) {
158
+ walker.currentNode = sentinel;
159
+ previousNode = walker.previousNode();
160
+ }
161
+ if (previousNode) $14e5c84cbc2e6e2e$var$focusElement(previousNode, true);
162
+ return previousNode;
163
+ },
164
+ focusFirst (opts = {
165
+ }) {
166
+ let scope = scopeRef.current;
167
+ let { tabbable: tabbable } = opts;
168
+ let walker = $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa($14e5c84cbc2e6e2e$var$getScopeRoot(scope), {
169
+ tabbable: tabbable
170
+ }, scope);
171
+ walker.currentNode = scope[0].previousElementSibling;
172
+ let nextNode = walker.nextNode();
173
+ if (nextNode) $14e5c84cbc2e6e2e$var$focusElement(nextNode, true);
174
+ return nextNode;
175
+ },
176
+ focusLast (opts = {
177
+ }) {
178
+ let scope = scopeRef.current;
179
+ let { tabbable: tabbable } = opts;
180
+ let walker = $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa($14e5c84cbc2e6e2e$var$getScopeRoot(scope), {
181
+ tabbable: tabbable
182
+ }, scope);
183
+ walker.currentNode = scope[scope.length - 1].nextElementSibling;
184
+ let previousNode = walker.previousNode();
185
+ if (previousNode) $14e5c84cbc2e6e2e$var$focusElement(previousNode, true);
186
+ return previousNode;
187
+ }
122
188
  };
123
- }, [children]);
124
- $c9e8f80f5bb1841844f54e4ad30b$var$useFocusContainment(scopeRef, contain);
125
- $c9e8f80f5bb1841844f54e4ad30b$var$useRestoreFocus(scopeRef, restoreFocus, contain);
126
- $c9e8f80f5bb1841844f54e4ad30b$var$useAutoFocus(scopeRef, autoFocus);
127
- let focusManager = $c9e8f80f5bb1841844f54e4ad30b$var$createFocusManagerForScope(scopeRef);
128
- return /*#__PURE__*/_react.createElement($c9e8f80f5bb1841844f54e4ad30b$var$FocusContext.Provider, {
129
- value: focusManager
130
- }, /*#__PURE__*/_react.createElement("span", {
131
- hidden: true,
132
- ref: startRef
133
- }), children, /*#__PURE__*/_react.createElement("span", {
134
- hidden: true,
135
- ref: endRef
136
- }));
137
189
  }
138
- /**
139
- * Returns a FocusManager interface for the parent FocusScope.
140
- * A FocusManager can be used to programmatically move focus within
141
- * a FocusScope, e.g. in response to user events like keyboard navigation.
142
- */
143
-
144
- export function useFocusManager() {
145
- return useContext($c9e8f80f5bb1841844f54e4ad30b$var$FocusContext);
190
+ const $14e5c84cbc2e6e2e$var$focusableElements = [
191
+ 'input:not([disabled]):not([type=hidden])',
192
+ 'select:not([disabled])',
193
+ 'textarea:not([disabled])',
194
+ 'button:not([disabled])',
195
+ 'a[href]',
196
+ 'area[href]',
197
+ 'summary',
198
+ 'iframe',
199
+ 'object',
200
+ 'embed',
201
+ 'audio[controls]',
202
+ 'video[controls]',
203
+ '[contenteditable]'
204
+ ];
205
+ const $14e5c84cbc2e6e2e$var$FOCUSABLE_ELEMENT_SELECTOR = $14e5c84cbc2e6e2e$var$focusableElements.join(':not([hidden]),') + ',[tabindex]:not([disabled]):not([hidden])';
206
+ $14e5c84cbc2e6e2e$var$focusableElements.push('[tabindex]:not([tabindex="-1"]):not([disabled])');
207
+ const $14e5c84cbc2e6e2e$var$TABBABLE_ELEMENT_SELECTOR = $14e5c84cbc2e6e2e$var$focusableElements.join(':not([hidden]):not([tabindex="-1"]),');
208
+ function $14e5c84cbc2e6e2e$var$getScopeRoot(scope) {
209
+ return scope[0].parentElement;
146
210
  }
147
-
148
- function $c9e8f80f5bb1841844f54e4ad30b$var$createFocusManagerForScope(scopeRef) {
149
- return {
150
- focusNext(opts) {
151
- if (opts === void 0) {
152
- opts = {};
153
- }
154
-
155
- let scope = scopeRef.current;
156
- let {
157
- from,
158
- tabbable,
159
- wrap
160
- } = opts;
161
- let node = from || document.activeElement;
162
- let sentinel = scope[0].previousElementSibling;
163
- let walker = getFocusableTreeWalker($c9e8f80f5bb1841844f54e4ad30b$var$getScopeRoot(scope), {
164
- tabbable
165
- }, scope);
166
- walker.currentNode = $c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(node, scope) ? node : sentinel;
167
- let nextNode = walker.nextNode();
168
-
169
- if (!nextNode && wrap) {
170
- walker.currentNode = sentinel;
171
- nextNode = walker.nextNode();
172
- }
173
-
174
- if (nextNode) {
175
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(nextNode, true);
176
- }
177
-
178
- return nextNode;
179
- },
180
-
181
- focusPrevious(opts) {
182
- if (opts === void 0) {
183
- opts = {};
184
- }
185
-
186
- let scope = scopeRef.current;
187
- let {
188
- from,
189
- tabbable,
190
- wrap
191
- } = opts;
192
- let node = from || document.activeElement;
193
- let sentinel = scope[scope.length - 1].nextElementSibling;
194
- let walker = getFocusableTreeWalker($c9e8f80f5bb1841844f54e4ad30b$var$getScopeRoot(scope), {
195
- tabbable
196
- }, scope);
197
- walker.currentNode = $c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(node, scope) ? node : sentinel;
198
- let previousNode = walker.previousNode();
199
-
200
- if (!previousNode && wrap) {
201
- walker.currentNode = sentinel;
202
- previousNode = walker.previousNode();
203
- }
204
-
205
- if (previousNode) {
206
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(previousNode, true);
207
- }
208
-
209
- return previousNode;
210
- }
211
-
212
- };
211
+ function $14e5c84cbc2e6e2e$var$useFocusContainment(scopeRef, contain) {
212
+ let focusedNode = $6saFI$useRef();
213
+ let raf = $6saFI$useRef(null);
214
+ $6saFI$useLayoutEffect(()=>{
215
+ let scope1 = scopeRef.current;
216
+ if (!contain) return;
217
+ // Handle the Tab key to contain focus within the scope
218
+ let onKeyDown = (e)=>{
219
+ if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey || scopeRef !== $14e5c84cbc2e6e2e$var$activeScope) return;
220
+ let focusedElement = document.activeElement;
221
+ let scope = scopeRef.current;
222
+ if (!$14e5c84cbc2e6e2e$var$isElementInScope(focusedElement, scope)) return;
223
+ let walker = $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa($14e5c84cbc2e6e2e$var$getScopeRoot(scope), {
224
+ tabbable: true
225
+ }, scope);
226
+ walker.currentNode = focusedElement;
227
+ let nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
228
+ if (!nextElement) {
229
+ walker.currentNode = e.shiftKey ? scope[scope.length - 1].nextElementSibling : scope[0].previousElementSibling;
230
+ nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
231
+ }
232
+ e.preventDefault();
233
+ if (nextElement) $14e5c84cbc2e6e2e$var$focusElement(nextElement, true);
234
+ };
235
+ let onFocus = (e)=>{
236
+ // If focusing an element in a child scope of the currently active scope, the child becomes active.
237
+ // Moving out of the active scope to an ancestor is not allowed.
238
+ if (!$14e5c84cbc2e6e2e$var$activeScope || $14e5c84cbc2e6e2e$var$isAncestorScope($14e5c84cbc2e6e2e$var$activeScope, scopeRef)) {
239
+ $14e5c84cbc2e6e2e$var$activeScope = scopeRef;
240
+ focusedNode.current = e.target;
241
+ } else if (scopeRef === $14e5c84cbc2e6e2e$var$activeScope && !$14e5c84cbc2e6e2e$var$isElementInChildScope(e.target, scopeRef)) {
242
+ // If a focus event occurs outside the active scope (e.g. user tabs from browser location bar),
243
+ // restore focus to the previously focused node or the first tabbable element in the active scope.
244
+ if (focusedNode.current) focusedNode.current.focus();
245
+ else if ($14e5c84cbc2e6e2e$var$activeScope) $14e5c84cbc2e6e2e$var$focusFirstInScope($14e5c84cbc2e6e2e$var$activeScope.current);
246
+ } else if (scopeRef === $14e5c84cbc2e6e2e$var$activeScope) focusedNode.current = e.target;
247
+ };
248
+ let onBlur = (e)=>{
249
+ // Firefox doesn't shift focus back to the Dialog properly without this
250
+ raf.current = requestAnimationFrame(()=>{
251
+ // Use document.activeElement instead of e.relatedTarget so we can tell if user clicked into iframe
252
+ if (scopeRef === $14e5c84cbc2e6e2e$var$activeScope && !$14e5c84cbc2e6e2e$var$isElementInChildScope(document.activeElement, scopeRef)) {
253
+ $14e5c84cbc2e6e2e$var$activeScope = scopeRef;
254
+ focusedNode.current = e.target;
255
+ focusedNode.current.focus();
256
+ }
257
+ });
258
+ };
259
+ document.addEventListener('keydown', onKeyDown, false);
260
+ document.addEventListener('focusin', onFocus, false);
261
+ scope1.forEach((element)=>element.addEventListener('focusin', onFocus, false)
262
+ );
263
+ scope1.forEach((element)=>element.addEventListener('focusout', onBlur, false)
264
+ );
265
+ return ()=>{
266
+ document.removeEventListener('keydown', onKeyDown, false);
267
+ document.removeEventListener('focusin', onFocus, false);
268
+ scope1.forEach((element)=>element.removeEventListener('focusin', onFocus, false)
269
+ );
270
+ scope1.forEach((element)=>element.removeEventListener('focusout', onBlur, false)
271
+ );
272
+ };
273
+ }, [
274
+ scopeRef,
275
+ contain
276
+ ]);
277
+ // eslint-disable-next-line arrow-body-style
278
+ $6saFI$useEffect(()=>{
279
+ return ()=>cancelAnimationFrame(raf.current)
280
+ ;
281
+ }, [
282
+ raf
283
+ ]);
213
284
  }
214
-
215
- 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]'];
216
- const $c9e8f80f5bb1841844f54e4ad30b$var$FOCUSABLE_ELEMENT_SELECTOR = $c9e8f80f5bb1841844f54e4ad30b$var$focusableElements.join(':not([hidden]),') + ',[tabindex]:not([disabled]):not([hidden])';
217
- $c9e8f80f5bb1841844f54e4ad30b$var$focusableElements.push('[tabindex]:not([tabindex="-1"]):not([disabled])');
218
- const $c9e8f80f5bb1841844f54e4ad30b$var$TABBABLE_ELEMENT_SELECTOR = $c9e8f80f5bb1841844f54e4ad30b$var$focusableElements.join(':not([hidden]):not([tabindex="-1"]),');
219
-
220
- function $c9e8f80f5bb1841844f54e4ad30b$var$getScopeRoot(scope) {
221
- return scope[0].parentElement;
285
+ function $14e5c84cbc2e6e2e$var$isElementInAnyScope(element) {
286
+ for (let scope of $14e5c84cbc2e6e2e$var$scopes.keys()){
287
+ if ($14e5c84cbc2e6e2e$var$isElementInScope(element, scope.current)) return true;
288
+ }
289
+ return false;
222
290
  }
223
-
224
- function $c9e8f80f5bb1841844f54e4ad30b$var$useFocusContainment(scopeRef, contain) {
225
- let focusedNode = useRef();
226
- let raf = useRef(null);
227
- useEffect(() => {
228
- let scope = scopeRef.current;
229
-
230
- if (!contain) {
231
- return;
232
- } // Handle the Tab key to contain focus within the scope
233
-
234
-
235
- let onKeyDown = e => {
236
- if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey) {
237
- return;
238
- }
239
-
240
- let focusedElement = document.activeElement;
241
-
242
- if (!$c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(focusedElement, scope)) {
243
- return;
244
- }
245
-
246
- let walker = getFocusableTreeWalker($c9e8f80f5bb1841844f54e4ad30b$var$getScopeRoot(scope), {
247
- tabbable: true
248
- }, scope);
249
- walker.currentNode = focusedElement;
250
- let nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
251
-
252
- if (!nextElement) {
253
- walker.currentNode = e.shiftKey ? scope[scope.length - 1].nextElementSibling : scope[0].previousElementSibling;
254
- nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
255
- }
256
-
257
- e.preventDefault();
258
-
259
- if (nextElement) {
260
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(nextElement, true);
261
- }
262
- };
263
-
264
- let onFocus = e => {
265
- // If a focus event occurs outside the active scope (e.g. user tabs from browser location bar),
266
- // restore focus to the previously focused node or the first tabbable element in the active scope.
267
- let isInAnyScope = $c9e8f80f5bb1841844f54e4ad30b$var$isElementInAnyScope(e.target, $c9e8f80f5bb1841844f54e4ad30b$var$scopes);
268
-
269
- if (!isInAnyScope) {
270
- if (focusedNode.current) {
271
- focusedNode.current.focus();
272
- } else if ($c9e8f80f5bb1841844f54e4ad30b$var$activeScope) {
273
- $c9e8f80f5bb1841844f54e4ad30b$var$focusFirstInScope($c9e8f80f5bb1841844f54e4ad30b$var$activeScope.current);
274
- }
275
- } else {
276
- $c9e8f80f5bb1841844f54e4ad30b$var$activeScope = scopeRef;
277
- focusedNode.current = e.target;
278
- }
279
- };
280
-
281
- let onBlur = e => {
282
- // Firefox doesn't shift focus back to the Dialog properly without this
283
- raf.current = requestAnimationFrame(() => {
284
- // Use document.activeElement instead of e.relatedTarget so we can tell if user clicked into iframe
285
- let isInAnyScope = $c9e8f80f5bb1841844f54e4ad30b$var$isElementInAnyScope(document.activeElement, $c9e8f80f5bb1841844f54e4ad30b$var$scopes);
286
-
287
- if (!isInAnyScope) {
288
- $c9e8f80f5bb1841844f54e4ad30b$var$activeScope = scopeRef;
289
- focusedNode.current = e.target;
290
- focusedNode.current.focus();
291
- }
292
- });
293
- };
294
-
295
- document.addEventListener('keydown', onKeyDown, false);
296
- document.addEventListener('focusin', onFocus, false);
297
- scope.forEach(element => element.addEventListener('focusin', onFocus, false));
298
- scope.forEach(element => element.addEventListener('focusout', onBlur, false));
299
- return () => {
300
- document.removeEventListener('keydown', onKeyDown, false);
301
- document.removeEventListener('focusin', onFocus, false);
302
- scope.forEach(element => element.removeEventListener('focusin', onFocus, false));
303
- scope.forEach(element => element.removeEventListener('focusout', onBlur, false));
304
- };
305
- }, [scopeRef, contain]); // eslint-disable-next-line arrow-body-style
306
-
307
- useEffect(() => {
308
- return () => cancelAnimationFrame(raf.current);
309
- }, [raf]);
291
+ function $14e5c84cbc2e6e2e$var$isElementInScope(element, scope) {
292
+ return scope.some((node)=>node.contains(element)
293
+ );
310
294
  }
311
-
312
- function $c9e8f80f5bb1841844f54e4ad30b$var$isElementInAnyScope(element, scopes) {
313
- for (let scope of scopes.values()) {
314
- if ($c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(element, scope.current)) {
315
- return true;
295
+ function $14e5c84cbc2e6e2e$var$isElementInChildScope(element, scope) {
296
+ // node.contains in isElementInScope covers child scopes that are also DOM children,
297
+ // but does not cover child scopes in portals.
298
+ for (let s of $14e5c84cbc2e6e2e$var$scopes.keys()){
299
+ if ((s === scope || $14e5c84cbc2e6e2e$var$isAncestorScope(scope, s)) && $14e5c84cbc2e6e2e$var$isElementInScope(element, s.current)) return true;
316
300
  }
317
- }
318
-
319
- return false;
301
+ return false;
320
302
  }
321
-
322
- function $c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(element, scope) {
323
- return scope.some(node => node.contains(element));
303
+ function $14e5c84cbc2e6e2e$var$isAncestorScope(ancestor, scope) {
304
+ let parent = $14e5c84cbc2e6e2e$var$scopes.get(scope);
305
+ if (!parent) return false;
306
+ if (parent === ancestor) return true;
307
+ return $14e5c84cbc2e6e2e$var$isAncestorScope(ancestor, parent);
324
308
  }
325
-
326
- function $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(element, scroll) {
327
- if (scroll === void 0) {
328
- scroll = false;
329
- }
330
-
331
- if (element != null && !scroll) {
332
- try {
333
- focusSafely(element);
334
- } catch (err) {// ignore
309
+ function $14e5c84cbc2e6e2e$var$focusElement(element, scroll = false) {
310
+ if (element != null && !scroll) try {
311
+ $1159c3b6ba210e4f$export$80f3e147d781571c(element);
312
+ } catch (err) {
313
+ // ignore
335
314
  }
336
- } else if (element != null) {
337
- try {
338
- element.focus();
339
- } catch (err) {// ignore
315
+ else if (element != null) try {
316
+ element.focus();
317
+ } catch (err1) {
318
+ // ignore
340
319
  }
341
- }
342
320
  }
343
-
344
- function $c9e8f80f5bb1841844f54e4ad30b$var$focusFirstInScope(scope) {
345
- let sentinel = scope[0].previousElementSibling;
346
- let walker = getFocusableTreeWalker($c9e8f80f5bb1841844f54e4ad30b$var$getScopeRoot(scope), {
347
- tabbable: true
348
- }, scope);
349
- walker.currentNode = sentinel;
350
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(walker.nextNode());
321
+ function $14e5c84cbc2e6e2e$var$focusFirstInScope(scope) {
322
+ let sentinel = scope[0].previousElementSibling;
323
+ let walker = $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa($14e5c84cbc2e6e2e$var$getScopeRoot(scope), {
324
+ tabbable: true
325
+ }, scope);
326
+ walker.currentNode = sentinel;
327
+ $14e5c84cbc2e6e2e$var$focusElement(walker.nextNode());
351
328
  }
352
-
353
- function $c9e8f80f5bb1841844f54e4ad30b$var$useAutoFocus(scopeRef, autoFocus) {
354
- useEffect(() => {
355
- if (autoFocus) {
356
- $c9e8f80f5bb1841844f54e4ad30b$var$activeScope = scopeRef;
357
-
358
- if (!$c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(document.activeElement, $c9e8f80f5bb1841844f54e4ad30b$var$activeScope.current)) {
359
- $c9e8f80f5bb1841844f54e4ad30b$var$focusFirstInScope(scopeRef.current);
360
- }
361
- }
362
- }, [scopeRef, autoFocus]);
329
+ function $14e5c84cbc2e6e2e$var$useAutoFocus(scopeRef, autoFocus) {
330
+ const autoFocusRef = $6saFI$react.useRef(autoFocus);
331
+ $6saFI$useEffect(()=>{
332
+ if (autoFocusRef.current) {
333
+ $14e5c84cbc2e6e2e$var$activeScope = scopeRef;
334
+ if (!$14e5c84cbc2e6e2e$var$isElementInScope(document.activeElement, $14e5c84cbc2e6e2e$var$activeScope.current)) $14e5c84cbc2e6e2e$var$focusFirstInScope(scopeRef.current);
335
+ }
336
+ autoFocusRef.current = false;
337
+ }, []);
338
+ }
339
+ function $14e5c84cbc2e6e2e$var$useRestoreFocus(scopeRef, restoreFocus, contain) {
340
+ // create a ref during render instead of useLayoutEffect so the active element is saved before a child with autoFocus=true mounts.
341
+ const nodeToRestoreRef = $6saFI$useRef(typeof document !== 'undefined' ? document.activeElement : null);
342
+ // useLayoutEffect instead of useEffect so the active element is saved synchronously instead of asynchronously.
343
+ $6saFI$useLayoutEffect(()=>{
344
+ let nodeToRestore = nodeToRestoreRef.current;
345
+ if (!restoreFocus) return;
346
+ // Handle the Tab key so that tabbing out of the scope goes to the next element
347
+ // after the node that had focus when the scope mounted. This is important when
348
+ // using portals for overlays, so that focus goes to the expected element when
349
+ // tabbing out of the overlay.
350
+ let onKeyDown = (e)=>{
351
+ if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey) return;
352
+ let focusedElement = document.activeElement;
353
+ if (!$14e5c84cbc2e6e2e$var$isElementInScope(focusedElement, scopeRef.current)) return;
354
+ // Create a DOM tree walker that matches all tabbable elements
355
+ let walker = $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa(document.body, {
356
+ tabbable: true
357
+ });
358
+ // Find the next tabbable element after the currently focused element
359
+ walker.currentNode = focusedElement;
360
+ let nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
361
+ if (!document.body.contains(nodeToRestore) || nodeToRestore === document.body) nodeToRestore = null;
362
+ // If there is no next element, or it is outside the current scope, move focus to the
363
+ // next element after the node to restore to instead.
364
+ if ((!nextElement || !$14e5c84cbc2e6e2e$var$isElementInScope(nextElement, scopeRef.current)) && nodeToRestore) {
365
+ walker.currentNode = nodeToRestore;
366
+ // Skip over elements within the scope, in case the scope immediately follows the node to restore.
367
+ do nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
368
+ while ($14e5c84cbc2e6e2e$var$isElementInScope(nextElement, scopeRef.current))
369
+ e.preventDefault();
370
+ e.stopPropagation();
371
+ if (nextElement) $14e5c84cbc2e6e2e$var$focusElement(nextElement, true);
372
+ 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)
373
+ // then move focus to the body.
374
+ // Otherwise restore focus to the nodeToRestore (e.g menu within a popover -> tabbing to close the menu should move focus to menu trigger)
375
+ if (!$14e5c84cbc2e6e2e$var$isElementInAnyScope(nodeToRestore)) focusedElement.blur();
376
+ else $14e5c84cbc2e6e2e$var$focusElement(nodeToRestore, true);
377
+ }
378
+ };
379
+ if (!contain) document.addEventListener('keydown', onKeyDown, true);
380
+ return ()=>{
381
+ if (!contain) document.removeEventListener('keydown', onKeyDown, true);
382
+ if (restoreFocus && nodeToRestore && $14e5c84cbc2e6e2e$var$isElementInScope(document.activeElement, scopeRef.current)) requestAnimationFrame(()=>{
383
+ if (document.body.contains(nodeToRestore)) $14e5c84cbc2e6e2e$var$focusElement(nodeToRestore);
384
+ });
385
+ };
386
+ }, [
387
+ scopeRef,
388
+ restoreFocus,
389
+ contain
390
+ ]);
391
+ }
392
+ function $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa(root, opts, scope) {
393
+ let selector = (opts === null || opts === void 0 ? void 0 : opts.tabbable) ? $14e5c84cbc2e6e2e$var$TABBABLE_ELEMENT_SELECTOR : $14e5c84cbc2e6e2e$var$FOCUSABLE_ELEMENT_SELECTOR;
394
+ let walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
395
+ acceptNode (node) {
396
+ var ref;
397
+ // Skip nodes inside the starting node.
398
+ if (opts === null || opts === void 0 ? void 0 : (ref = opts.from) === null || ref === void 0 ? void 0 : ref.contains(node)) return NodeFilter.FILTER_REJECT;
399
+ if (node.matches(selector) && $985a2847ebcbb615$export$e989c0fffaa6b27a(node) && (!scope || $14e5c84cbc2e6e2e$var$isElementInScope(node, scope))) return NodeFilter.FILTER_ACCEPT;
400
+ return NodeFilter.FILTER_SKIP;
401
+ }
402
+ });
403
+ if (opts === null || opts === void 0 ? void 0 : opts.from) walker.currentNode = opts.from;
404
+ return walker;
405
+ }
406
+ function $14e5c84cbc2e6e2e$export$c5251b9e124bf29(ref) {
407
+ return {
408
+ focusNext (opts = {
409
+ }) {
410
+ let root = ref.current;
411
+ let { from: from , tabbable: tabbable , wrap: wrap } = opts;
412
+ let node = from || document.activeElement;
413
+ let walker = $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa(root, {
414
+ tabbable: tabbable
415
+ });
416
+ if (root.contains(node)) walker.currentNode = node;
417
+ let nextNode = walker.nextNode();
418
+ if (!nextNode && wrap) {
419
+ walker.currentNode = root;
420
+ nextNode = walker.nextNode();
421
+ }
422
+ if (nextNode) $14e5c84cbc2e6e2e$var$focusElement(nextNode, true);
423
+ return nextNode;
424
+ },
425
+ focusPrevious (opts = {
426
+ }) {
427
+ let root = ref.current;
428
+ let { from: from , tabbable: tabbable , wrap: wrap } = opts;
429
+ let node = from || document.activeElement;
430
+ let walker = $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa(root, {
431
+ tabbable: tabbable
432
+ });
433
+ if (root.contains(node)) walker.currentNode = node;
434
+ else {
435
+ let next = $14e5c84cbc2e6e2e$var$last(walker);
436
+ if (next) $14e5c84cbc2e6e2e$var$focusElement(next, true);
437
+ return next;
438
+ }
439
+ let previousNode = walker.previousNode();
440
+ if (!previousNode && wrap) {
441
+ walker.currentNode = root;
442
+ previousNode = $14e5c84cbc2e6e2e$var$last(walker);
443
+ }
444
+ if (previousNode) $14e5c84cbc2e6e2e$var$focusElement(previousNode, true);
445
+ return previousNode;
446
+ },
447
+ focusFirst (opts = {
448
+ }) {
449
+ let root = ref.current;
450
+ let { tabbable: tabbable } = opts;
451
+ let walker = $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa(root, {
452
+ tabbable: tabbable
453
+ });
454
+ let nextNode = walker.nextNode();
455
+ if (nextNode) $14e5c84cbc2e6e2e$var$focusElement(nextNode, true);
456
+ return nextNode;
457
+ },
458
+ focusLast (opts = {
459
+ }) {
460
+ let root = ref.current;
461
+ let { tabbable: tabbable } = opts;
462
+ let walker = $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa(root, {
463
+ tabbable: tabbable
464
+ });
465
+ let next = $14e5c84cbc2e6e2e$var$last(walker);
466
+ if (next) $14e5c84cbc2e6e2e$var$focusElement(next, true);
467
+ return next;
468
+ }
469
+ };
470
+ }
471
+ function $14e5c84cbc2e6e2e$var$last(walker) {
472
+ let next;
473
+ let last;
474
+ do {
475
+ last = walker.lastChild();
476
+ if (last) next = last;
477
+ }while (last)
478
+ return next;
363
479
  }
364
480
 
365
- function $c9e8f80f5bb1841844f54e4ad30b$var$useRestoreFocus(scopeRef, restoreFocus, contain) {
366
- // useLayoutEffect instead of useEffect so the active element is saved synchronously instead of asynchronously.
367
- useLayoutEffect(() => {
368
- let scope = scopeRef.current;
369
- let nodeToRestore = document.activeElement; // Handle the Tab key so that tabbing out of the scope goes to the next element
370
- // after the node that had focus when the scope mounted. This is important when
371
- // using portals for overlays, so that focus goes to the expected element when
372
- // tabbing out of the overlay.
373
-
374
- let onKeyDown = e => {
375
- if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey) {
376
- return;
377
- }
378
-
379
- let focusedElement = document.activeElement;
380
481
 
381
- if (!$c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(focusedElement, scope)) {
382
- return;
383
- } // Create a DOM tree walker that matches all tabbable elements
482
+ var $503734efc0922182$exports = {};
384
483
 
484
+ $parcel$export($503734efc0922182$exports, "FocusRing", () => $503734efc0922182$export$1a38b4ad7f578e1d);
385
485
 
386
- let walker = getFocusableTreeWalker(document.body, {
387
- tabbable: true
388
- }); // Find the next tabbable element after the currently focused element
389
486
 
390
- walker.currentNode = focusedElement;
391
- let nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
392
487
 
393
- if (!document.body.contains(nodeToRestore) || nodeToRestore === document.body) {
394
- nodeToRestore = null;
395
- } // If there is no next element, or it is outside the current scope, move focus to the
396
- // next element after the node to restore to instead.
488
+ var $e63d024ca16f2165$exports = {};
397
489
 
490
+ $parcel$export($e63d024ca16f2165$exports, "useFocusRing", () => $e63d024ca16f2165$export$4e328f61c538687f);
398
491
 
399
- if ((!nextElement || !$c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(nextElement, scope)) && nodeToRestore) {
400
- walker.currentNode = nodeToRestore; // Skip over elements within the scope, in case the scope immediately follows the node to restore.
401
492
 
402
- do {
403
- nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
404
- } while ($c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(nextElement, scope));
405
493
 
406
- e.preventDefault();
407
- e.stopPropagation();
408
-
409
- if (nextElement) {
410
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(nextElement, true);
411
- } else {
412
- // If there is no next element, blur the focused element to move focus to the body.
413
- focusedElement.blur();
414
- }
415
- }
494
+ function $e63d024ca16f2165$export$4e328f61c538687f(props = {
495
+ }) {
496
+ let { autoFocus: autoFocus = false , isTextInput: isTextInput , within: within } = props;
497
+ let state = $6saFI$useRef({
498
+ isFocused: false,
499
+ isFocusVisible: autoFocus || $6saFI$isFocusVisible()
500
+ }).current;
501
+ let [isFocused1, setFocused] = $6saFI$useState(false);
502
+ let [isFocusVisibleState, setFocusVisible] = $6saFI$useState(()=>state.isFocused && state.isFocusVisible
503
+ );
504
+ let updateState = ()=>setFocusVisible(state.isFocused && state.isFocusVisible)
505
+ ;
506
+ let onFocusChange = (isFocused)=>{
507
+ state.isFocused = isFocused;
508
+ setFocused(isFocused);
509
+ updateState();
416
510
  };
417
-
418
- if (!contain) {
419
- document.addEventListener('keydown', onKeyDown, true);
420
- }
421
-
422
- return () => {
423
- if (!contain) {
424
- document.removeEventListener('keydown', onKeyDown, true);
425
- }
426
-
427
- if (restoreFocus && nodeToRestore && $c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(document.activeElement, scope)) {
428
- requestAnimationFrame(() => {
429
- if (document.body.contains(nodeToRestore)) {
430
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(nodeToRestore);
431
- }
432
- });
433
- }
511
+ $6saFI$useFocusVisibleListener((isFocusVisible)=>{
512
+ state.isFocusVisible = isFocusVisible;
513
+ updateState();
514
+ }, [], {
515
+ isTextInput: isTextInput
516
+ });
517
+ let { focusProps: focusProps } = $6saFI$useFocus({
518
+ isDisabled: within,
519
+ onFocusChange: onFocusChange
520
+ });
521
+ let { focusWithinProps: focusWithinProps } = $6saFI$useFocusWithin({
522
+ isDisabled: !within,
523
+ onFocusWithinChange: onFocusChange
524
+ });
525
+ return {
526
+ isFocused: isFocused1,
527
+ isFocusVisible: state.isFocused && isFocusVisibleState,
528
+ focusProps: within ? focusWithinProps : focusProps
434
529
  };
435
- }, [scopeRef, restoreFocus, contain]);
436
530
  }
437
- /**
438
- * Create a [TreeWalker]{@link https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker}
439
- * that matches all focusable/tabbable elements.
440
- */
441
-
442
-
443
- export function getFocusableTreeWalker(root, opts, scope) {
444
- let selector = opts != null && opts.tabbable ? $c9e8f80f5bb1841844f54e4ad30b$var$TABBABLE_ELEMENT_SELECTOR : $c9e8f80f5bb1841844f54e4ad30b$var$FOCUSABLE_ELEMENT_SELECTOR;
445
- let walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
446
- acceptNode(node) {
447
- var _opts$from;
448
-
449
- // Skip nodes inside the starting node.
450
- if (opts != null && (_opts$from = opts.from) != null && _opts$from.contains(node)) {
451
- return NodeFilter.FILTER_REJECT;
452
- }
453
531
 
454
- if (node.matches(selector) && $ee5e90cbb4a22466973155c14222fa1$export$isElementVisible(node) && (!scope || $c9e8f80f5bb1841844f54e4ad30b$var$isElementInScope(node, scope))) {
455
- return NodeFilter.FILTER_ACCEPT;
456
- }
457
532
 
458
- return NodeFilter.FILTER_SKIP;
459
- }
460
-
461
- });
462
-
463
- if (opts != null && opts.from) {
464
- walker.currentNode = opts.from;
465
- }
466
-
467
- return walker;
533
+ function $503734efc0922182$export$1a38b4ad7f578e1d(props) {
534
+ let { children: children , focusClass: focusClass , focusRingClass: focusRingClass } = props;
535
+ let { isFocused: isFocused , isFocusVisible: isFocusVisible , focusProps: focusProps } = $e63d024ca16f2165$export$4e328f61c538687f(props);
536
+ let child = $6saFI$react.Children.only(children);
537
+ return(/*#__PURE__*/ $6saFI$react.cloneElement(child, $6saFI$mergeProps(child.props, {
538
+ ...focusProps,
539
+ className: $6saFI$clsx({
540
+ [focusClass || '']: isFocused,
541
+ [focusRingClass || '']: isFocusVisible
542
+ })
543
+ })));
468
544
  }
469
- /**
470
- * Creates a FocusManager object that can be used to move focus within an element.
471
- */
472
-
473
- export function createFocusManager(ref) {
474
- return {
475
- focusNext(opts) {
476
- if (opts === void 0) {
477
- opts = {};
478
- }
479
-
480
- let root = ref.current;
481
- let {
482
- from,
483
- tabbable,
484
- wrap
485
- } = opts;
486
- let node = from || document.activeElement;
487
- let walker = getFocusableTreeWalker(root, {
488
- tabbable
489
- });
490
-
491
- if (root.contains(node)) {
492
- walker.currentNode = node;
493
- }
494
-
495
- let nextNode = walker.nextNode();
496
-
497
- if (!nextNode && wrap) {
498
- walker.currentNode = root;
499
- nextNode = walker.nextNode();
500
- }
501
-
502
- if (nextNode) {
503
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(nextNode, true);
504
- }
505
-
506
- return nextNode;
507
- },
508
-
509
- focusPrevious(opts) {
510
- if (opts === void 0) {
511
- opts = {};
512
- }
513
-
514
- let root = ref.current;
515
- let {
516
- from,
517
- tabbable,
518
- wrap
519
- } = opts;
520
- let node = from || document.activeElement;
521
- let walker = getFocusableTreeWalker(root, {
522
- tabbable
523
- });
524
-
525
- if (root.contains(node)) {
526
- walker.currentNode = node;
527
- } else {
528
- let next = $c9e8f80f5bb1841844f54e4ad30b$var$last(walker);
529
-
530
- if (next) {
531
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(next, true);
532
- }
533
545
 
534
- return next;
535
- }
536
546
 
537
- let previousNode = walker.previousNode();
547
+ var $391c6482f25a1991$exports = {};
538
548
 
539
- if (!previousNode && wrap) {
540
- walker.currentNode = root;
541
- previousNode = $c9e8f80f5bb1841844f54e4ad30b$var$last(walker);
542
- }
549
+ $parcel$export($391c6482f25a1991$exports, "FocusableProvider", () => $391c6482f25a1991$export$13f3202a3e5ddd5);
550
+ $parcel$export($391c6482f25a1991$exports, "useFocusable", () => $391c6482f25a1991$export$4c014de7c8940b4c);
543
551
 
544
- if (previousNode) {
545
- $c9e8f80f5bb1841844f54e4ad30b$var$focusElement(previousNode, true);
546
- }
547
-
548
- return previousNode;
549
- }
550
552
 
551
- };
552
- }
553
-
554
- function $c9e8f80f5bb1841844f54e4ad30b$var$last(walker) {
555
- let next;
556
- let last;
557
-
558
- do {
559
- last = walker.lastChild();
560
-
561
- if (last) {
562
- next = last;
563
- }
564
- } while (last);
565
-
566
- return next;
567
- }
568
553
 
569
- /**
570
- * Determines whether a focus ring should be shown to indicate keyboard focus.
571
- * Focus rings are visible only when the user is interacting with a keyboard,
572
- * not with a mouse, touch, or other input methods.
573
- */
574
- export function useFocusRing(props) {
575
- if (props === void 0) {
576
- props = {};
577
- }
578
-
579
- let {
580
- autoFocus = false,
581
- isTextInput,
582
- within
583
- } = props;
584
- let state = useRef({
585
- isFocused: false,
586
- isFocusVisible: autoFocus || _isFocusVisible()
587
- }).current;
588
- let [isFocusVisibleState, setFocusVisible] = useState(() => state.isFocused && state.isFocusVisible);
589
-
590
- let updateState = () => setFocusVisible(state.isFocused && state.isFocusVisible);
591
-
592
- let onFocusChange = isFocused => {
593
- state.isFocused = isFocused;
594
- updateState();
595
- };
596
-
597
- useFocusVisibleListener(isFocusVisible => {
598
- state.isFocusVisible = isFocusVisible;
599
- updateState();
600
- }, [], {
601
- isTextInput
602
- });
603
- let {
604
- focusProps
605
- } = useFocus({
606
- isDisabled: within,
607
- onFocusChange
608
- });
609
- let {
610
- focusWithinProps
611
- } = useFocusWithin({
612
- isDisabled: !within,
613
- onFocusWithinChange: onFocusChange
614
- });
615
- return {
616
- isFocused: state.isFocused,
617
- isFocusVisible: state.isFocused && isFocusVisibleState,
618
- focusProps: within ? focusWithinProps : focusProps
619
- };
554
+ let $391c6482f25a1991$var$FocusableContext = /*#__PURE__*/ $6saFI$react.createContext(null);
555
+ function $391c6482f25a1991$var$useFocusableContext(ref) {
556
+ let context = $6saFI$useContext($391c6482f25a1991$var$FocusableContext) || {
557
+ };
558
+ $6saFI$useSyncRef(context, ref);
559
+ // eslint-disable-next-line
560
+ let { ref: _ , ...otherProps } = context;
561
+ return otherProps;
620
562
  }
621
-
622
563
  /**
623
- * A utility component that applies a CSS class when an element has keyboard focus.
624
- * Focus rings are visible only when the user is interacting with a keyboard,
625
- * not with a mouse, touch, or other input methods.
626
- */
627
- export function FocusRing(props) {
628
- let {
629
- children,
630
- focusClass,
631
- focusRingClass
632
- } = props;
633
- let {
634
- isFocused,
635
- isFocusVisible,
636
- focusProps
637
- } = useFocusRing(props);
638
-
639
- let child = _react.Children.only(children);
640
-
641
- return /*#__PURE__*/_react.cloneElement(child, mergeProps(child.props, _babelRuntimeHelpersEsmExtends({}, focusProps, {
642
- className: _clsx({
643
- [focusClass || '']: isFocused,
644
- [focusRingClass || '']: isFocusVisible
645
- })
646
- })));
564
+ * Provides DOM props to the nearest focusable child.
565
+ */ function $391c6482f25a1991$var$FocusableProvider(props, ref) {
566
+ let { children: children , ...otherProps } = props;
567
+ let context = {
568
+ ...otherProps,
569
+ ref: ref
570
+ };
571
+ return(/*#__PURE__*/ $6saFI$react.createElement($391c6482f25a1991$var$FocusableContext.Provider, {
572
+ value: context
573
+ }, children));
647
574
  }
648
-
649
- let $e11539c8317b2d21639df611cb5658f$var$FocusableContext = /*#__PURE__*/_react.createContext(null);
650
-
651
- function $e11539c8317b2d21639df611cb5658f$var$useFocusableContext(ref) {
652
- let context = useContext($e11539c8317b2d21639df611cb5658f$var$FocusableContext) || {};
653
- useSyncRef(context, ref);
654
- return context;
575
+ let $391c6482f25a1991$export$13f3202a3e5ddd5 = /*#__PURE__*/ $6saFI$react.forwardRef($391c6482f25a1991$var$FocusableProvider);
576
+ function $391c6482f25a1991$export$4c014de7c8940b4c(props, domRef) {
577
+ let { focusProps: focusProps } = $6saFI$useFocus(props);
578
+ let { keyboardProps: keyboardProps } = $6saFI$useKeyboard(props);
579
+ let interactions = $6saFI$mergeProps(focusProps, keyboardProps);
580
+ let domProps = $391c6482f25a1991$var$useFocusableContext(domRef);
581
+ let interactionProps = props.isDisabled ? {
582
+ } : domProps;
583
+ let autoFocusRef = $6saFI$useRef(props.autoFocus);
584
+ $6saFI$useEffect(()=>{
585
+ if (autoFocusRef.current && domRef.current) domRef.current.focus();
586
+ autoFocusRef.current = false;
587
+ }, []);
588
+ return {
589
+ focusableProps: $6saFI$mergeProps({
590
+ ...interactions,
591
+ tabIndex: props.excludeFromTabOrder && !props.isDisabled ? -1 : undefined
592
+ }, interactionProps)
593
+ };
655
594
  }
656
- /**
657
- * Provides DOM props to the nearest focusable child.
658
- */
659
595
 
660
596
 
661
- function $e11539c8317b2d21639df611cb5658f$var$FocusableProvider(props, ref) {
662
- let {
663
- children
664
- } = props,
665
- otherProps = _babelRuntimeHelpersEsmObjectWithoutPropertiesLoose(props, ["children"]);
666
597
 
667
- let context = _babelRuntimeHelpersEsmExtends({}, otherProps, {
668
- ref
669
- });
670
598
 
671
- return /*#__PURE__*/_react.createElement($e11539c8317b2d21639df611cb5658f$var$FocusableContext.Provider, {
672
- value: context
673
- }, children);
674
- }
675
599
 
676
- export let FocusableProvider = /*#__PURE__*/_react.forwardRef($e11539c8317b2d21639df611cb5658f$var$FocusableProvider);
677
600
 
678
- /**
679
- * Used to make an element focusable and capable of auto focus.
680
- */
681
- export function useFocusable(props, domRef) {
682
- let {
683
- focusProps
684
- } = useFocus(props);
685
- let {
686
- keyboardProps
687
- } = useKeyboard(props);
688
- let interactions = mergeProps(focusProps, keyboardProps);
689
- let domProps = $e11539c8317b2d21639df611cb5658f$var$useFocusableContext(domRef);
690
- let interactionProps = props.isDisabled ? {} : domProps;
691
- useEffect(() => {
692
- if (props.autoFocus && domRef.current) {
693
- domRef.current.focus();
694
- }
695
- }, [props.autoFocus, domRef]);
696
- return {
697
- focusableProps: mergeProps(_babelRuntimeHelpersEsmExtends({}, interactions, {
698
- tabIndex: props.excludeFromTabOrder && !props.isDisabled ? -1 : undefined
699
- }), interactionProps)
700
- };
701
- }
601
+ export {$14e5c84cbc2e6e2e$export$20e40289641fbbb6 as FocusScope, $14e5c84cbc2e6e2e$export$10c5169755ce7bd7 as useFocusManager, $14e5c84cbc2e6e2e$export$2d6ec8fc375ceafa as getFocusableTreeWalker, $14e5c84cbc2e6e2e$export$c5251b9e124bf29 as createFocusManager, $503734efc0922182$export$1a38b4ad7f578e1d as FocusRing, $391c6482f25a1991$export$13f3202a3e5ddd5 as FocusableProvider, $391c6482f25a1991$export$4c014de7c8940b4c as useFocusable, $e63d024ca16f2165$export$4e328f61c538687f as useFocusRing, $1159c3b6ba210e4f$export$80f3e147d781571c as focusSafely};
702
602
  //# sourceMappingURL=module.js.map