@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 +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/index.js +213 -273
- package/dist/index.js.map +7 -1
- package/dist/index.mjs +196 -276
- package/dist/index.mjs.map +7 -1
- package/package.json +6 -6
- package/dist/index.d.ts.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import * as Radix from
|
|
3
|
-
import { Primitive } from
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
30
|
-
|
|
30
|
+
declare const FocusScope: React.ForwardRefExoticComponent<FocusScopeProps & React.RefAttributes<HTMLDivElement>>;
|
|
31
|
+
declare const Root: React.ForwardRefExoticComponent<FocusScopeProps & React.RefAttributes<HTMLDivElement>>;
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
export { FocusScope, type FocusScopeProps, Root };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import * as Radix from
|
|
3
|
-
import { Primitive } from
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
30
|
-
|
|
30
|
+
declare const FocusScope: React.ForwardRefExoticComponent<FocusScopeProps & React.RefAttributes<HTMLDivElement>>;
|
|
31
|
+
declare const Root: React.ForwardRefExoticComponent<FocusScopeProps & React.RefAttributes<HTMLDivElement>>;
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
export { FocusScope, type FocusScopeProps, Root };
|
package/dist/index.js
CHANGED
|
@@ -1,300 +1,240 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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 ===
|
|
135
|
+
const isTabKey = event.key === "Tab" && !event.altKey && !event.ctrlKey && !event.metaKey;
|
|
143
136
|
const focusedElement = document.activeElement;
|
|
144
137
|
if (isTabKey && focusedElement) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
-
|
|
188
|
-
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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);
|
|
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
|
-
|
|
230
|
-
|
|
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
|
|
240
|
-
if (getComputedStyle(node).visibility ===
|
|
241
|
-
while(node){
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
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
|
|
250
|
-
return element instanceof HTMLInputElement &&
|
|
251
|
-
}
|
|
252
|
-
function
|
|
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
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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
|
-
|
|
264
|
-
|
|
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
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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
|
|
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)
|
|
230
|
+
if (index !== -1) {
|
|
231
|
+
updatedArray.splice(index, 1);
|
|
232
|
+
}
|
|
289
233
|
return updatedArray;
|
|
290
|
-
}
|
|
291
|
-
function
|
|
292
|
-
return items.filter((item)=>item.tagName !==
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
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
|