focus-trap 7.5.4 → 7.6.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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * focus-trap 7.5.4
2
+ * focus-trap 7.6.1
3
3
  * @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
4
4
  */
5
5
  (function (global, factory) {
@@ -13,6 +13,28 @@
13
13
  })());
14
14
  })(this, (function (exports, tabbable) { 'use strict';
15
15
 
16
+ function _arrayLikeToArray(r, a) {
17
+ (null == a || a > r.length) && (a = r.length);
18
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
19
+ return n;
20
+ }
21
+ function _arrayWithoutHoles(r) {
22
+ if (Array.isArray(r)) return _arrayLikeToArray(r);
23
+ }
24
+ function _defineProperty(e, r, t) {
25
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
26
+ value: t,
27
+ enumerable: !0,
28
+ configurable: !0,
29
+ writable: !0
30
+ }) : e[r] = t, e;
31
+ }
32
+ function _iterableToArray(r) {
33
+ if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
34
+ }
35
+ function _nonIterableSpread() {
36
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
37
+ }
16
38
  function ownKeys(e, r) {
17
39
  var t = Object.keys(e);
18
40
  if (Object.getOwnPropertySymbols) {
@@ -34,33 +56,29 @@
34
56
  }
35
57
  return e;
36
58
  }
37
- function _defineProperty(obj, key, value) {
38
- key = _toPropertyKey(key);
39
- if (key in obj) {
40
- Object.defineProperty(obj, key, {
41
- value: value,
42
- enumerable: true,
43
- configurable: true,
44
- writable: true
45
- });
46
- } else {
47
- obj[key] = value;
48
- }
49
- return obj;
59
+ function _toConsumableArray(r) {
60
+ return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
50
61
  }
51
- function _toPrimitive(input, hint) {
52
- if (typeof input !== "object" || input === null) return input;
53
- var prim = input[Symbol.toPrimitive];
54
- if (prim !== undefined) {
55
- var res = prim.call(input, hint || "default");
56
- if (typeof res !== "object") return res;
62
+ function _toPrimitive(t, r) {
63
+ if ("object" != typeof t || !t) return t;
64
+ var e = t[Symbol.toPrimitive];
65
+ if (void 0 !== e) {
66
+ var i = e.call(t, r || "default");
67
+ if ("object" != typeof i) return i;
57
68
  throw new TypeError("@@toPrimitive must return a primitive value.");
58
69
  }
59
- return (hint === "string" ? String : Number)(input);
70
+ return ("string" === r ? String : Number)(t);
60
71
  }
61
- function _toPropertyKey(arg) {
62
- var key = _toPrimitive(arg, "string");
63
- return typeof key === "symbol" ? key : String(key);
72
+ function _toPropertyKey(t) {
73
+ var i = _toPrimitive(t, "string");
74
+ return "symbol" == typeof i ? i : i + "";
75
+ }
76
+ function _unsupportedIterableToArray(r, a) {
77
+ if (r) {
78
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
79
+ var t = {}.toString.call(r).slice(8, -1);
80
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
81
+ }
64
82
  }
65
83
 
66
84
  var activeFocusTraps = {
@@ -122,10 +140,8 @@
122
140
  idx = i;
123
141
  return false; // break
124
142
  }
125
-
126
143
  return true; // next
127
144
  });
128
-
129
145
  return idx;
130
146
  };
131
147
 
@@ -238,7 +254,7 @@
238
254
  return state.containerGroups.findIndex(function (_ref) {
239
255
  var container = _ref.container,
240
256
  tabbableNodes = _ref.tabbableNodes;
241
- return container.contains(element) || ( // fall back to explicit tabbable search which will take into consideration any
257
+ return container.contains(element) || (// fall back to explicit tabbable search which will take into consideration any
242
258
  // web components if the `tabbableOptions.getShadowRoot` option was used for
243
259
  // the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't
244
260
  // look inside web components even if open)
@@ -254,25 +270,31 @@
254
270
  * (if a node is explicitly NOT given), or a function that returns any of these
255
271
  * values.
256
272
  * @param {string} optionName
257
- * @returns {undefined | false | HTMLElement | SVGElement} Returns
258
- * `undefined` if the option is not specified; `false` if the option
259
- * resolved to `false` (node explicitly not given); otherwise, the resolved
260
- * DOM node.
273
+ * @param {Object} options
274
+ * @param {boolean} [options.hasFallback] True if the option could be a selector string
275
+ * and the option allows for a fallback scenario in the case where the selector is
276
+ * valid but does not match a node (i.e. the queried node doesn't exist in the DOM).
277
+ * @param {Array} [options.params] Params to pass to the option if it's a function.
278
+ * @returns {undefined | null | false | HTMLElement | SVGElement} Returns
279
+ * `undefined` if the option is not specified; `null` if the option didn't resolve
280
+ * to a node but `options.hasFallback=true`, `false` if the option resolved to `false`
281
+ * (node explicitly not given); otherwise, the resolved DOM node.
261
282
  * @throws {Error} If the option is set, not `false`, and is not, or does not
262
- * resolve to a node.
283
+ * resolve to a node, unless the option is a selector string and `options.hasFallback=true`.
263
284
  */
264
285
  var getNodeForOption = function getNodeForOption(optionName) {
286
+ var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
287
+ _ref2$hasFallback = _ref2.hasFallback,
288
+ hasFallback = _ref2$hasFallback === void 0 ? false : _ref2$hasFallback,
289
+ _ref2$params = _ref2.params,
290
+ params = _ref2$params === void 0 ? [] : _ref2$params;
265
291
  var optionValue = config[optionName];
266
292
  if (typeof optionValue === 'function') {
267
- for (var _len2 = arguments.length, params = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
268
- params[_key2 - 1] = arguments[_key2];
269
- }
270
- optionValue = optionValue.apply(void 0, params);
293
+ optionValue = optionValue.apply(void 0, _toConsumableArray(params));
271
294
  }
272
295
  if (optionValue === true) {
273
296
  optionValue = undefined; // use default value
274
297
  }
275
-
276
298
  if (!optionValue) {
277
299
  if (optionValue === undefined || optionValue === false) {
278
300
  return optionValue;
@@ -284,21 +306,31 @@
284
306
  var node = optionValue; // could be HTMLElement, SVGElement, or non-empty string at this point
285
307
 
286
308
  if (typeof optionValue === 'string') {
287
- node = doc.querySelector(optionValue); // resolve to node, or null if fails
309
+ try {
310
+ node = doc.querySelector(optionValue); // resolve to node, or null if fails
311
+ } catch (err) {
312
+ throw new Error("`".concat(optionName, "` appears to be an invalid selector; error=\"").concat(err.message, "\""));
313
+ }
288
314
  if (!node) {
289
- throw new Error("`".concat(optionName, "` as selector refers to no known node"));
315
+ if (!hasFallback) {
316
+ throw new Error("`".concat(optionName, "` as selector refers to no known node"));
317
+ }
318
+ // else, `node` MUST be `null` because that's what `Document.querySelector()` returns
319
+ // if the selector is valid but doesn't match anything
290
320
  }
291
321
  }
292
322
  return node;
293
323
  };
294
324
  var getInitialFocusNode = function getInitialFocusNode() {
295
- var node = getNodeForOption('initialFocus');
325
+ var node = getNodeForOption('initialFocus', {
326
+ hasFallback: true
327
+ });
296
328
 
297
329
  // false explicitly indicates we want no initialFocus at all
298
330
  if (node === false) {
299
331
  return false;
300
332
  }
301
- if (node === undefined || !tabbable.isFocusable(node, config.tabbableOptions)) {
333
+ if (node === undefined || node && !tabbable.isFocusable(node, config.tabbableOptions)) {
302
334
  // option not specified nor focusable: use fallback options
303
335
  if (findContainerIndex(doc.activeElement) >= 0) {
304
336
  node = doc.activeElement;
@@ -309,6 +341,10 @@
309
341
  // NOTE: `fallbackFocus` option function cannot return `false` (not supported)
310
342
  node = firstTabbableNode || getNodeForOption('fallbackFocus');
311
343
  }
344
+ } else if (node === null) {
345
+ // option is a VALID selector string that doesn't yield a node: use the `fallbackFocus`
346
+ // option instead of the default behavior when the option isn't specified at all
347
+ node = getNodeForOption('fallbackFocus');
312
348
  }
313
349
  if (!node) {
314
350
  throw new Error('Your focus-trap needs to have at least one focusable element');
@@ -418,25 +454,25 @@
418
454
  *
419
455
  * @returns {HTMLElement} The element that currently has the focus
420
456
  **/
421
- var getActiveElement = function getActiveElement(el) {
457
+ var _getActiveElement = function getActiveElement(el) {
422
458
  var activeElement = el.activeElement;
423
459
  if (!activeElement) {
424
460
  return;
425
461
  }
426
462
  if (activeElement.shadowRoot && activeElement.shadowRoot.activeElement !== null) {
427
- return getActiveElement(activeElement.shadowRoot);
463
+ return _getActiveElement(activeElement.shadowRoot);
428
464
  }
429
465
  return activeElement;
430
466
  };
431
- var tryFocus = function tryFocus(node) {
467
+ var _tryFocus = function tryFocus(node) {
432
468
  if (node === false) {
433
469
  return;
434
470
  }
435
- if (node === getActiveElement(document)) {
471
+ if (node === _getActiveElement(document)) {
436
472
  return;
437
473
  }
438
474
  if (!node || !node.focus) {
439
- tryFocus(getInitialFocusNode());
475
+ _tryFocus(getInitialFocusNode());
440
476
  return;
441
477
  }
442
478
  node.focus({
@@ -449,7 +485,9 @@
449
485
  }
450
486
  };
451
487
  var getReturnFocusNode = function getReturnFocusNode(previousActiveElement) {
452
- var node = getNodeForOption('setReturnFocus', previousActiveElement);
488
+ var node = getNodeForOption('setReturnFocus', {
489
+ params: [previousActiveElement]
490
+ });
453
491
  return node ? node : node === false ? false : previousActiveElement;
454
492
  };
455
493
 
@@ -464,11 +502,11 @@
464
502
  * @returns {Node|undefined} The next node, or `undefined` if a next node couldn't be
465
503
  * determined given the current state of the trap.
466
504
  */
467
- var findNextNavNode = function findNextNavNode(_ref2) {
468
- var target = _ref2.target,
469
- event = _ref2.event,
470
- _ref2$isBackward = _ref2.isBackward,
471
- isBackward = _ref2$isBackward === void 0 ? false : _ref2$isBackward;
505
+ var findNextNavNode = function findNextNavNode(_ref3) {
506
+ var target = _ref3.target,
507
+ event = _ref3.event,
508
+ _ref3$isBackward = _ref3.isBackward,
509
+ isBackward = _ref3$isBackward === void 0 ? false : _ref3$isBackward;
472
510
  target = target || getActualTarget(event);
473
511
  updateTabbableNodes();
474
512
  var destinationNode = null;
@@ -492,8 +530,8 @@
492
530
  // REVERSE
493
531
 
494
532
  // is the target the first tabbable node in a group?
495
- var startOfGroupIndex = findIndex(state.tabbableGroups, function (_ref3) {
496
- var firstTabbableNode = _ref3.firstTabbableNode;
533
+ var startOfGroupIndex = findIndex(state.tabbableGroups, function (_ref4) {
534
+ var firstTabbableNode = _ref4.firstTabbableNode;
497
535
  return target === firstTabbableNode;
498
536
  });
499
537
  if (startOfGroupIndex < 0 && (containerGroup.container === target || tabbable.isFocusable(target, config.tabbableOptions) && !tabbable.isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target, false))) {
@@ -521,8 +559,8 @@
521
559
  // FORWARD
522
560
 
523
561
  // is the target the last tabbable node in a group?
524
- var lastOfGroupIndex = findIndex(state.tabbableGroups, function (_ref4) {
525
- var lastTabbableNode = _ref4.lastTabbableNode;
562
+ var lastOfGroupIndex = findIndex(state.tabbableGroups, function (_ref5) {
563
+ var lastTabbableNode = _ref5.lastTabbableNode;
526
564
  return target === lastTabbableNode;
527
565
  });
528
566
  if (lastOfGroupIndex < 0 && (containerGroup.container === target || tabbable.isFocusable(target, config.tabbableOptions) && !tabbable.isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target))) {
@@ -680,9 +718,9 @@
680
718
  });
681
719
  }
682
720
  if (nextNode) {
683
- tryFocus(nextNode);
721
+ _tryFocus(nextNode);
684
722
  } else {
685
- tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
723
+ _tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
686
724
  }
687
725
  }
688
726
  state.recentNavEvent = undefined; // clear
@@ -707,19 +745,21 @@
707
745
  // to where it normally would
708
746
  event.preventDefault();
709
747
  }
710
- tryFocus(destinationNode);
748
+ _tryFocus(destinationNode);
711
749
  }
712
750
  // else, let the browser take care of [shift+]tab and move the focus
713
751
  };
752
+ var checkTabKey = function checkTabKey(event) {
753
+ if (config.isKeyForward(event) || config.isKeyBackward(event)) {
754
+ checkKeyNav(event, config.isKeyBackward(event));
755
+ }
756
+ };
714
757
 
715
- var checkKey = function checkKey(event) {
758
+ // we use a different event phase for the Escape key to allow canceling the event and checking for this in escapeDeactivates
759
+ var checkEscapeKey = function checkEscapeKey(event) {
716
760
  if (isEscapeEvent(event) && valueOrHandler(config.escapeDeactivates, event) !== false) {
717
761
  event.preventDefault();
718
762
  trap.deactivate();
719
- return;
720
- }
721
- if (config.isKeyForward(event) || config.isKeyBackward(event)) {
722
- checkKeyNav(event, config.isKeyBackward(event));
723
763
  }
724
764
  };
725
765
  var checkClick = function checkClick(e) {
@@ -752,8 +792,8 @@
752
792
  // Delay ensures that the focused element doesn't capture the event
753
793
  // that caused the focus trap activation.
754
794
  state.delayInitialFocusTimer = config.delayInitialFocus ? delay(function () {
755
- tryFocus(getInitialFocusNode());
756
- }) : tryFocus(getInitialFocusNode());
795
+ _tryFocus(getInitialFocusNode());
796
+ }) : _tryFocus(getInitialFocusNode());
757
797
  doc.addEventListener('focusin', checkFocusIn, true);
758
798
  doc.addEventListener('mousedown', checkPointerDown, {
759
799
  capture: true,
@@ -767,10 +807,11 @@
767
807
  capture: true,
768
808
  passive: false
769
809
  });
770
- doc.addEventListener('keydown', checkKey, {
810
+ doc.addEventListener('keydown', checkTabKey, {
771
811
  capture: true,
772
812
  passive: false
773
813
  });
814
+ doc.addEventListener('keydown', checkEscapeKey);
774
815
  return trap;
775
816
  };
776
817
  var removeListeners = function removeListeners() {
@@ -781,7 +822,8 @@
781
822
  doc.removeEventListener('mousedown', checkPointerDown, true);
782
823
  doc.removeEventListener('touchstart', checkPointerDown, true);
783
824
  doc.removeEventListener('click', checkClick, true);
784
- doc.removeEventListener('keydown', checkKey, true);
825
+ doc.removeEventListener('keydown', checkTabKey, true);
826
+ doc.removeEventListener('keydown', checkEscapeKey);
785
827
  return trap;
786
828
  };
787
829
 
@@ -800,7 +842,7 @@
800
842
  // If the currently focused is removed then browsers will move focus to the
801
843
  // <body> element. If this happens, try to move focus back into the trap.
802
844
  if (isFocusedNodeRemoved) {
803
- tryFocus(getInitialFocusNode());
845
+ _tryFocus(getInitialFocusNode());
804
846
  }
805
847
  };
806
848
 
@@ -886,7 +928,7 @@
886
928
  var finishDeactivation = function finishDeactivation() {
887
929
  delay(function () {
888
930
  if (returnFocus) {
889
- tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
931
+ _tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
890
932
  }
891
933
  onPostDeactivate === null || onPostDeactivate === void 0 || onPostDeactivate();
892
934
  });
@@ -945,7 +987,5 @@
945
987
 
946
988
  exports.createFocusTrap = createFocusTrap;
947
989
 
948
- Object.defineProperty(exports, '__esModule', { value: true });
949
-
950
990
  }));
951
991
  //# sourceMappingURL=focus-trap.umd.js.map