@radix-ui/react-toast 0.1.2-rc.49 → 0.1.2-rc.51

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.
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/react/toast/src/packages/react/toast/src/Toast.tsx","packages/react/toast/src/packages/react/toast/src/index.ts","packages/react/toast/src/index.ts"],"sourcesContent":[null,null,"export * from './Toast';\n"],"names":[],"version":3,"file":"index.d.ts.map"}
1
+ {"mappings":"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","sources":["packages/react/toast/src/packages/react/toast/src/Toast.tsx","packages/react/toast/src/packages/react/toast/src/index.ts","packages/react/toast/src/index.ts"],"sourcesContent":[null,null,"export {\n createToastScope,\n //\n ToastProvider,\n ToastViewport,\n Toast,\n ToastTitle,\n ToastDescription,\n ToastAction,\n ToastClose,\n //\n Provider,\n Viewport,\n Root,\n Title,\n Description,\n Action,\n Close,\n} from './Toast';\nexport type {\n ToastProviderProps,\n ToastViewportProps,\n ToastProps,\n ToastTitleProps,\n ToastDescriptionProps,\n ToastActionProps,\n ToastCloseProps,\n} from './Toast';\n"],"names":[],"version":3,"file":"index.d.ts.map"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ var $iTyic$react = require("react");
3
3
  var $iTyic$reactdom = require("react-dom");
4
4
  var $iTyic$radixuiprimitive = require("@radix-ui/primitive");
5
5
  var $iTyic$radixuireactcomposerefs = require("@radix-ui/react-compose-refs");
6
+ var $iTyic$radixuireactcollection = require("@radix-ui/react-collection");
6
7
  var $iTyic$radixuireactcontext = require("@radix-ui/react-context");
7
8
  var $iTyic$radixuireactdismissablelayer = require("@radix-ui/react-dismissable-layer");
8
9
  var $iTyic$radixuireactpresence = require("@radix-ui/react-presence");
@@ -13,45 +14,29 @@ var $iTyic$radixuireactusecontrollablestate = require("@radix-ui/react-use-contr
13
14
  var $iTyic$radixuireactuselayouteffect = require("@radix-ui/react-use-layout-effect");
14
15
  var $iTyic$radixuireactvisuallyhidden = require("@radix-ui/react-visually-hidden");
15
16
 
16
- function $parcel$exportWildcard(dest, source) {
17
- Object.keys(source).forEach(function(key) {
18
- if (key === 'default' || key === '__esModule' || dest.hasOwnProperty(key)) {
19
- return;
20
- }
21
-
22
- Object.defineProperty(dest, key, {
23
- enumerable: true,
24
- get: function get() {
25
- return source[key];
26
- }
27
- });
28
- });
29
-
30
- return dest;
17
+ function $parcel$export(e, n, v, s) {
18
+ Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
31
19
  }
32
20
  function $parcel$interopDefault(a) {
33
21
  return a && a.__esModule ? a.default : a;
34
22
  }
35
- function $parcel$export(e, n, v, s) {
36
- Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
37
- }
38
- var $9208a85b3e79d33f$exports = {};
39
23
 
40
- $parcel$export($9208a85b3e79d33f$exports, "createToastScope", () => $9208a85b3e79d33f$export$8a359da18fbc9073);
41
- $parcel$export($9208a85b3e79d33f$exports, "ToastProvider", () => $9208a85b3e79d33f$export$f5d03d415824e0e);
42
- $parcel$export($9208a85b3e79d33f$exports, "ToastViewport", () => $9208a85b3e79d33f$export$6192c2425ecfd989);
43
- $parcel$export($9208a85b3e79d33f$exports, "Toast", () => $9208a85b3e79d33f$export$8d8dc7d5f743331b);
44
- $parcel$export($9208a85b3e79d33f$exports, "ToastTitle", () => $9208a85b3e79d33f$export$16d42d7c29b95a4);
45
- $parcel$export($9208a85b3e79d33f$exports, "ToastDescription", () => $9208a85b3e79d33f$export$ecddd96c53621d9a);
46
- $parcel$export($9208a85b3e79d33f$exports, "ToastAction", () => $9208a85b3e79d33f$export$3019feecfda683d2);
47
- $parcel$export($9208a85b3e79d33f$exports, "ToastClose", () => $9208a85b3e79d33f$export$811e70f61c205839);
48
- $parcel$export($9208a85b3e79d33f$exports, "Provider", () => $9208a85b3e79d33f$export$2881499e37b75b9a);
49
- $parcel$export($9208a85b3e79d33f$exports, "Viewport", () => $9208a85b3e79d33f$export$d5c6c08dc2d3ca7);
50
- $parcel$export($9208a85b3e79d33f$exports, "Root", () => $9208a85b3e79d33f$export$be92b6f5f03c0fe9);
51
- $parcel$export($9208a85b3e79d33f$exports, "Title", () => $9208a85b3e79d33f$export$f99233281efd08a0);
52
- $parcel$export($9208a85b3e79d33f$exports, "Description", () => $9208a85b3e79d33f$export$393edc798c47379d);
53
- $parcel$export($9208a85b3e79d33f$exports, "Action", () => $9208a85b3e79d33f$export$e19cd5f9376f8cee);
54
- $parcel$export($9208a85b3e79d33f$exports, "Close", () => $9208a85b3e79d33f$export$f39c2d165cd861fe);
24
+ $parcel$export(module.exports, "createToastScope", () => $9208a85b3e79d33f$export$8a359da18fbc9073);
25
+ $parcel$export(module.exports, "ToastProvider", () => $9208a85b3e79d33f$export$f5d03d415824e0e);
26
+ $parcel$export(module.exports, "ToastViewport", () => $9208a85b3e79d33f$export$6192c2425ecfd989);
27
+ $parcel$export(module.exports, "Toast", () => $9208a85b3e79d33f$export$8d8dc7d5f743331b);
28
+ $parcel$export(module.exports, "ToastTitle", () => $9208a85b3e79d33f$export$16d42d7c29b95a4);
29
+ $parcel$export(module.exports, "ToastDescription", () => $9208a85b3e79d33f$export$ecddd96c53621d9a);
30
+ $parcel$export(module.exports, "ToastAction", () => $9208a85b3e79d33f$export$3019feecfda683d2);
31
+ $parcel$export(module.exports, "ToastClose", () => $9208a85b3e79d33f$export$811e70f61c205839);
32
+ $parcel$export(module.exports, "Provider", () => $9208a85b3e79d33f$export$2881499e37b75b9a);
33
+ $parcel$export(module.exports, "Viewport", () => $9208a85b3e79d33f$export$d5c6c08dc2d3ca7);
34
+ $parcel$export(module.exports, "Root", () => $9208a85b3e79d33f$export$be92b6f5f03c0fe9);
35
+ $parcel$export(module.exports, "Title", () => $9208a85b3e79d33f$export$f99233281efd08a0);
36
+ $parcel$export(module.exports, "Description", () => $9208a85b3e79d33f$export$393edc798c47379d);
37
+ $parcel$export(module.exports, "Action", () => $9208a85b3e79d33f$export$e19cd5f9376f8cee);
38
+ $parcel$export(module.exports, "Close", () => $9208a85b3e79d33f$export$f39c2d165cd861fe);
39
+
55
40
 
56
41
 
57
42
 
@@ -69,7 +54,10 @@ $parcel$export($9208a85b3e79d33f$exports, "Close", () => $9208a85b3e79d33f$expor
69
54
  /* -------------------------------------------------------------------------------------------------
70
55
  * ToastProvider
71
56
  * -----------------------------------------------------------------------------------------------*/ const $9208a85b3e79d33f$var$PROVIDER_NAME = 'ToastProvider';
72
- const [$9208a85b3e79d33f$var$createToastContext, $9208a85b3e79d33f$export$8a359da18fbc9073] = $iTyic$radixuireactcontext.createContextScope('Toast');
57
+ const [$9208a85b3e79d33f$var$Collection, $9208a85b3e79d33f$var$useCollection, $9208a85b3e79d33f$var$createCollectionScope] = $iTyic$radixuireactcollection.createCollection('Toast');
58
+ const [$9208a85b3e79d33f$var$createToastContext, $9208a85b3e79d33f$export$8a359da18fbc9073] = $iTyic$radixuireactcontext.createContextScope('Toast', [
59
+ $9208a85b3e79d33f$var$createCollectionScope
60
+ ]);
73
61
  const [$9208a85b3e79d33f$var$ToastProviderProvider, $9208a85b3e79d33f$var$useToastProviderContext] = $9208a85b3e79d33f$var$createToastContext($9208a85b3e79d33f$var$PROVIDER_NAME);
74
62
  const $9208a85b3e79d33f$export$f5d03d415824e0e = (props)=>{
75
63
  const { __scopeToast: __scopeToast , label: label = 'Notification' , duration: duration = 5000 , swipeDirection: swipeDirection = 'right' , swipeThreshold: swipeThreshold = 50 , children: children } = props;
@@ -77,7 +65,9 @@ const $9208a85b3e79d33f$export$f5d03d415824e0e = (props)=>{
77
65
  const [toastCount, setToastCount] = $iTyic$react.useState(0);
78
66
  const isFocusedToastEscapeKeyDownRef = $iTyic$react.useRef(false);
79
67
  const isClosePausedRef = $iTyic$react.useRef(false);
80
- return /*#__PURE__*/ $iTyic$react.createElement($9208a85b3e79d33f$var$ToastProviderProvider, {
68
+ return /*#__PURE__*/ $iTyic$react.createElement($9208a85b3e79d33f$var$Collection.Provider, {
69
+ scope: __scopeToast
70
+ }, /*#__PURE__*/ $iTyic$react.createElement($9208a85b3e79d33f$var$ToastProviderProvider, {
81
71
  scope: __scopeToast,
82
72
  label: label,
83
73
  duration: duration,
@@ -94,7 +84,7 @@ const $9208a85b3e79d33f$export$f5d03d415824e0e = (props)=>{
94
84
  , []),
95
85
  isFocusedToastEscapeKeyDownRef: isFocusedToastEscapeKeyDownRef,
96
86
  isClosePausedRef: isClosePausedRef
97
- }, children);
87
+ }, children));
98
88
  };
99
89
  $9208a85b3e79d33f$export$f5d03d415824e0e.propTypes = {
100
90
  label (props) {
@@ -119,10 +109,14 @@ const $9208a85b3e79d33f$var$VIEWPORT_RESUME = 'toast.viewportResume';
119
109
  const $9208a85b3e79d33f$export$6192c2425ecfd989 = /*#__PURE__*/ $iTyic$react.forwardRef((props, forwardedRef)=>{
120
110
  const { __scopeToast: __scopeToast , hotkey: hotkey = $9208a85b3e79d33f$var$VIEWPORT_DEFAULT_HOTKEY , label: label = 'Notifications ({hotkey})' , ...viewportProps } = props;
121
111
  const context = $9208a85b3e79d33f$var$useToastProviderContext($9208a85b3e79d33f$var$VIEWPORT_NAME, __scopeToast);
112
+ const getItems = $9208a85b3e79d33f$var$useCollection(__scopeToast);
122
113
  const wrapperRef = $iTyic$react.useRef(null);
114
+ const headFocusProxyRef = $iTyic$react.useRef(null);
115
+ const tailFocusProxyRef = $iTyic$react.useRef(null);
123
116
  const ref = $iTyic$react.useRef(null);
124
117
  const composedRefs = $iTyic$radixuireactcomposerefs.useComposedRefs(forwardedRef, ref, context.onViewportChange);
125
118
  const hotkeyLabel = hotkey.join('+').replace(/Key/g, '').replace(/Digit/g, '');
119
+ const hasToasts = context.toastCount > 0;
126
120
  $iTyic$react.useEffect(()=>{
127
121
  const handleKeyDown = (event)=>{
128
122
  var _ref$current;
@@ -170,33 +164,62 @@ const $9208a85b3e79d33f$export$6192c2425ecfd989 = /*#__PURE__*/ $iTyic$react.for
170
164
  }, [
171
165
  context.isClosePausedRef
172
166
  ]);
167
+ const getSortedTabbableCandidates = $iTyic$react.useCallback(({ tabbingDirection: tabbingDirection })=>{
168
+ const toastItems = getItems();
169
+ const tabbableCandidates = toastItems.map((toastItem)=>{
170
+ const toastNode = toastItem.ref.current;
171
+ const toastTabbableCandidates = [
172
+ toastNode,
173
+ ...$9208a85b3e79d33f$var$getTabbableCandidates(toastNode)
174
+ ];
175
+ return tabbingDirection === 'forwards' ? toastTabbableCandidates : toastTabbableCandidates.reverse();
176
+ });
177
+ return (tabbingDirection === 'forwards' ? tabbableCandidates.reverse() : tabbableCandidates).flat();
178
+ }, [
179
+ getItems
180
+ ]);
173
181
  $iTyic$react.useEffect(()=>{
174
- const viewport = ref.current; // Re-order DOM so most recent toasts are at top of DOM structure to improve tab order
182
+ const viewport = ref.current; // We programmatically manage tabbing as we are unable to influence
183
+ // the source order with portals, this allows us to reverse the
184
+ // tab order so that it runs from most recent toast to least
175
185
  if (viewport) {
176
- const prepended = new Set();
177
- const observer = new MutationObserver((mutations)=>{
178
- const addedNodes = mutations.map((mutation)=>Array.from(mutation.addedNodes)
179
- ).reduce((a, b)=>a.concat(b)
180
- );
181
- addedNodes.forEach((node)=>{
182
- // mutation will immediately fire again when we prepend so we only prepend if
183
- // it hasn't just prepended.
184
- if (!prepended.has(node)) {
185
- viewport.prepend(node);
186
- prepended.add(node);
187
- } else // this else catches the case where the mutation fires immediately after prepend.
188
- // we remove from cache after it prepends to allow observer to catch future updates
189
- // to DOM order, e.g. if `key` changes for a toast and is reportalled to bottom.
190
- prepended.delete(node);
191
- });
192
- });
193
- observer.observe(viewport, {
194
- childList: true
195
- });
196
- return ()=>observer.disconnect()
186
+ const handleKeyDown = (event)=>{
187
+ const isMetaKey = event.altKey || event.ctrlKey || event.metaKey;
188
+ const isTabKey = event.key === 'Tab' && !isMetaKey;
189
+ if (isTabKey) {
190
+ const focusedElement = document.activeElement;
191
+ const isTabbingBackwards = event.shiftKey;
192
+ const targetIsViewport = event.target === viewport; // If we're back tabbing after jumping to the viewport then we simply
193
+ // proxy focus out to the preceding document
194
+ if (targetIsViewport && isTabbingBackwards) {
195
+ var _headFocusProxyRef$cu;
196
+ (_headFocusProxyRef$cu = headFocusProxyRef.current) === null || _headFocusProxyRef$cu === void 0 || _headFocusProxyRef$cu.focus();
197
+ return;
198
+ }
199
+ const tabbingDirection = isTabbingBackwards ? 'backwards' : 'forwards';
200
+ const sortedCandidates = getSortedTabbableCandidates({
201
+ tabbingDirection: tabbingDirection
202
+ });
203
+ const index = sortedCandidates.findIndex((candidate)=>candidate === focusedElement
204
+ );
205
+ if ($9208a85b3e79d33f$var$focusFirst(sortedCandidates.slice(index + 1))) event.preventDefault();
206
+ else {
207
+ var _headFocusProxyRef$cu2, _tailFocusProxyRef$cu;
208
+ // If we can't focus that means we're at the edges so we
209
+ // proxy to the corresponding exit point and let the browser handle
210
+ // tab/shift+tab keypress and implicitly pass focus to the next valid element in the document
211
+ isTabbingBackwards ? (_headFocusProxyRef$cu2 = headFocusProxyRef.current) === null || _headFocusProxyRef$cu2 === void 0 || _headFocusProxyRef$cu2.focus() : (_tailFocusProxyRef$cu = tailFocusProxyRef.current) === null || _tailFocusProxyRef$cu === void 0 || _tailFocusProxyRef$cu.focus();
212
+ }
213
+ }
214
+ }; // Toasts are not in the viewport React tree so we need to bind DOM events
215
+ viewport.addEventListener('keydown', handleKeyDown);
216
+ return ()=>viewport.removeEventListener('keydown', handleKeyDown)
197
217
  ;
198
218
  }
199
- }, []);
219
+ }, [
220
+ getItems,
221
+ getSortedTabbableCandidates
222
+ ]);
200
223
  return /*#__PURE__*/ $iTyic$react.createElement($iTyic$radixuireactdismissablelayer.Branch, {
201
224
  ref: wrapperRef,
202
225
  role: "region",
@@ -205,17 +228,59 @@ const $9208a85b3e79d33f$export$6192c2425ecfd989 = /*#__PURE__*/ $iTyic$react.for
205
228
  tabIndex: -1 // incase list has size when empty (e.g. padding), we remove pointer events so
206
229
  ,
207
230
  style: {
208
- pointerEvents: context.toastCount > 0 ? undefined : 'none'
231
+ pointerEvents: hasToasts ? undefined : 'none'
209
232
  }
233
+ }, hasToasts && /*#__PURE__*/ $iTyic$react.createElement($9208a85b3e79d33f$var$FocusProxy, {
234
+ ref: headFocusProxyRef,
235
+ onFocusFromOutsideViewport: ()=>{
236
+ const tabbableCandidates = getSortedTabbableCandidates({
237
+ tabbingDirection: 'forwards'
238
+ });
239
+ $9208a85b3e79d33f$var$focusFirst(tabbableCandidates);
240
+ }
241
+ }), /*#__PURE__*/ $iTyic$react.createElement($9208a85b3e79d33f$var$Collection.Slot, {
242
+ scope: __scopeToast
210
243
  }, /*#__PURE__*/ $iTyic$react.createElement($iTyic$radixuireactprimitive.Primitive.ol, ($parcel$interopDefault($iTyic$babelruntimehelpersextends))({
211
244
  tabIndex: -1
212
245
  }, viewportProps, {
213
246
  ref: composedRefs
214
- })));
247
+ }))), hasToasts && /*#__PURE__*/ $iTyic$react.createElement($9208a85b3e79d33f$var$FocusProxy, {
248
+ ref: tailFocusProxyRef,
249
+ onFocusFromOutsideViewport: ()=>{
250
+ const tabbableCandidates = getSortedTabbableCandidates({
251
+ tabbingDirection: 'backwards'
252
+ });
253
+ $9208a85b3e79d33f$var$focusFirst(tabbableCandidates);
254
+ }
255
+ }));
215
256
  });
216
257
  /*#__PURE__*/ Object.assign($9208a85b3e79d33f$export$6192c2425ecfd989, {
217
258
  displayName: $9208a85b3e79d33f$var$VIEWPORT_NAME
218
259
  });
260
+ /* -----------------------------------------------------------------------------------------------*/ const $9208a85b3e79d33f$var$FOCUS_PROXY_NAME = 'ToastFocusProxy';
261
+ const $9208a85b3e79d33f$var$FocusProxy = /*#__PURE__*/ $iTyic$react.forwardRef((props, forwardedRef)=>{
262
+ const { __scopeToast: __scopeToast , onFocusFromOutsideViewport: onFocusFromOutsideViewport , ...proxyProps } = props;
263
+ const context = $9208a85b3e79d33f$var$useToastProviderContext($9208a85b3e79d33f$var$FOCUS_PROXY_NAME, __scopeToast);
264
+ return /*#__PURE__*/ $iTyic$react.createElement($iTyic$radixuireactvisuallyhidden.VisuallyHidden, ($parcel$interopDefault($iTyic$babelruntimehelpersextends))({
265
+ "aria-hidden": true,
266
+ tabIndex: 0
267
+ }, proxyProps, {
268
+ ref: forwardedRef // Avoid page scrolling when focus is on the focus proxy
269
+ ,
270
+ style: {
271
+ position: 'fixed'
272
+ },
273
+ onFocus: (event)=>{
274
+ var _context$viewport;
275
+ const prevFocusedElement = event.relatedTarget;
276
+ const isFocusFromOutsideViewport = !((_context$viewport = context.viewport) !== null && _context$viewport !== void 0 && _context$viewport.contains(prevFocusedElement));
277
+ if (isFocusFromOutsideViewport) onFocusFromOutsideViewport();
278
+ }
279
+ }));
280
+ });
281
+ /*#__PURE__*/ Object.assign($9208a85b3e79d33f$var$FocusProxy, {
282
+ displayName: $9208a85b3e79d33f$var$FOCUS_PROXY_NAME
283
+ });
219
284
  /* -------------------------------------------------------------------------------------------------
220
285
  * Toast
221
286
  * -----------------------------------------------------------------------------------------------*/ const $9208a85b3e79d33f$var$TOAST_NAME = 'Toast';
@@ -286,11 +351,11 @@ const $9208a85b3e79d33f$var$ToastImpl = /*#__PURE__*/ $iTyic$react.forwardRef((p
286
351
  const [renderLabel, setRenderLabel] = $iTyic$react.useState(false);
287
352
  const { onToastAdd: onToastAdd , onToastRemove: onToastRemove } = context;
288
353
  const handleClose = $iTyic$radixuireactusecallbackref.useCallbackRef(()=>{
289
- var _ref$current2, _context$viewport;
354
+ var _ref$current2, _context$viewport2;
290
355
  // focus viewport if focus is within toast to read the remaining toast
291
356
  // count to SR users and ensure focus isn't lost
292
357
  const isFocusInToast = (_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.contains(document.activeElement);
293
- if (isFocusInToast) (_context$viewport = context.viewport) === null || _context$viewport === void 0 || _context$viewport.focus();
358
+ if (isFocusInToast) (_context$viewport2 = context.viewport) === null || _context$viewport2 === void 0 || _context$viewport2.focus();
294
359
  onClose();
295
360
  });
296
361
  const startTimer = $iTyic$react.useCallback((duration)=>{
@@ -349,7 +414,9 @@ const $9208a85b3e79d33f$var$ToastImpl = /*#__PURE__*/ $iTyic$react.forwardRef((p
349
414
  scope: __scopeToast,
350
415
  isInteractive: true,
351
416
  onClose: handleClose
352
- }, /*#__PURE__*/ $iTyic$reactdom.createPortal(/*#__PURE__*/ $iTyic$react.createElement($iTyic$radixuireactdismissablelayer.Root, {
417
+ }, /*#__PURE__*/ $iTyic$reactdom.createPortal(/*#__PURE__*/ $iTyic$react.createElement($9208a85b3e79d33f$var$Collection.ItemSlot, {
418
+ scope: __scopeToast
419
+ }, /*#__PURE__*/ $iTyic$react.createElement($iTyic$radixuireactdismissablelayer.Root, {
353
420
  asChild: true,
354
421
  onEscapeKeyDown: $iTyic$radixuiprimitive.composeEventHandlers(onEscapeKeyDown, ()=>{
355
422
  if (!context.isFocusedToastEscapeKeyDownRef.current) handleClose();
@@ -450,7 +517,7 @@ const $9208a85b3e79d33f$var$ToastImpl = /*#__PURE__*/ $iTyic$react.forwardRef((p
450
517
  });
451
518
  }
452
519
  })
453
- }), /*#__PURE__*/ $iTyic$react.createElement($iTyic$radixuireactvisuallyhidden.VisuallyHidden, null, renderLabel && context.label), /*#__PURE__*/ $iTyic$react.createElement($iTyic$radixuireactslot.Slottable, null, children))), context.viewport)));
520
+ }), /*#__PURE__*/ $iTyic$react.createElement($iTyic$radixuireactvisuallyhidden.VisuallyHidden, null, renderLabel && context.label), /*#__PURE__*/ $iTyic$react.createElement($iTyic$radixuireactslot.Slottable, null, children)))), context.viewport)));
454
521
  });
455
522
  $9208a85b3e79d33f$var$ToastImpl.propTypes = {
456
523
  type (props) {
@@ -559,6 +626,39 @@ function $9208a85b3e79d33f$var$useNextFrame(callback = ()=>{}) {
559
626
  fn
560
627
  ]);
561
628
  }
629
+ /**
630
+ * Returns a list of potential tabbable candidates.
631
+ *
632
+ * NOTE: This is only a close approximation. For example it doesn't take into account cases like when
633
+ * elements are not visible. This cannot be worked out easily by just reading a property, but rather
634
+ * necessitate runtime knowledge (computed styles, etc). We deal with these cases separately.
635
+ *
636
+ * See: https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker
637
+ * Credit: https://github.com/discord/focus-layers/blob/master/src/util/wrapFocus.tsx#L1
638
+ */ function $9208a85b3e79d33f$var$getTabbableCandidates(container) {
639
+ const nodes = [];
640
+ const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
641
+ acceptNode: (node)=>{
642
+ const isHiddenInput = node.tagName === 'INPUT' && node.type === 'hidden';
643
+ if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP; // `.tabIndex` is not the same as the `tabindex` attribute. It works on the
644
+ // runtime's understanding of tabbability, so this automatically accounts
645
+ // for any kind of element that could be tabbed to.
646
+ return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
647
+ }
648
+ });
649
+ while(walker.nextNode())nodes.push(walker.currentNode); // we do not take into account the order of nodes with positive `tabIndex` as it
650
+ // hinders accessibility to have tab order different from visual order.
651
+ return nodes;
652
+ }
653
+ function $9208a85b3e79d33f$var$focusFirst(candidates) {
654
+ const previouslyFocusedElement = document.activeElement;
655
+ return candidates.some((candidate)=>{
656
+ // if focus is already where we want to go, we don't want to keep going through the candidates
657
+ if (candidate === previouslyFocusedElement) return true;
658
+ candidate.focus();
659
+ return document.activeElement !== previouslyFocusedElement;
660
+ });
661
+ }
562
662
  const $9208a85b3e79d33f$export$2881499e37b75b9a = $9208a85b3e79d33f$export$f5d03d415824e0e;
563
663
  const $9208a85b3e79d33f$export$d5c6c08dc2d3ca7 = $9208a85b3e79d33f$export$6192c2425ecfd989;
564
664
  const $9208a85b3e79d33f$export$be92b6f5f03c0fe9 = $9208a85b3e79d33f$export$8d8dc7d5f743331b;
@@ -568,7 +668,6 @@ const $9208a85b3e79d33f$export$e19cd5f9376f8cee = $9208a85b3e79d33f$export$3019f
568
668
  const $9208a85b3e79d33f$export$f39c2d165cd861fe = $9208a85b3e79d33f$export$811e70f61c205839;
569
669
 
570
670
 
571
- $parcel$exportWildcard(module.exports, $9208a85b3e79d33f$exports);
572
671
 
573
672
 
574
673
  //# sourceMappingURL=index.js.map