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.
- package/CHANGELOG.md +12 -0
- package/README.md +24 -6
- package/dist/focus-trap.esm.js +112 -70
- package/dist/focus-trap.esm.js.map +1 -1
- package/dist/focus-trap.esm.min.js +2 -2
- package/dist/focus-trap.esm.min.js.map +1 -1
- package/dist/focus-trap.js +112 -72
- package/dist/focus-trap.js.map +1 -1
- package/dist/focus-trap.min.js +2 -2
- package/dist/focus-trap.min.js.map +1 -1
- package/dist/focus-trap.umd.js +112 -72
- package/dist/focus-trap.umd.js.map +1 -1
- package/dist/focus-trap.umd.min.js +2 -2
- package/dist/focus-trap.umd.min.js.map +1 -1
- package/index.js +52 -20
- package/package.json +22 -23
package/dist/focus-trap.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* focus-trap 7.
|
|
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
|
|
38
|
-
|
|
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(
|
|
52
|
-
if (
|
|
53
|
-
var
|
|
54
|
-
if (
|
|
55
|
-
var
|
|
56
|
-
if (
|
|
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 (
|
|
70
|
+
return ("string" === r ? String : Number)(t);
|
|
60
71
|
}
|
|
61
|
-
function _toPropertyKey(
|
|
62
|
-
var
|
|
63
|
-
return
|
|
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) || (
|
|
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
|
-
* @
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
463
|
+
return _getActiveElement(activeElement.shadowRoot);
|
|
428
464
|
}
|
|
429
465
|
return activeElement;
|
|
430
466
|
};
|
|
431
|
-
var
|
|
467
|
+
var _tryFocus = function tryFocus(node) {
|
|
432
468
|
if (node === false) {
|
|
433
469
|
return;
|
|
434
470
|
}
|
|
435
|
-
if (node ===
|
|
471
|
+
if (node === _getActiveElement(document)) {
|
|
436
472
|
return;
|
|
437
473
|
}
|
|
438
474
|
if (!node || !node.focus) {
|
|
439
|
-
|
|
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',
|
|
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(
|
|
468
|
-
var target =
|
|
469
|
-
event =
|
|
470
|
-
|
|
471
|
-
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 (
|
|
496
|
-
var 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 (
|
|
525
|
-
var 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
|
-
|
|
721
|
+
_tryFocus(nextNode);
|
|
684
722
|
} else {
|
|
685
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
756
|
-
}) :
|
|
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',
|
|
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',
|
|
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
|
-
|
|
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
|
-
|
|
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
|