@radix-ui/react-focus-scope 1.0.4 → 1.1.0-rc.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/index.d.mts CHANGED
@@ -1,8 +1,9 @@
1
- import * as React from "react";
2
- import * as Radix from "@radix-ui/react-primitive";
3
- import { Primitive } from "@radix-ui/react-primitive";
4
- type PrimitiveDivProps = Radix.ComponentPropsWithoutRef<typeof Primitive.div>;
5
- export interface FocusScopeProps extends PrimitiveDivProps {
1
+ import * as React from 'react';
2
+ import * as Radix from '@radix-ui/react-primitive';
3
+ import { Primitive } from '@radix-ui/react-primitive';
4
+
5
+ declare type PrimitiveDivProps = Radix.ComponentPropsWithoutRef<typeof Primitive.div>;
6
+ interface FocusScopeProps extends PrimitiveDivProps {
6
7
  /**
7
8
  * When `true`, tabbing from last item will focus first tabbable
8
9
  * and shift+tab from first item will focus last tababble.
@@ -26,7 +27,7 @@ export interface FocusScopeProps extends PrimitiveDivProps {
26
27
  */
27
28
  onUnmountAutoFocus?: (event: Event) => void;
28
29
  }
29
- export const FocusScope: React.ForwardRefExoticComponent<FocusScopeProps & React.RefAttributes<HTMLDivElement>>;
30
- export const Root: React.ForwardRefExoticComponent<FocusScopeProps & React.RefAttributes<HTMLDivElement>>;
30
+ declare const FocusScope: React.ForwardRefExoticComponent<FocusScopeProps & React.RefAttributes<HTMLDivElement>>;
31
+ declare const Root: React.ForwardRefExoticComponent<FocusScopeProps & React.RefAttributes<HTMLDivElement>>;
31
32
 
32
- //# sourceMappingURL=index.d.ts.map
33
+ export { FocusScope, type FocusScopeProps, Root };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import * as React from "react";
2
- import * as Radix from "@radix-ui/react-primitive";
3
- import { Primitive } from "@radix-ui/react-primitive";
4
- type PrimitiveDivProps = Radix.ComponentPropsWithoutRef<typeof Primitive.div>;
5
- export interface FocusScopeProps extends PrimitiveDivProps {
1
+ import * as React from 'react';
2
+ import * as Radix from '@radix-ui/react-primitive';
3
+ import { Primitive } from '@radix-ui/react-primitive';
4
+
5
+ declare type PrimitiveDivProps = Radix.ComponentPropsWithoutRef<typeof Primitive.div>;
6
+ interface FocusScopeProps extends PrimitiveDivProps {
6
7
  /**
7
8
  * When `true`, tabbing from last item will focus first tabbable
8
9
  * and shift+tab from first item will focus last tababble.
@@ -26,7 +27,7 @@ export interface FocusScopeProps extends PrimitiveDivProps {
26
27
  */
27
28
  onUnmountAutoFocus?: (event: Event) => void;
28
29
  }
29
- export const FocusScope: React.ForwardRefExoticComponent<FocusScopeProps & React.RefAttributes<HTMLDivElement>>;
30
- export const Root: React.ForwardRefExoticComponent<FocusScopeProps & React.RefAttributes<HTMLDivElement>>;
30
+ declare const FocusScope: React.ForwardRefExoticComponent<FocusScopeProps & React.RefAttributes<HTMLDivElement>>;
31
+ declare const Root: React.ForwardRefExoticComponent<FocusScopeProps & React.RefAttributes<HTMLDivElement>>;
31
32
 
32
- //# sourceMappingURL=index.d.ts.map
33
+ export { FocusScope, type FocusScopeProps, Root };
package/dist/index.js CHANGED
@@ -1,300 +1,240 @@
1
- var $buum9$babelruntimehelpersextends = require("@babel/runtime/helpers/extends");
2
- var $buum9$react = require("react");
3
- var $buum9$radixuireactcomposerefs = require("@radix-ui/react-compose-refs");
4
- var $buum9$radixuireactprimitive = require("@radix-ui/react-primitive");
5
- var $buum9$radixuireactusecallbackref = require("@radix-ui/react-use-callback-ref");
6
-
7
- function $parcel$export(e, n, v, s) {
8
- Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
9
- }
10
- function $parcel$interopDefault(a) {
11
- return a && a.__esModule ? a.default : a;
12
- }
13
-
14
- $parcel$export(module.exports, "FocusScope", () => $2bc01e66e04aa9ed$export$20e40289641fbbb6);
15
- $parcel$export(module.exports, "Root", () => $2bc01e66e04aa9ed$export$be92b6f5f03c0fe9);
16
-
17
-
18
-
19
-
1
+ "use strict";
2
+ (() => {
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
10
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
11
+ }) : x)(function(x) {
12
+ if (typeof require !== "undefined") return require.apply(this, arguments);
13
+ throw Error('Dynamic require of "' + x + '" is not supported');
14
+ });
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
20
31
 
21
- const $2bc01e66e04aa9ed$var$AUTOFOCUS_ON_MOUNT = 'focusScope.autoFocusOnMount';
22
- const $2bc01e66e04aa9ed$var$AUTOFOCUS_ON_UNMOUNT = 'focusScope.autoFocusOnUnmount';
23
- const $2bc01e66e04aa9ed$var$EVENT_OPTIONS = {
24
- bubbles: false,
25
- cancelable: true
26
- };
27
- /* -------------------------------------------------------------------------------------------------
28
- * FocusScope
29
- * -----------------------------------------------------------------------------------------------*/ const $2bc01e66e04aa9ed$var$FOCUS_SCOPE_NAME = 'FocusScope';
30
- const $2bc01e66e04aa9ed$export$20e40289641fbbb6 = /*#__PURE__*/ $buum9$react.forwardRef((props, forwardedRef)=>{
31
- const { loop: loop = false , trapped: trapped = false , onMountAutoFocus: onMountAutoFocusProp , onUnmountAutoFocus: onUnmountAutoFocusProp , ...scopeProps } = props;
32
- const [container1, setContainer] = $buum9$react.useState(null);
33
- const onMountAutoFocus = $buum9$radixuireactusecallbackref.useCallbackRef(onMountAutoFocusProp);
34
- const onUnmountAutoFocus = $buum9$radixuireactusecallbackref.useCallbackRef(onUnmountAutoFocusProp);
35
- const lastFocusedElementRef = $buum9$react.useRef(null);
36
- const composedRefs = $buum9$radixuireactcomposerefs.useComposedRefs(forwardedRef, (node)=>setContainer(node)
37
- );
38
- const focusScope = $buum9$react.useRef({
39
- paused: false,
40
- pause () {
41
- this.paused = true;
42
- },
43
- resume () {
44
- this.paused = false;
45
- }
46
- }).current; // Takes care of trapping focus if focus is moved outside programmatically for example
47
- $buum9$react.useEffect(()=>{
48
- if (trapped) {
49
- function handleFocusIn(event) {
50
- if (focusScope.paused || !container1) return;
51
- const target = event.target;
52
- if (container1.contains(target)) lastFocusedElementRef.current = target;
53
- else $2bc01e66e04aa9ed$var$focus(lastFocusedElementRef.current, {
54
- select: true
55
- });
56
- }
57
- function handleFocusOut(event) {
58
- if (focusScope.paused || !container1) return;
59
- const relatedTarget = event.relatedTarget; // A `focusout` event with a `null` `relatedTarget` will happen in at least two cases:
60
- //
61
- // 1. When the user switches app/tabs/windows/the browser itself loses focus.
62
- // 2. In Google Chrome, when the focused element is removed from the DOM.
63
- //
64
- // We let the browser do its thing here because:
65
- //
66
- // 1. The browser already keeps a memory of what's focused for when the page gets refocused.
67
- // 2. In Google Chrome, if we try to focus the deleted focused element (as per below), it
68
- // throws the CPU to 100%, so we avoid doing anything for this reason here too.
69
- if (relatedTarget === null) return; // If the focus has moved to an actual legitimate element (`relatedTarget !== null`)
70
- // that is outside the container, we move focus to the last valid focused element inside.
71
- if (!container1.contains(relatedTarget)) $2bc01e66e04aa9ed$var$focus(lastFocusedElementRef.current, {
72
- select: true
73
- });
74
- } // When the focused element gets removed from the DOM, browsers move focus
75
- // back to the document.body. In this case, we move focus to the container
76
- // to keep focus trapped correctly.
77
- function handleMutations(mutations) {
78
- const focusedElement = document.activeElement;
79
- if (focusedElement !== document.body) return;
80
- for (const mutation of mutations)if (mutation.removedNodes.length > 0) $2bc01e66e04aa9ed$var$focus(container1);
32
+ // packages/react/focus-scope/src/FocusScope.tsx
33
+ var React = __toESM(__require("react"));
34
+ var import_react_compose_refs = __require("@radix-ui/react-compose-refs");
35
+ var import_react_primitive = __require("@radix-ui/react-primitive");
36
+ var import_react_use_callback_ref = __require("@radix-ui/react-use-callback-ref");
37
+ var import_jsx_runtime = __require("react/jsx-runtime");
38
+ var AUTOFOCUS_ON_MOUNT = "focusScope.autoFocusOnMount";
39
+ var AUTOFOCUS_ON_UNMOUNT = "focusScope.autoFocusOnUnmount";
40
+ var EVENT_OPTIONS = { bubbles: false, cancelable: true };
41
+ var FOCUS_SCOPE_NAME = "FocusScope";
42
+ var FocusScope = React.forwardRef((props, forwardedRef) => {
43
+ const {
44
+ loop = false,
45
+ trapped = false,
46
+ onMountAutoFocus: onMountAutoFocusProp,
47
+ onUnmountAutoFocus: onUnmountAutoFocusProp,
48
+ ...scopeProps
49
+ } = props;
50
+ const [container, setContainer] = React.useState(null);
51
+ const onMountAutoFocus = (0, import_react_use_callback_ref.useCallbackRef)(onMountAutoFocusProp);
52
+ const onUnmountAutoFocus = (0, import_react_use_callback_ref.useCallbackRef)(onUnmountAutoFocusProp);
53
+ const lastFocusedElementRef = React.useRef(null);
54
+ const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, (node) => setContainer(node));
55
+ const focusScope = React.useRef({
56
+ paused: false,
57
+ pause() {
58
+ this.paused = true;
59
+ },
60
+ resume() {
61
+ this.paused = false;
62
+ }
63
+ }).current;
64
+ React.useEffect(() => {
65
+ if (trapped) {
66
+ let handleFocusIn2 = function(event) {
67
+ if (focusScope.paused || !container) return;
68
+ const target = event.target;
69
+ if (container.contains(target)) {
70
+ lastFocusedElementRef.current = target;
71
+ } else {
72
+ focus(lastFocusedElementRef.current, { select: true });
73
+ }
74
+ }, handleFocusOut2 = function(event) {
75
+ if (focusScope.paused || !container) return;
76
+ const relatedTarget = event.relatedTarget;
77
+ if (relatedTarget === null) return;
78
+ if (!container.contains(relatedTarget)) {
79
+ focus(lastFocusedElementRef.current, { select: true });
80
+ }
81
+ }, handleMutations2 = function(mutations) {
82
+ const focusedElement = document.activeElement;
83
+ if (focusedElement !== document.body) return;
84
+ for (const mutation of mutations) {
85
+ if (mutation.removedNodes.length > 0) focus(container);
86
+ }
87
+ };
88
+ var handleFocusIn = handleFocusIn2, handleFocusOut = handleFocusOut2, handleMutations = handleMutations2;
89
+ document.addEventListener("focusin", handleFocusIn2);
90
+ document.addEventListener("focusout", handleFocusOut2);
91
+ const mutationObserver = new MutationObserver(handleMutations2);
92
+ if (container) mutationObserver.observe(container, { childList: true, subtree: true });
93
+ return () => {
94
+ document.removeEventListener("focusin", handleFocusIn2);
95
+ document.removeEventListener("focusout", handleFocusOut2);
96
+ mutationObserver.disconnect();
97
+ };
98
+ }
99
+ }, [trapped, container, focusScope.paused]);
100
+ React.useEffect(() => {
101
+ if (container) {
102
+ focusScopesStack.add(focusScope);
103
+ const previouslyFocusedElement = document.activeElement;
104
+ const hasFocusedCandidate = container.contains(previouslyFocusedElement);
105
+ if (!hasFocusedCandidate) {
106
+ const mountEvent = new CustomEvent(AUTOFOCUS_ON_MOUNT, EVENT_OPTIONS);
107
+ container.addEventListener(AUTOFOCUS_ON_MOUNT, onMountAutoFocus);
108
+ container.dispatchEvent(mountEvent);
109
+ if (!mountEvent.defaultPrevented) {
110
+ focusFirst(removeLinks(getTabbableCandidates(container)), { select: true });
111
+ if (document.activeElement === previouslyFocusedElement) {
112
+ focus(container);
81
113
  }
82
- document.addEventListener('focusin', handleFocusIn);
83
- document.addEventListener('focusout', handleFocusOut);
84
- const mutationObserver = new MutationObserver(handleMutations);
85
- if (container1) mutationObserver.observe(container1, {
86
- childList: true,
87
- subtree: true
88
- });
89
- return ()=>{
90
- document.removeEventListener('focusin', handleFocusIn);
91
- document.removeEventListener('focusout', handleFocusOut);
92
- mutationObserver.disconnect();
93
- };
114
+ }
94
115
  }
95
- }, [
96
- trapped,
97
- container1,
98
- focusScope.paused
99
- ]);
100
- $buum9$react.useEffect(()=>{
101
- if (container1) {
102
- $2bc01e66e04aa9ed$var$focusScopesStack.add(focusScope);
103
- const previouslyFocusedElement = document.activeElement;
104
- const hasFocusedCandidate = container1.contains(previouslyFocusedElement);
105
- if (!hasFocusedCandidate) {
106
- const mountEvent = new CustomEvent($2bc01e66e04aa9ed$var$AUTOFOCUS_ON_MOUNT, $2bc01e66e04aa9ed$var$EVENT_OPTIONS);
107
- container1.addEventListener($2bc01e66e04aa9ed$var$AUTOFOCUS_ON_MOUNT, onMountAutoFocus);
108
- container1.dispatchEvent(mountEvent);
109
- if (!mountEvent.defaultPrevented) {
110
- $2bc01e66e04aa9ed$var$focusFirst($2bc01e66e04aa9ed$var$removeLinks($2bc01e66e04aa9ed$var$getTabbableCandidates(container1)), {
111
- select: true
112
- });
113
- if (document.activeElement === previouslyFocusedElement) $2bc01e66e04aa9ed$var$focus(container1);
114
- }
116
+ return () => {
117
+ container.removeEventListener(AUTOFOCUS_ON_MOUNT, onMountAutoFocus);
118
+ setTimeout(() => {
119
+ const unmountEvent = new CustomEvent(AUTOFOCUS_ON_UNMOUNT, EVENT_OPTIONS);
120
+ container.addEventListener(AUTOFOCUS_ON_UNMOUNT, onUnmountAutoFocus);
121
+ container.dispatchEvent(unmountEvent);
122
+ if (!unmountEvent.defaultPrevented) {
123
+ focus(previouslyFocusedElement ?? document.body, { select: true });
115
124
  }
116
- return ()=>{
117
- container1.removeEventListener($2bc01e66e04aa9ed$var$AUTOFOCUS_ON_MOUNT, onMountAutoFocus); // We hit a react bug (fixed in v17) with focusing in unmount.
118
- // We need to delay the focus a little to get around it for now.
119
- // See: https://github.com/facebook/react/issues/17894
120
- setTimeout(()=>{
121
- const unmountEvent = new CustomEvent($2bc01e66e04aa9ed$var$AUTOFOCUS_ON_UNMOUNT, $2bc01e66e04aa9ed$var$EVENT_OPTIONS);
122
- container1.addEventListener($2bc01e66e04aa9ed$var$AUTOFOCUS_ON_UNMOUNT, onUnmountAutoFocus);
123
- container1.dispatchEvent(unmountEvent);
124
- if (!unmountEvent.defaultPrevented) $2bc01e66e04aa9ed$var$focus(previouslyFocusedElement !== null && previouslyFocusedElement !== void 0 ? previouslyFocusedElement : document.body, {
125
- select: true
126
- });
127
- // we need to remove the listener after we `dispatchEvent`
128
- container1.removeEventListener($2bc01e66e04aa9ed$var$AUTOFOCUS_ON_UNMOUNT, onUnmountAutoFocus);
129
- $2bc01e66e04aa9ed$var$focusScopesStack.remove(focusScope);
130
- }, 0);
131
- };
132
- }
133
- }, [
134
- container1,
135
- onMountAutoFocus,
136
- onUnmountAutoFocus,
137
- focusScope
138
- ]); // Takes care of looping focus (when tabbing whilst at the edges)
139
- const handleKeyDown = $buum9$react.useCallback((event)=>{
125
+ container.removeEventListener(AUTOFOCUS_ON_UNMOUNT, onUnmountAutoFocus);
126
+ focusScopesStack.remove(focusScope);
127
+ }, 0);
128
+ };
129
+ }
130
+ }, [container, onMountAutoFocus, onUnmountAutoFocus, focusScope]);
131
+ const handleKeyDown = React.useCallback(
132
+ (event) => {
140
133
  if (!loop && !trapped) return;
141
134
  if (focusScope.paused) return;
142
- const isTabKey = event.key === 'Tab' && !event.altKey && !event.ctrlKey && !event.metaKey;
135
+ const isTabKey = event.key === "Tab" && !event.altKey && !event.ctrlKey && !event.metaKey;
143
136
  const focusedElement = document.activeElement;
144
137
  if (isTabKey && focusedElement) {
145
- const container = event.currentTarget;
146
- const [first, last] = $2bc01e66e04aa9ed$var$getTabbableEdges(container);
147
- const hasTabbableElementsInside = first && last; // we can only wrap focus if we have tabbable edges
148
- if (!hasTabbableElementsInside) {
149
- if (focusedElement === container) event.preventDefault();
150
- } else {
151
- if (!event.shiftKey && focusedElement === last) {
152
- event.preventDefault();
153
- if (loop) $2bc01e66e04aa9ed$var$focus(first, {
154
- select: true
155
- });
156
- } else if (event.shiftKey && focusedElement === first) {
157
- event.preventDefault();
158
- if (loop) $2bc01e66e04aa9ed$var$focus(last, {
159
- select: true
160
- });
161
- }
138
+ const container2 = event.currentTarget;
139
+ const [first, last] = getTabbableEdges(container2);
140
+ const hasTabbableElementsInside = first && last;
141
+ if (!hasTabbableElementsInside) {
142
+ if (focusedElement === container2) event.preventDefault();
143
+ } else {
144
+ if (!event.shiftKey && focusedElement === last) {
145
+ event.preventDefault();
146
+ if (loop) focus(first, { select: true });
147
+ } else if (event.shiftKey && focusedElement === first) {
148
+ event.preventDefault();
149
+ if (loop) focus(last, { select: true });
162
150
  }
151
+ }
163
152
  }
164
- }, [
165
- loop,
166
- trapped,
167
- focusScope.paused
168
- ]);
169
- return /*#__PURE__*/ $buum9$react.createElement($buum9$radixuireactprimitive.Primitive.div, ($parcel$interopDefault($buum9$babelruntimehelpersextends))({
170
- tabIndex: -1
171
- }, scopeProps, {
172
- ref: composedRefs,
173
- onKeyDown: handleKeyDown
174
- }));
175
- });
176
- /*#__PURE__*/ Object.assign($2bc01e66e04aa9ed$export$20e40289641fbbb6, {
177
- displayName: $2bc01e66e04aa9ed$var$FOCUS_SCOPE_NAME
178
- });
179
- /* -------------------------------------------------------------------------------------------------
180
- * Utils
181
- * -----------------------------------------------------------------------------------------------*/ /**
182
- * Attempts focusing the first element in a list of candidates.
183
- * Stops when focus has actually moved.
184
- */ function $2bc01e66e04aa9ed$var$focusFirst(candidates, { select: select = false } = {}) {
153
+ },
154
+ [loop, trapped, focusScope.paused]
155
+ );
156
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.div, { tabIndex: -1, ...scopeProps, ref: composedRefs, onKeyDown: handleKeyDown });
157
+ });
158
+ FocusScope.displayName = FOCUS_SCOPE_NAME;
159
+ function focusFirst(candidates, { select = false } = {}) {
185
160
  const previouslyFocusedElement = document.activeElement;
186
- for (const candidate of candidates){
187
- $2bc01e66e04aa9ed$var$focus(candidate, {
188
- select: select
189
- });
190
- if (document.activeElement !== previouslyFocusedElement) return;
161
+ for (const candidate of candidates) {
162
+ focus(candidate, { select });
163
+ if (document.activeElement !== previouslyFocusedElement) return;
191
164
  }
192
- }
193
- /**
194
- * Returns the first and last tabbable elements inside a container.
195
- */ function $2bc01e66e04aa9ed$var$getTabbableEdges(container) {
196
- const candidates = $2bc01e66e04aa9ed$var$getTabbableCandidates(container);
197
- const first = $2bc01e66e04aa9ed$var$findVisible(candidates, container);
198
- const last = $2bc01e66e04aa9ed$var$findVisible(candidates.reverse(), container);
199
- return [
200
- first,
201
- last
202
- ];
203
- }
204
- /**
205
- * Returns a list of potential tabbable candidates.
206
- *
207
- * NOTE: This is only a close approximation. For example it doesn't take into account cases like when
208
- * elements are not visible. This cannot be worked out easily by just reading a property, but rather
209
- * necessitate runtime knowledge (computed styles, etc). We deal with these cases separately.
210
- *
211
- * See: https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker
212
- * Credit: https://github.com/discord/focus-layers/blob/master/src/util/wrapFocus.tsx#L1
213
- */ function $2bc01e66e04aa9ed$var$getTabbableCandidates(container) {
165
+ }
166
+ function getTabbableEdges(container) {
167
+ const candidates = getTabbableCandidates(container);
168
+ const first = findVisible(candidates, container);
169
+ const last = findVisible(candidates.reverse(), container);
170
+ return [first, last];
171
+ }
172
+ function getTabbableCandidates(container) {
214
173
  const nodes = [];
215
174
  const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
216
- acceptNode: (node)=>{
217
- const isHiddenInput = node.tagName === 'INPUT' && node.type === 'hidden';
218
- if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP; // `.tabIndex` is not the same as the `tabindex` attribute. It works on the
219
- // runtime's understanding of tabbability, so this automatically accounts
220
- // for any kind of element that could be tabbed to.
221
- return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
222
- }
175
+ acceptNode: (node) => {
176
+ const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
177
+ if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP;
178
+ return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
179
+ }
223
180
  });
224
- while(walker.nextNode())nodes.push(walker.currentNode); // we do not take into account the order of nodes with positive `tabIndex` as it
225
- // hinders accessibility to have tab order different from visual order.
181
+ while (walker.nextNode()) nodes.push(walker.currentNode);
226
182
  return nodes;
227
- }
228
- /**
229
- * Returns the first visible element in a list.
230
- * NOTE: Only checks visibility up to the `container`.
231
- */ function $2bc01e66e04aa9ed$var$findVisible(elements, container) {
232
- for (const element of elements){
233
- // we stop checking if it's hidden at the `container` level (excluding)
234
- if (!$2bc01e66e04aa9ed$var$isHidden(element, {
235
- upTo: container
236
- })) return element;
183
+ }
184
+ function findVisible(elements, container) {
185
+ for (const element of elements) {
186
+ if (!isHidden(element, { upTo: container })) return element;
237
187
  }
238
- }
239
- function $2bc01e66e04aa9ed$var$isHidden(node, { upTo: upTo }) {
240
- if (getComputedStyle(node).visibility === 'hidden') return true;
241
- while(node){
242
- // we stop at `upTo` (excluding it)
243
- if (upTo !== undefined && node === upTo) return false;
244
- if (getComputedStyle(node).display === 'none') return true;
245
- node = node.parentElement;
188
+ }
189
+ function isHidden(node, { upTo }) {
190
+ if (getComputedStyle(node).visibility === "hidden") return true;
191
+ while (node) {
192
+ if (upTo !== void 0 && node === upTo) return false;
193
+ if (getComputedStyle(node).display === "none") return true;
194
+ node = node.parentElement;
246
195
  }
247
196
  return false;
248
- }
249
- function $2bc01e66e04aa9ed$var$isSelectableInput(element) {
250
- return element instanceof HTMLInputElement && 'select' in element;
251
- }
252
- function $2bc01e66e04aa9ed$var$focus(element, { select: select = false } = {}) {
253
- // only focus if that element is focusable
197
+ }
198
+ function isSelectableInput(element) {
199
+ return element instanceof HTMLInputElement && "select" in element;
200
+ }
201
+ function focus(element, { select = false } = {}) {
254
202
  if (element && element.focus) {
255
- const previouslyFocusedElement = document.activeElement; // NOTE: we prevent scrolling on focus, to minimize jarring transitions for users
256
- element.focus({
257
- preventScroll: true
258
- }); // only select if its not the same element, it supports selection and we need to select
259
- if (element !== previouslyFocusedElement && $2bc01e66e04aa9ed$var$isSelectableInput(element) && select) element.select();
203
+ const previouslyFocusedElement = document.activeElement;
204
+ element.focus({ preventScroll: true });
205
+ if (element !== previouslyFocusedElement && isSelectableInput(element) && select)
206
+ element.select();
260
207
  }
261
- }
262
- /* -------------------------------------------------------------------------------------------------
263
- * FocusScope stack
264
- * -----------------------------------------------------------------------------------------------*/ const $2bc01e66e04aa9ed$var$focusScopesStack = $2bc01e66e04aa9ed$var$createFocusScopesStack();
265
- function $2bc01e66e04aa9ed$var$createFocusScopesStack() {
266
- /** A stack of focus scopes, with the active one at the top */ let stack = [];
208
+ }
209
+ var focusScopesStack = createFocusScopesStack();
210
+ function createFocusScopesStack() {
211
+ let stack = [];
267
212
  return {
268
- add (focusScope) {
269
- // pause the currently active focus scope (at the top of the stack)
270
- const activeFocusScope = stack[0];
271
- if (focusScope !== activeFocusScope) activeFocusScope === null || activeFocusScope === void 0 || activeFocusScope.pause();
272
- // remove in case it already exists (because we'll re-add it at the top of the stack)
273
- stack = $2bc01e66e04aa9ed$var$arrayRemove(stack, focusScope);
274
- stack.unshift(focusScope);
275
- },
276
- remove (focusScope) {
277
- var _stack$;
278
- stack = $2bc01e66e04aa9ed$var$arrayRemove(stack, focusScope);
279
- (_stack$ = stack[0]) === null || _stack$ === void 0 || _stack$.resume();
213
+ add(focusScope) {
214
+ const activeFocusScope = stack[0];
215
+ if (focusScope !== activeFocusScope) {
216
+ activeFocusScope?.pause();
280
217
  }
218
+ stack = arrayRemove(stack, focusScope);
219
+ stack.unshift(focusScope);
220
+ },
221
+ remove(focusScope) {
222
+ stack = arrayRemove(stack, focusScope);
223
+ stack[0]?.resume();
224
+ }
281
225
  };
282
- }
283
- function $2bc01e66e04aa9ed$var$arrayRemove(array, item) {
284
- const updatedArray = [
285
- ...array
286
- ];
226
+ }
227
+ function arrayRemove(array, item) {
228
+ const updatedArray = [...array];
287
229
  const index = updatedArray.indexOf(item);
288
- if (index !== -1) updatedArray.splice(index, 1);
230
+ if (index !== -1) {
231
+ updatedArray.splice(index, 1);
232
+ }
289
233
  return updatedArray;
290
- }
291
- function $2bc01e66e04aa9ed$var$removeLinks(items) {
292
- return items.filter((item)=>item.tagName !== 'A'
293
- );
294
- }
295
- const $2bc01e66e04aa9ed$export$be92b6f5f03c0fe9 = $2bc01e66e04aa9ed$export$20e40289641fbbb6;
296
-
297
-
298
-
299
-
234
+ }
235
+ function removeLinks(items) {
236
+ return items.filter((item) => item.tagName !== "A");
237
+ }
238
+ var Root = FocusScope;
239
+ })();
300
240
  //# sourceMappingURL=index.js.map