@cleartrip/ct-design-focus-lock 1.1.0

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.
@@ -0,0 +1,1688 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react/jsx-runtime'), require('react')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'react/jsx-runtime', 'react'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.CTDesignSystemFocusLock = {}, global.jsxRuntime, global.React));
5
+ })(this, (function (exports, jsxRuntime, React$1) { 'use strict';
6
+
7
+ function _interopNamespace(e) {
8
+ if (e && e.__esModule) return e;
9
+ var n = Object.create(null);
10
+ if (e) {
11
+ Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default') {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
20
+ }
21
+ n.default = e;
22
+ return Object.freeze(n);
23
+ }
24
+
25
+ var React__namespace = /*#__PURE__*/_interopNamespace(React$1);
26
+
27
+ /******************************************************************************
28
+ Copyright (c) Microsoft Corporation.
29
+
30
+ Permission to use, copy, modify, and/or distribute this software for any
31
+ purpose with or without fee is hereby granted.
32
+
33
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
34
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
35
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
36
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
37
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
38
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39
+ PERFORMANCE OF THIS SOFTWARE.
40
+ ***************************************************************************** */
41
+ /* global Reflect, Promise, SuppressedError, Symbol */
42
+
43
+ var __assign = function () {
44
+ __assign = Object.assign || function __assign(t) {
45
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
46
+ s = arguments[i];
47
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
48
+ }
49
+ return t;
50
+ };
51
+ return __assign.apply(this, arguments);
52
+ };
53
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
54
+ var e = new Error(message);
55
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
56
+ };
57
+
58
+ function _objectWithoutPropertiesLoose(source, excluded) {
59
+ if (source == null) return {};
60
+ var target = {};
61
+ var sourceKeys = Object.keys(source);
62
+ var key, i;
63
+ for (i = 0; i < sourceKeys.length; i++) {
64
+ key = sourceKeys[i];
65
+ if (excluded.indexOf(key) >= 0) continue;
66
+ target[key] = source[key];
67
+ }
68
+ return target;
69
+ }
70
+
71
+ function _extends() {
72
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
73
+ for (var i = 1; i < arguments.length; i++) {
74
+ var source = arguments[i];
75
+ for (var key in source) {
76
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
77
+ target[key] = source[key];
78
+ }
79
+ }
80
+ }
81
+ return target;
82
+ };
83
+ return _extends.apply(this, arguments);
84
+ }
85
+
86
+ /**
87
+ * Copyright (c) 2013-present, Facebook, Inc.
88
+ *
89
+ * This source code is licensed under the MIT license found in the
90
+ * LICENSE file in the root directory of this source tree.
91
+ */
92
+ var ReactPropTypesSecret_1;
93
+ var hasRequiredReactPropTypesSecret;
94
+ function requireReactPropTypesSecret() {
95
+ if (hasRequiredReactPropTypesSecret) return ReactPropTypesSecret_1;
96
+ hasRequiredReactPropTypesSecret = 1;
97
+ var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
98
+ ReactPropTypesSecret_1 = ReactPropTypesSecret;
99
+ return ReactPropTypesSecret_1;
100
+ }
101
+
102
+ /**
103
+ * Copyright (c) 2013-present, Facebook, Inc.
104
+ *
105
+ * This source code is licensed under the MIT license found in the
106
+ * LICENSE file in the root directory of this source tree.
107
+ */
108
+ var factoryWithThrowingShims;
109
+ var hasRequiredFactoryWithThrowingShims;
110
+ function requireFactoryWithThrowingShims() {
111
+ if (hasRequiredFactoryWithThrowingShims) return factoryWithThrowingShims;
112
+ hasRequiredFactoryWithThrowingShims = 1;
113
+ var ReactPropTypesSecret = requireReactPropTypesSecret();
114
+ function emptyFunction() {}
115
+ function emptyFunctionWithReset() {}
116
+ emptyFunctionWithReset.resetWarningCache = emptyFunction;
117
+ factoryWithThrowingShims = function () {
118
+ function shim(props, propName, componentName, location, propFullName, secret) {
119
+ if (secret === ReactPropTypesSecret) {
120
+ // It is still safe when called from React.
121
+ return;
122
+ }
123
+ var err = new Error('Calling PropTypes validators directly is not supported by the `prop-types` package. ' + 'Use PropTypes.checkPropTypes() to call them. ' + 'Read more at http://fb.me/use-check-prop-types');
124
+ err.name = 'Invariant Violation';
125
+ throw err;
126
+ }
127
+ shim.isRequired = shim;
128
+ function getShim() {
129
+ return shim;
130
+ }
131
+ // Important!
132
+ // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.
133
+ var ReactPropTypes = {
134
+ array: shim,
135
+ bigint: shim,
136
+ bool: shim,
137
+ func: shim,
138
+ number: shim,
139
+ object: shim,
140
+ string: shim,
141
+ symbol: shim,
142
+ any: shim,
143
+ arrayOf: getShim,
144
+ element: shim,
145
+ elementType: shim,
146
+ instanceOf: getShim,
147
+ node: shim,
148
+ objectOf: getShim,
149
+ oneOf: getShim,
150
+ oneOfType: getShim,
151
+ shape: getShim,
152
+ exact: getShim,
153
+ checkPropTypes: emptyFunctionWithReset,
154
+ resetWarningCache: emptyFunction
155
+ };
156
+ ReactPropTypes.PropTypes = ReactPropTypes;
157
+ return ReactPropTypes;
158
+ };
159
+ return factoryWithThrowingShims;
160
+ }
161
+
162
+ /**
163
+ * Copyright (c) 2013-present, Facebook, Inc.
164
+ *
165
+ * This source code is licensed under the MIT license found in the
166
+ * LICENSE file in the root directory of this source tree.
167
+ */
168
+ {
169
+ // By explicitly using `prop-types` you are opting into new production behavior.
170
+ // http://fb.me/prop-types-in-prod
171
+ requireFactoryWithThrowingShims()();
172
+ }
173
+
174
+ /**
175
+ * defines a focus group
176
+ */
177
+ var FOCUS_GROUP = 'data-focus-lock';
178
+ /**
179
+ * disables element discovery inside a group marked by key
180
+ */
181
+ var FOCUS_DISABLED = 'data-focus-lock-disabled';
182
+ /**
183
+ * allows uncontrolled focus within the marked area, effectively disabling focus lock for it's content
184
+ */
185
+ var FOCUS_ALLOW = 'data-no-focus-lock';
186
+ /**
187
+ * instructs autofocus engine to pick default autofocus inside a given node
188
+ * can be set on the element or container
189
+ */
190
+ var FOCUS_AUTO = 'data-autofocus-inside';
191
+ /**
192
+ * instructs autofocus to ignore elements within a given node
193
+ * can be set on the element or container
194
+ */
195
+ var FOCUS_NO_AUTOFOCUS = 'data-no-autofocus';
196
+
197
+ /**
198
+ * Assigns a value for a given ref, no matter of the ref format
199
+ * @param {RefObject} ref - a callback function or ref object
200
+ * @param value - a new value
201
+ *
202
+ * @see https://github.com/theKashey/use-callback-ref#assignref
203
+ * @example
204
+ * const refObject = useRef();
205
+ * const refFn = (ref) => {....}
206
+ *
207
+ * assignRef(refObject, "refValue");
208
+ * assignRef(refFn, "refValue");
209
+ */
210
+ function assignRef(ref, value) {
211
+ if (typeof ref === 'function') {
212
+ ref(value);
213
+ } else if (ref) {
214
+ ref.current = value;
215
+ }
216
+ return ref;
217
+ }
218
+
219
+ /**
220
+ * creates a MutableRef with ref change callback
221
+ * @param initialValue - initial ref value
222
+ * @param {Function} callback - a callback to run when value changes
223
+ *
224
+ * @example
225
+ * const ref = useCallbackRef(0, (newValue, oldValue) => console.log(oldValue, '->', newValue);
226
+ * ref.current = 1;
227
+ * // prints 0 -> 1
228
+ *
229
+ * @see https://reactjs.org/docs/hooks-reference.html#useref
230
+ * @see https://github.com/theKashey/use-callback-ref#usecallbackref---to-replace-reactuseref
231
+ * @returns {MutableRefObject}
232
+ */
233
+ function useCallbackRef(initialValue, callback) {
234
+ var ref = React$1.useState(function () {
235
+ return {
236
+ // value
237
+ value: initialValue,
238
+ // last callback
239
+ callback: callback,
240
+ // "memoized" public interface
241
+ facade: {
242
+ get current() {
243
+ return ref.value;
244
+ },
245
+ set current(value) {
246
+ var last = ref.value;
247
+ if (last !== value) {
248
+ ref.value = value;
249
+ ref.callback(value, last);
250
+ }
251
+ }
252
+ }
253
+ };
254
+ })[0];
255
+ // update callback
256
+ ref.callback = callback;
257
+ return ref.facade;
258
+ }
259
+
260
+ /**
261
+ * Merges two or more refs together providing a single interface to set their value
262
+ * @param {RefObject|Ref} refs
263
+ * @returns {MutableRefObject} - a new ref, which translates all changes to {refs}
264
+ *
265
+ * @see {@link mergeRefs} a version without buit-in memoization
266
+ * @see https://github.com/theKashey/use-callback-ref#usemergerefs
267
+ * @example
268
+ * const Component = React.forwardRef((props, ref) => {
269
+ * const ownRef = useRef();
270
+ * const domRef = useMergeRefs([ref, ownRef]); // 👈 merge together
271
+ * return <div ref={domRef}>...</div>
272
+ * }
273
+ */
274
+ function useMergeRefs(refs, defaultValue) {
275
+ return useCallbackRef(defaultValue || null, function (newValue) {
276
+ return refs.forEach(function (ref) {
277
+ return assignRef(ref, newValue);
278
+ });
279
+ });
280
+ }
281
+
282
+ var hiddenGuard = {
283
+ width: '1px',
284
+ height: '0px',
285
+ padding: 0,
286
+ overflow: 'hidden',
287
+ position: 'fixed',
288
+ top: '1px',
289
+ left: '1px'
290
+ };
291
+
292
+ function ItoI(a) {
293
+ return a;
294
+ }
295
+ function innerCreateMedium(defaults, middleware) {
296
+ if (middleware === void 0) {
297
+ middleware = ItoI;
298
+ }
299
+ var buffer = [];
300
+ var assigned = false;
301
+ var medium = {
302
+ read: function () {
303
+ if (assigned) {
304
+ throw new Error('Sidecar: could not `read` from an `assigned` medium. `read` could be used only with `useMedium`.');
305
+ }
306
+ if (buffer.length) {
307
+ return buffer[buffer.length - 1];
308
+ }
309
+ return defaults;
310
+ },
311
+ useMedium: function (data) {
312
+ var item = middleware(data, assigned);
313
+ buffer.push(item);
314
+ return function () {
315
+ buffer = buffer.filter(function (x) {
316
+ return x !== item;
317
+ });
318
+ };
319
+ },
320
+ assignSyncMedium: function (cb) {
321
+ assigned = true;
322
+ while (buffer.length) {
323
+ var cbs = buffer;
324
+ buffer = [];
325
+ cbs.forEach(cb);
326
+ }
327
+ buffer = {
328
+ push: function (x) {
329
+ return cb(x);
330
+ },
331
+ filter: function () {
332
+ return buffer;
333
+ }
334
+ };
335
+ },
336
+ assignMedium: function (cb) {
337
+ assigned = true;
338
+ var pendingQueue = [];
339
+ if (buffer.length) {
340
+ var cbs = buffer;
341
+ buffer = [];
342
+ cbs.forEach(cb);
343
+ pendingQueue = buffer;
344
+ }
345
+ var executeQueue = function () {
346
+ var cbs = pendingQueue;
347
+ pendingQueue = [];
348
+ cbs.forEach(cb);
349
+ };
350
+ var cycle = function () {
351
+ return Promise.resolve().then(executeQueue);
352
+ };
353
+ cycle();
354
+ buffer = {
355
+ push: function (x) {
356
+ pendingQueue.push(x);
357
+ cycle();
358
+ },
359
+ filter: function (filter) {
360
+ pendingQueue = pendingQueue.filter(filter);
361
+ return buffer;
362
+ }
363
+ };
364
+ }
365
+ };
366
+ return medium;
367
+ }
368
+ function createMedium(defaults, middleware) {
369
+ if (middleware === void 0) {
370
+ middleware = ItoI;
371
+ }
372
+ return innerCreateMedium(defaults, middleware);
373
+ }
374
+ // eslint-disable-next-line @typescript-eslint/ban-types
375
+ function createSidecarMedium(options) {
376
+ if (options === void 0) {
377
+ options = {};
378
+ }
379
+ var medium = innerCreateMedium(null);
380
+ medium.options = __assign({
381
+ async: true,
382
+ ssr: false
383
+ }, options);
384
+ return medium;
385
+ }
386
+
387
+ var mediumFocus = createMedium({}, function (_ref) {
388
+ var target = _ref.target,
389
+ currentTarget = _ref.currentTarget;
390
+ return {
391
+ target: target,
392
+ currentTarget: currentTarget
393
+ };
394
+ });
395
+ var mediumBlur = createMedium();
396
+ var mediumEffect = createMedium();
397
+ var mediumSidecar = createSidecarMedium({
398
+ async: true // focus-lock sidecar is not required on the server
399
+ // however, it might be required for JSDOM tests
400
+ // ssr: true,
401
+ });
402
+
403
+ var emptyArray = [];
404
+ var FocusLock$1 = /*#__PURE__*/React__namespace.forwardRef(function FocusLockUI(props, parentRef) {
405
+ var _extends2;
406
+ var _React$useState = React__namespace.useState(),
407
+ realObserved = _React$useState[0],
408
+ setObserved = _React$useState[1];
409
+ var observed = React__namespace.useRef();
410
+ var isActive = React__namespace.useRef(false);
411
+ var originalFocusedElement = React__namespace.useRef(null);
412
+ var children = props.children,
413
+ disabled = props.disabled,
414
+ noFocusGuards = props.noFocusGuards,
415
+ persistentFocus = props.persistentFocus,
416
+ crossFrame = props.crossFrame,
417
+ autoFocus = props.autoFocus;
418
+ props.allowTextSelection;
419
+ var group = props.group,
420
+ className = props.className,
421
+ whiteList = props.whiteList,
422
+ hasPositiveIndices = props.hasPositiveIndices,
423
+ _props$shards = props.shards,
424
+ shards = _props$shards === void 0 ? emptyArray : _props$shards,
425
+ _props$as = props.as,
426
+ Container = _props$as === void 0 ? 'div' : _props$as,
427
+ _props$lockProps = props.lockProps,
428
+ containerProps = _props$lockProps === void 0 ? {} : _props$lockProps,
429
+ SideCar = props.sideCar,
430
+ shouldReturnFocus = props.returnFocus,
431
+ focusOptions = props.focusOptions,
432
+ onActivationCallback = props.onActivation,
433
+ onDeactivationCallback = props.onDeactivation;
434
+ var _React$useState2 = React__namespace.useState({}),
435
+ id = _React$useState2[0]; // SIDE EFFECT CALLBACKS
436
+
437
+ var onActivation = React__namespace.useCallback(function () {
438
+ originalFocusedElement.current = originalFocusedElement.current || document && document.activeElement;
439
+ if (observed.current && onActivationCallback) {
440
+ onActivationCallback(observed.current);
441
+ }
442
+ isActive.current = true;
443
+ }, [onActivationCallback]);
444
+ var onDeactivation = React__namespace.useCallback(function () {
445
+ isActive.current = false;
446
+ if (onDeactivationCallback) {
447
+ onDeactivationCallback(observed.current);
448
+ }
449
+ }, [onDeactivationCallback]);
450
+ React$1.useEffect(function () {
451
+ if (!disabled) {
452
+ // cleanup return focus on trap deactivation
453
+ // sideEffect/returnFocus should happen by this time
454
+ originalFocusedElement.current = null;
455
+ }
456
+ }, []);
457
+ var returnFocus = React__namespace.useCallback(function (allowDefer) {
458
+ var returnFocusTo = originalFocusedElement.current;
459
+ if (returnFocusTo && returnFocusTo.focus) {
460
+ var howToReturnFocus = typeof shouldReturnFocus === 'function' ? shouldReturnFocus(returnFocusTo) : shouldReturnFocus;
461
+ if (howToReturnFocus) {
462
+ var returnFocusOptions = typeof howToReturnFocus === 'object' ? howToReturnFocus : undefined;
463
+ originalFocusedElement.current = null;
464
+ if (allowDefer) {
465
+ // React might return focus after update
466
+ // it's safer to defer the action
467
+ Promise.resolve().then(function () {
468
+ return returnFocusTo.focus(returnFocusOptions);
469
+ });
470
+ } else {
471
+ returnFocusTo.focus(returnFocusOptions);
472
+ }
473
+ }
474
+ }
475
+ }, [shouldReturnFocus]); // MEDIUM CALLBACKS
476
+
477
+ var onFocus = React__namespace.useCallback(function (event) {
478
+ if (isActive.current) {
479
+ mediumFocus.useMedium(event);
480
+ }
481
+ }, []);
482
+ var onBlur = mediumBlur.useMedium; // REF PROPAGATION
483
+ // not using real refs due to race conditions
484
+
485
+ var setObserveNode = React__namespace.useCallback(function (newObserved) {
486
+ if (observed.current !== newObserved) {
487
+ observed.current = newObserved;
488
+ setObserved(newObserved);
489
+ }
490
+ }, []);
491
+ var lockProps = _extends((_extends2 = {}, _extends2[FOCUS_DISABLED] = disabled && 'disabled', _extends2[FOCUS_GROUP] = group, _extends2), containerProps);
492
+ var hasLeadingGuards = noFocusGuards !== true;
493
+ var hasTailingGuards = hasLeadingGuards && noFocusGuards !== 'tail';
494
+ var mergedRef = useMergeRefs([parentRef, setObserveNode]);
495
+ return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, hasLeadingGuards && [/*#__PURE__*/
496
+ // nearest focus guard
497
+ React__namespace.createElement("div", {
498
+ key: "guard-first",
499
+ "data-focus-guard": true,
500
+ tabIndex: disabled ? -1 : 0,
501
+ style: hiddenGuard
502
+ }),
503
+ // first tabbed element guard
504
+ hasPositiveIndices ? /*#__PURE__*/React__namespace.createElement("div", {
505
+ key: "guard-nearest",
506
+ "data-focus-guard": true,
507
+ tabIndex: disabled ? -1 : 1,
508
+ style: hiddenGuard
509
+ }) : null], !disabled && /*#__PURE__*/React__namespace.createElement(SideCar, {
510
+ id: id,
511
+ sideCar: mediumSidecar,
512
+ observed: realObserved,
513
+ disabled: disabled,
514
+ persistentFocus: persistentFocus,
515
+ crossFrame: crossFrame,
516
+ autoFocus: autoFocus,
517
+ whiteList: whiteList,
518
+ shards: shards,
519
+ onActivation: onActivation,
520
+ onDeactivation: onDeactivation,
521
+ returnFocus: returnFocus,
522
+ focusOptions: focusOptions
523
+ }), /*#__PURE__*/React__namespace.createElement(Container, _extends({
524
+ ref: mergedRef
525
+ }, lockProps, {
526
+ className: className,
527
+ onBlur: onBlur,
528
+ onFocus: onFocus
529
+ }), children), hasTailingGuards && /*#__PURE__*/React__namespace.createElement("div", {
530
+ "data-focus-guard": true,
531
+ tabIndex: disabled ? -1 : 0,
532
+ style: hiddenGuard
533
+ }));
534
+ });
535
+ FocusLock$1.propTypes = {};
536
+ FocusLock$1.defaultProps = {
537
+ children: undefined,
538
+ disabled: false,
539
+ returnFocus: false,
540
+ focusOptions: undefined,
541
+ noFocusGuards: false,
542
+ autoFocus: true,
543
+ persistentFocus: false,
544
+ crossFrame: true,
545
+ hasPositiveIndices: undefined,
546
+ allowTextSelection: undefined,
547
+ group: undefined,
548
+ className: undefined,
549
+ whiteList: undefined,
550
+ shards: undefined,
551
+ as: 'div',
552
+ lockProps: {},
553
+ onActivation: undefined,
554
+ onDeactivation: undefined
555
+ };
556
+
557
+ var inheritsLooseExports = {};
558
+ var inheritsLoose = {
559
+ get exports(){ return inheritsLooseExports; },
560
+ set exports(v){ inheritsLooseExports = v; },
561
+ };
562
+
563
+ var setPrototypeOfExports = {};
564
+ var setPrototypeOf = {
565
+ get exports(){ return setPrototypeOfExports; },
566
+ set exports(v){ setPrototypeOfExports = v; },
567
+ };
568
+
569
+ (function (module) {
570
+ function _setPrototypeOf(o, p) {
571
+ module.exports = _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
572
+ o.__proto__ = p;
573
+ return o;
574
+ }, module.exports.__esModule = true, module.exports["default"] = module.exports;
575
+ return _setPrototypeOf(o, p);
576
+ }
577
+ module.exports = _setPrototypeOf, module.exports.__esModule = true, module.exports["default"] = module.exports;
578
+ })(setPrototypeOf);
579
+
580
+ (function (module) {
581
+ var setPrototypeOf = setPrototypeOfExports;
582
+ function _inheritsLoose(subClass, superClass) {
583
+ subClass.prototype = Object.create(superClass.prototype);
584
+ subClass.prototype.constructor = subClass;
585
+ setPrototypeOf(subClass, superClass);
586
+ }
587
+ module.exports = _inheritsLoose, module.exports.__esModule = true, module.exports["default"] = module.exports;
588
+ })(inheritsLoose);
589
+
590
+ var definePropertyExports = {};
591
+ var defineProperty = {
592
+ get exports(){ return definePropertyExports; },
593
+ set exports(v){ definePropertyExports = v; },
594
+ };
595
+
596
+ var toPropertyKeyExports = {};
597
+ var toPropertyKey = {
598
+ get exports(){ return toPropertyKeyExports; },
599
+ set exports(v){ toPropertyKeyExports = v; },
600
+ };
601
+
602
+ var _typeofExports = {};
603
+ var _typeof = {
604
+ get exports(){ return _typeofExports; },
605
+ set exports(v){ _typeofExports = v; },
606
+ };
607
+
608
+ (function (module) {
609
+ function _typeof(o) {
610
+ "@babel/helpers - typeof";
611
+
612
+ return (module.exports = _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
613
+ return typeof o;
614
+ } : function (o) {
615
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
616
+ }, module.exports.__esModule = true, module.exports["default"] = module.exports), _typeof(o);
617
+ }
618
+ module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports;
619
+ })(_typeof);
620
+
621
+ var toPrimitiveExports = {};
622
+ var toPrimitive = {
623
+ get exports(){ return toPrimitiveExports; },
624
+ set exports(v){ toPrimitiveExports = v; },
625
+ };
626
+
627
+ (function (module) {
628
+ var _typeof = _typeofExports["default"];
629
+ function _toPrimitive(input, hint) {
630
+ if (_typeof(input) !== "object" || input === null) return input;
631
+ var prim = input[Symbol.toPrimitive];
632
+ if (prim !== undefined) {
633
+ var res = prim.call(input, hint || "default");
634
+ if (_typeof(res) !== "object") return res;
635
+ throw new TypeError("@@toPrimitive must return a primitive value.");
636
+ }
637
+ return (hint === "string" ? String : Number)(input);
638
+ }
639
+ module.exports = _toPrimitive, module.exports.__esModule = true, module.exports["default"] = module.exports;
640
+ })(toPrimitive);
641
+
642
+ (function (module) {
643
+ var _typeof = _typeofExports["default"];
644
+ var toPrimitive = toPrimitiveExports;
645
+ function _toPropertyKey(arg) {
646
+ var key = toPrimitive(arg, "string");
647
+ return _typeof(key) === "symbol" ? key : String(key);
648
+ }
649
+ module.exports = _toPropertyKey, module.exports.__esModule = true, module.exports["default"] = module.exports;
650
+ })(toPropertyKey);
651
+
652
+ (function (module) {
653
+ var toPropertyKey = toPropertyKeyExports;
654
+ function _defineProperty(obj, key, value) {
655
+ key = toPropertyKey(key);
656
+ if (key in obj) {
657
+ Object.defineProperty(obj, key, {
658
+ value: value,
659
+ enumerable: true,
660
+ configurable: true,
661
+ writable: true
662
+ });
663
+ } else {
664
+ obj[key] = value;
665
+ }
666
+ return obj;
667
+ }
668
+ module.exports = _defineProperty, module.exports.__esModule = true, module.exports["default"] = module.exports;
669
+ })(defineProperty);
670
+
671
+ function _interopDefault$1(ex) {
672
+ return ex && typeof ex === 'object' && 'default' in ex ? ex['default'] : ex;
673
+ }
674
+ var _inheritsLoose = _interopDefault$1(inheritsLooseExports);
675
+ var _defineProperty = _interopDefault$1(definePropertyExports);
676
+ var React = React__namespace.default;
677
+ var React__default = _interopDefault$1(React);
678
+ function withSideEffect(reducePropsToState, handleStateChangeOnClient) {
679
+ function getDisplayName(WrappedComponent) {
680
+ return WrappedComponent.displayName || WrappedComponent.name || 'Component';
681
+ }
682
+ return function wrap(WrappedComponent) {
683
+ var mountedInstances = [];
684
+ var state;
685
+ function emitChange() {
686
+ state = reducePropsToState(mountedInstances.map(function (instance) {
687
+ return instance.props;
688
+ }));
689
+ handleStateChangeOnClient(state);
690
+ }
691
+ var SideEffect = /*#__PURE__*/function (_PureComponent) {
692
+ _inheritsLoose(SideEffect, _PureComponent);
693
+ function SideEffect() {
694
+ return _PureComponent.apply(this, arguments) || this;
695
+ }
696
+
697
+ // Try to use displayName of wrapped component
698
+ SideEffect.peek = function peek() {
699
+ return state;
700
+ };
701
+ var _proto = SideEffect.prototype;
702
+ _proto.componentDidMount = function componentDidMount() {
703
+ mountedInstances.push(this);
704
+ emitChange();
705
+ };
706
+ _proto.componentDidUpdate = function componentDidUpdate() {
707
+ emitChange();
708
+ };
709
+ _proto.componentWillUnmount = function componentWillUnmount() {
710
+ var index = mountedInstances.indexOf(this);
711
+ mountedInstances.splice(index, 1);
712
+ emitChange();
713
+ };
714
+ _proto.render = function render() {
715
+ return /*#__PURE__*/React__default.createElement(WrappedComponent, this.props);
716
+ };
717
+ return SideEffect;
718
+ }(React.PureComponent);
719
+ _defineProperty(SideEffect, "displayName", "SideEffect(" + getDisplayName(WrappedComponent) + ")");
720
+ return SideEffect;
721
+ };
722
+ }
723
+ var lib = withSideEffect;
724
+
725
+ /*
726
+ IE11 support
727
+ */
728
+ var toArray = function (a) {
729
+ var ret = Array(a.length);
730
+ for (var i = 0; i < a.length; ++i) {
731
+ ret[i] = a[i];
732
+ }
733
+ return ret;
734
+ };
735
+ var asArray = function (a) {
736
+ return Array.isArray(a) ? a : [a];
737
+ };
738
+ var getFirst = function (a) {
739
+ return Array.isArray(a) ? a[0] : a;
740
+ };
741
+
742
+ var isElementHidden = function (node) {
743
+ // we can measure only "elements"
744
+ // consider others as "visible"
745
+ if (node.nodeType !== Node.ELEMENT_NODE) {
746
+ return false;
747
+ }
748
+ var computedStyle = window.getComputedStyle(node, null);
749
+ if (!computedStyle || !computedStyle.getPropertyValue) {
750
+ return false;
751
+ }
752
+ return computedStyle.getPropertyValue('display') === 'none' || computedStyle.getPropertyValue('visibility') === 'hidden';
753
+ };
754
+ var getParentNode = function (node) {
755
+ // DOCUMENT_FRAGMENT_NODE can also point on ShadowRoot. In this case .host will point on the next node
756
+ return node.parentNode && node.parentNode.nodeType === Node.DOCUMENT_FRAGMENT_NODE ?
757
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
758
+ node.parentNode.host : node.parentNode;
759
+ };
760
+ var isTopNode = function (node) {
761
+ // @ts-ignore
762
+ return node === document || node && node.nodeType === Node.DOCUMENT_NODE;
763
+ };
764
+ var isVisibleUncached = function (node, checkParent) {
765
+ return !node || isTopNode(node) || !isElementHidden(node) && checkParent(getParentNode(node));
766
+ };
767
+ var isVisibleCached = function (visibilityCache, node) {
768
+ var cached = visibilityCache.get(node);
769
+ if (cached !== undefined) {
770
+ return cached;
771
+ }
772
+ var result = isVisibleUncached(node, isVisibleCached.bind(undefined, visibilityCache));
773
+ visibilityCache.set(node, result);
774
+ return result;
775
+ };
776
+ var isAutoFocusAllowedUncached = function (node, checkParent) {
777
+ return node && !isTopNode(node) ? isAutoFocusAllowed(node) ? checkParent(getParentNode(node)) : false : true;
778
+ };
779
+ var isAutoFocusAllowedCached = function (cache, node) {
780
+ var cached = cache.get(node);
781
+ if (cached !== undefined) {
782
+ return cached;
783
+ }
784
+ var result = isAutoFocusAllowedUncached(node, isAutoFocusAllowedCached.bind(undefined, cache));
785
+ cache.set(node, result);
786
+ return result;
787
+ };
788
+ var getDataset = function (node) {
789
+ // @ts-ignore
790
+ return node.dataset;
791
+ };
792
+ var isHTMLButtonElement = function (node) {
793
+ return node.tagName === 'BUTTON';
794
+ };
795
+ var isHTMLInputElement = function (node) {
796
+ return node.tagName === 'INPUT';
797
+ };
798
+ var isRadioElement = function (node) {
799
+ return isHTMLInputElement(node) && node.type === 'radio';
800
+ };
801
+ var notHiddenInput = function (node) {
802
+ return !((isHTMLInputElement(node) || isHTMLButtonElement(node)) && (node.type === 'hidden' || node.disabled));
803
+ };
804
+ var isAutoFocusAllowed = function (node) {
805
+ var attribute = node.getAttribute(FOCUS_NO_AUTOFOCUS);
806
+ return ![true, 'true', ''].includes(attribute);
807
+ };
808
+ var isGuard = function (node) {
809
+ var _a;
810
+ return Boolean(node && ((_a = getDataset(node)) === null || _a === void 0 ? void 0 : _a.focusGuard));
811
+ };
812
+ var isNotAGuard = function (node) {
813
+ return !isGuard(node);
814
+ };
815
+ var isDefined = function (x) {
816
+ return Boolean(x);
817
+ };
818
+
819
+ var tabSort = function (a, b) {
820
+ var tabDiff = a.tabIndex - b.tabIndex;
821
+ var indexDiff = a.index - b.index;
822
+ if (tabDiff) {
823
+ if (!a.tabIndex) {
824
+ return 1;
825
+ }
826
+ if (!b.tabIndex) {
827
+ return -1;
828
+ }
829
+ }
830
+ return tabDiff || indexDiff;
831
+ };
832
+ var orderByTabIndex = function (nodes, filterNegative, keepGuards) {
833
+ return toArray(nodes).map(function (node, index) {
834
+ return {
835
+ node: node,
836
+ index: index,
837
+ tabIndex: keepGuards && node.tabIndex === -1 ? (node.dataset || {}).focusGuard ? 0 : -1 : node.tabIndex
838
+ };
839
+ }).filter(function (data) {
840
+ return !filterNegative || data.tabIndex >= 0;
841
+ }).sort(tabSort);
842
+ };
843
+
844
+ /**
845
+ * list of the object to be considered as focusable
846
+ */
847
+ var tabbables = ['button:enabled', 'select:enabled', 'textarea:enabled', 'input:enabled',
848
+ // elements with explicit roles will also use explicit tabindex
849
+ // '[role="button"]',
850
+ 'a[href]', 'area[href]', 'summary', 'iframe', 'object', 'embed', 'audio[controls]', 'video[controls]', '[tabindex]', '[contenteditable]', '[autofocus]'];
851
+
852
+ var queryTabbables = tabbables.join(',');
853
+ var queryGuardTabbables = "".concat(queryTabbables, ", [data-focus-guard]");
854
+ var getFocusablesWithShadowDom = function (parent, withGuards) {
855
+ return toArray((parent.shadowRoot || parent).children).reduce(function (acc, child) {
856
+ return acc.concat(child.matches(withGuards ? queryGuardTabbables : queryTabbables) ? [child] : [], getFocusablesWithShadowDom(child));
857
+ }, []);
858
+ };
859
+ var getFocusablesWithIFrame = function (parent, withGuards) {
860
+ var _a;
861
+ // contentDocument of iframe will be null if current origin cannot access it
862
+ if (parent instanceof HTMLIFrameElement && ((_a = parent.contentDocument) === null || _a === void 0 ? void 0 : _a.body)) {
863
+ return getFocusables([parent.contentDocument.body], withGuards);
864
+ }
865
+ return [parent];
866
+ };
867
+ var getFocusables = function (parents, withGuards) {
868
+ return parents.reduce(function (acc, parent) {
869
+ var _a;
870
+ var focusableWithShadowDom = getFocusablesWithShadowDom(parent, withGuards);
871
+ var focusableWithIframes = (_a = []).concat.apply(_a, focusableWithShadowDom.map(function (node) {
872
+ return getFocusablesWithIFrame(node, withGuards);
873
+ }));
874
+ return acc.concat(
875
+ // add all tabbables inside and within shadow DOMs in DOM order
876
+ focusableWithIframes,
877
+ // add if node is tabbable itself
878
+ parent.parentNode ? toArray(parent.parentNode.querySelectorAll(queryTabbables)).filter(function (node) {
879
+ return node === parent;
880
+ }) : []);
881
+ }, []);
882
+ };
883
+ /**
884
+ * return a list of focusable nodes within an area marked as "auto-focusable"
885
+ * @param parent
886
+ */
887
+ var getParentAutofocusables = function (parent) {
888
+ var parentFocus = parent.querySelectorAll("[".concat(FOCUS_AUTO, "]"));
889
+ return toArray(parentFocus).map(function (node) {
890
+ return getFocusables([node]);
891
+ }).reduce(function (acc, nodes) {
892
+ return acc.concat(nodes);
893
+ }, []);
894
+ };
895
+
896
+ /**
897
+ * given list of focusable elements keeps the ones user can interact with
898
+ * @param nodes
899
+ * @param visibilityCache
900
+ */
901
+ var filterFocusable = function (nodes, visibilityCache) {
902
+ return toArray(nodes).filter(function (node) {
903
+ return isVisibleCached(visibilityCache, node);
904
+ }).filter(function (node) {
905
+ return notHiddenInput(node);
906
+ });
907
+ };
908
+ var filterAutoFocusable = function (nodes, cache) {
909
+ if (cache === void 0) {
910
+ cache = new Map();
911
+ }
912
+ return toArray(nodes).filter(function (node) {
913
+ return isAutoFocusAllowedCached(cache, node);
914
+ });
915
+ };
916
+ /**
917
+ * !__WARNING__! Low level API.
918
+ * @returns all tabbable nodes
919
+ *
920
+ * @see {@link getFocusableNodes} to get any focusable element
921
+ *
922
+ * @param topNodes - array of top level HTMLElements to search inside
923
+ * @param visibilityCache - an cache to store intermediate measurements. Expected to be a fresh `new Map` on every call
924
+ */
925
+ var getTabbableNodes = function (topNodes, visibilityCache, withGuards) {
926
+ return orderByTabIndex(filterFocusable(getFocusables(topNodes, withGuards), visibilityCache), true, withGuards);
927
+ };
928
+ /**
929
+ * !__WARNING__! Low level API.
930
+ *
931
+ * @returns anything "focusable", not only tabbable. The difference is in `tabIndex=-1`
932
+ * (without guards, as long as they are not expected to be ever focused)
933
+ *
934
+ * @see {@link getTabbableNodes} to get only tabble nodes element
935
+ *
936
+ * @param topNodes - array of top level HTMLElements to search inside
937
+ * @param visibilityCache - an cache to store intermediate measurements. Expected to be a fresh `new Map` on every call
938
+ */
939
+ var getFocusableNodes = function (topNodes, visibilityCache) {
940
+ return orderByTabIndex(filterFocusable(getFocusables(topNodes), visibilityCache), false);
941
+ };
942
+ /**
943
+ * return list of nodes which are expected to be auto-focused
944
+ * @param topNode
945
+ * @param visibilityCache
946
+ */
947
+ var parentAutofocusables = function (topNode, visibilityCache) {
948
+ return filterFocusable(getParentAutofocusables(topNode), visibilityCache);
949
+ };
950
+ /*
951
+ * Determines if element is contained in scope, including nested shadow DOMs
952
+ */
953
+ var contains = function (scope, element) {
954
+ if (scope.shadowRoot) {
955
+ return contains(scope.shadowRoot, element);
956
+ } else {
957
+ if (Object.getPrototypeOf(scope).contains !== undefined && Object.getPrototypeOf(scope).contains.call(scope, element)) {
958
+ return true;
959
+ }
960
+ return toArray(scope.children).some(function (child) {
961
+ var _a;
962
+ if (child instanceof HTMLIFrameElement) {
963
+ var iframeBody = (_a = child.contentDocument) === null || _a === void 0 ? void 0 : _a.body;
964
+ if (iframeBody) {
965
+ return contains(iframeBody, element);
966
+ }
967
+ return false;
968
+ }
969
+ return contains(child, element);
970
+ });
971
+ }
972
+ };
973
+
974
+ /**
975
+ * in case of multiple nodes nested inside each other
976
+ * keeps only top ones
977
+ * this is O(nlogn)
978
+ * @param nodes
979
+ * @returns {*}
980
+ */
981
+ var filterNested = function (nodes) {
982
+ var contained = new Set();
983
+ var l = nodes.length;
984
+ for (var i = 0; i < l; i += 1) {
985
+ for (var j = i + 1; j < l; j += 1) {
986
+ var position = nodes[i].compareDocumentPosition(nodes[j]);
987
+ /* eslint-disable no-bitwise */
988
+ if ((position & Node.DOCUMENT_POSITION_CONTAINED_BY) > 0) {
989
+ contained.add(j);
990
+ }
991
+ if ((position & Node.DOCUMENT_POSITION_CONTAINS) > 0) {
992
+ contained.add(i);
993
+ }
994
+ /* eslint-enable */
995
+ }
996
+ }
997
+
998
+ return nodes.filter(function (_, index) {
999
+ return !contained.has(index);
1000
+ });
1001
+ };
1002
+ /**
1003
+ * finds top most parent for a node
1004
+ * @param node
1005
+ * @returns {*}
1006
+ */
1007
+ var getTopParent = function (node) {
1008
+ return node.parentNode ? getTopParent(node.parentNode) : node;
1009
+ };
1010
+ /**
1011
+ * returns all "focus containers" inside a given node
1012
+ * @param node - node or nodes to look inside
1013
+ * @returns Element[]
1014
+ */
1015
+ var getAllAffectedNodes = function (node) {
1016
+ var nodes = asArray(node);
1017
+ return nodes.filter(Boolean).reduce(function (acc, currentNode) {
1018
+ var group = currentNode.getAttribute(FOCUS_GROUP);
1019
+ acc.push.apply(acc, group ? filterNested(toArray(getTopParent(currentNode).querySelectorAll("[".concat(FOCUS_GROUP, "=\"").concat(group, "\"]:not([").concat(FOCUS_DISABLED, "=\"disabled\"])")))) : [currentNode]);
1020
+ return acc;
1021
+ }, []);
1022
+ };
1023
+
1024
+ var safeProbe = function (cb) {
1025
+ try {
1026
+ return cb();
1027
+ } catch (e) {
1028
+ return undefined;
1029
+ }
1030
+ };
1031
+
1032
+ /**
1033
+ * returns active element from document or from nested shadowdoms
1034
+ */
1035
+ /**
1036
+ * returns current active element. If the active element is a "container" itself(shadowRoot or iframe) returns active element inside it
1037
+ * @param [inDocument]
1038
+ */
1039
+ var getActiveElement = function (inDocument) {
1040
+ if (inDocument === void 0) {
1041
+ inDocument = document;
1042
+ }
1043
+ if (!inDocument || !inDocument.activeElement) {
1044
+ return undefined;
1045
+ }
1046
+ var activeElement = inDocument.activeElement;
1047
+ return activeElement.shadowRoot ? getActiveElement(activeElement.shadowRoot) : activeElement instanceof HTMLIFrameElement && safeProbe(function () {
1048
+ return activeElement.contentWindow.document;
1049
+ }) ? getActiveElement(activeElement.contentWindow.document) : activeElement;
1050
+ };
1051
+
1052
+ var focusInFrame = function (frame, activeElement) {
1053
+ return frame === activeElement;
1054
+ };
1055
+ var focusInsideIframe = function (topNode, activeElement) {
1056
+ return Boolean(toArray(topNode.querySelectorAll('iframe')).some(function (node) {
1057
+ return focusInFrame(node, activeElement);
1058
+ }));
1059
+ };
1060
+ /**
1061
+ * @returns {Boolean} true, if the current focus is inside given node or nodes.
1062
+ * Supports nodes hidden inside shadowDom
1063
+ */
1064
+ var focusInside = function (topNode, activeElement) {
1065
+ // const activeElement = document && getActiveElement();
1066
+ if (activeElement === void 0) {
1067
+ activeElement = getActiveElement(getFirst(topNode).ownerDocument);
1068
+ }
1069
+ if (!activeElement || activeElement.dataset && activeElement.dataset.focusGuard) {
1070
+ return false;
1071
+ }
1072
+ return getAllAffectedNodes(topNode).some(function (node) {
1073
+ return contains(node, activeElement) || focusInsideIframe(node, activeElement);
1074
+ });
1075
+ };
1076
+
1077
+ /**
1078
+ * checks if focus is hidden FROM the focus-lock
1079
+ * ie contained inside a node focus-lock shall ignore
1080
+ *
1081
+ * This is a utility function coupled with {@link FOCUS_ALLOW} constant
1082
+ *
1083
+ * @returns {boolean} focus is currently is in "allow" area
1084
+ */
1085
+ var focusIsHidden = function (inDocument) {
1086
+ if (inDocument === void 0) {
1087
+ inDocument = document;
1088
+ }
1089
+ var activeElement = getActiveElement(inDocument);
1090
+ if (!activeElement) {
1091
+ return false;
1092
+ }
1093
+ // this does not support setting FOCUS_ALLOW within shadow dom
1094
+ return toArray(inDocument.querySelectorAll("[".concat(FOCUS_ALLOW, "]"))).some(function (node) {
1095
+ return contains(node, activeElement);
1096
+ });
1097
+ };
1098
+
1099
+ var findSelectedRadio = function (node, nodes) {
1100
+ return nodes.filter(isRadioElement).filter(function (el) {
1101
+ return el.name === node.name;
1102
+ }).filter(function (el) {
1103
+ return el.checked;
1104
+ })[0] || node;
1105
+ };
1106
+ var correctNode = function (node, nodes) {
1107
+ if (isRadioElement(node) && node.name) {
1108
+ return findSelectedRadio(node, nodes);
1109
+ }
1110
+ return node;
1111
+ };
1112
+ /**
1113
+ * giving a set of radio inputs keeps only selected (tabbable) ones
1114
+ * @param nodes
1115
+ */
1116
+ var correctNodes = function (nodes) {
1117
+ // IE11 has no Set(array) constructor
1118
+ var resultSet = new Set();
1119
+ nodes.forEach(function (node) {
1120
+ return resultSet.add(correctNode(node, nodes));
1121
+ });
1122
+ // using filter to support IE11
1123
+ return nodes.filter(function (node) {
1124
+ return resultSet.has(node);
1125
+ });
1126
+ };
1127
+
1128
+ var pickFirstFocus = function (nodes) {
1129
+ if (nodes[0] && nodes.length > 1) {
1130
+ return correctNode(nodes[0], nodes);
1131
+ }
1132
+ return nodes[0];
1133
+ };
1134
+ var pickFocusable = function (nodes, index) {
1135
+ if (nodes.length > 1) {
1136
+ return nodes.indexOf(correctNode(nodes[index], nodes));
1137
+ }
1138
+ return index;
1139
+ };
1140
+
1141
+ var NEW_FOCUS = 'NEW_FOCUS';
1142
+ /**
1143
+ * Main solver for the "find next focus" question
1144
+ * @param innerNodes
1145
+ * @param outerNodes
1146
+ * @param activeElement
1147
+ * @param lastNode
1148
+ * @returns {number|string|undefined|*}
1149
+ */
1150
+ var newFocus = function (innerNodes, outerNodes, activeElement, lastNode) {
1151
+ var cnt = innerNodes.length;
1152
+ var firstFocus = innerNodes[0];
1153
+ var lastFocus = innerNodes[cnt - 1];
1154
+ var isOnGuard = isGuard(activeElement);
1155
+ // focus is inside
1156
+ if (activeElement && innerNodes.indexOf(activeElement) >= 0) {
1157
+ return undefined;
1158
+ }
1159
+ var activeIndex = activeElement !== undefined ? outerNodes.indexOf(activeElement) : -1;
1160
+ var lastIndex = lastNode ? outerNodes.indexOf(lastNode) : activeIndex;
1161
+ var lastNodeInside = lastNode ? innerNodes.indexOf(lastNode) : -1;
1162
+ var indexDiff = activeIndex - lastIndex;
1163
+ var firstNodeIndex = outerNodes.indexOf(firstFocus);
1164
+ var lastNodeIndex = outerNodes.indexOf(lastFocus);
1165
+ var correctedNodes = correctNodes(outerNodes);
1166
+ var correctedIndex = activeElement !== undefined ? correctedNodes.indexOf(activeElement) : -1;
1167
+ var correctedIndexDiff = correctedIndex - (lastNode ? correctedNodes.indexOf(lastNode) : activeIndex);
1168
+ var returnFirstNode = pickFocusable(innerNodes, 0);
1169
+ var returnLastNode = pickFocusable(innerNodes, cnt - 1);
1170
+ // new focus
1171
+ if (activeIndex === -1 || lastNodeInside === -1) {
1172
+ return NEW_FOCUS;
1173
+ }
1174
+ // old focus
1175
+ if (!indexDiff && lastNodeInside >= 0) {
1176
+ return lastNodeInside;
1177
+ }
1178
+ // first element
1179
+ if (activeIndex <= firstNodeIndex && isOnGuard && Math.abs(indexDiff) > 1) {
1180
+ return returnLastNode;
1181
+ }
1182
+ // last element
1183
+ if (activeIndex >= lastNodeIndex && isOnGuard && Math.abs(indexDiff) > 1) {
1184
+ return returnFirstNode;
1185
+ }
1186
+ // jump out, but not on the guard
1187
+ if (indexDiff && Math.abs(correctedIndexDiff) > 1) {
1188
+ return lastNodeInside;
1189
+ }
1190
+ // focus above lock
1191
+ if (activeIndex <= firstNodeIndex) {
1192
+ return returnLastNode;
1193
+ }
1194
+ // focus below lock
1195
+ if (activeIndex > lastNodeIndex) {
1196
+ return returnFirstNode;
1197
+ }
1198
+ // index is inside tab order, but outside Lock
1199
+ if (indexDiff) {
1200
+ if (Math.abs(indexDiff) > 1) {
1201
+ return lastNodeInside;
1202
+ }
1203
+ return (cnt + lastNodeInside + indexDiff) % cnt;
1204
+ }
1205
+ // do nothing
1206
+ return undefined;
1207
+ };
1208
+
1209
+ var findAutoFocused = function (autoFocusables) {
1210
+ return function (node) {
1211
+ var _a;
1212
+ var autofocus = (_a = getDataset(node)) === null || _a === void 0 ? void 0 : _a.autofocus;
1213
+ return (
1214
+ // @ts-expect-error
1215
+ node.autofocus ||
1216
+ //
1217
+ autofocus !== undefined && autofocus !== 'false' ||
1218
+ //
1219
+ autoFocusables.indexOf(node) >= 0
1220
+ );
1221
+ };
1222
+ };
1223
+ var pickAutofocus = function (nodesIndexes, orderedNodes, groups) {
1224
+ var nodes = nodesIndexes.map(function (_a) {
1225
+ var node = _a.node;
1226
+ return node;
1227
+ });
1228
+ var autoFocusable = filterAutoFocusable(nodes.filter(findAutoFocused(groups)));
1229
+ if (autoFocusable && autoFocusable.length) {
1230
+ return pickFirstFocus(autoFocusable);
1231
+ }
1232
+ return pickFirstFocus(filterAutoFocusable(orderedNodes));
1233
+ };
1234
+
1235
+ var getParents = function (node, parents) {
1236
+ if (parents === void 0) {
1237
+ parents = [];
1238
+ }
1239
+ parents.push(node);
1240
+ if (node.parentNode) {
1241
+ getParents(node.parentNode.host || node.parentNode, parents);
1242
+ }
1243
+ return parents;
1244
+ };
1245
+ /**
1246
+ * finds a parent for both nodeA and nodeB
1247
+ * @param nodeA
1248
+ * @param nodeB
1249
+ * @returns {boolean|*}
1250
+ */
1251
+ var getCommonParent = function (nodeA, nodeB) {
1252
+ var parentsA = getParents(nodeA);
1253
+ var parentsB = getParents(nodeB);
1254
+ // tslint:disable-next-line:prefer-for-of
1255
+ for (var i = 0; i < parentsA.length; i += 1) {
1256
+ var currentParent = parentsA[i];
1257
+ if (parentsB.indexOf(currentParent) >= 0) {
1258
+ return currentParent;
1259
+ }
1260
+ }
1261
+ return false;
1262
+ };
1263
+ var getTopCommonParent = function (baseActiveElement, leftEntry, rightEntries) {
1264
+ var activeElements = asArray(baseActiveElement);
1265
+ var leftEntries = asArray(leftEntry);
1266
+ var activeElement = activeElements[0];
1267
+ var topCommon = false;
1268
+ leftEntries.filter(Boolean).forEach(function (entry) {
1269
+ topCommon = getCommonParent(topCommon || entry, entry) || topCommon;
1270
+ rightEntries.filter(Boolean).forEach(function (subEntry) {
1271
+ var common = getCommonParent(activeElement, subEntry);
1272
+ if (common) {
1273
+ if (!topCommon || contains(common, topCommon)) {
1274
+ topCommon = common;
1275
+ } else {
1276
+ topCommon = getCommonParent(common, topCommon);
1277
+ }
1278
+ }
1279
+ });
1280
+ });
1281
+ // TODO: add assert here?
1282
+ return topCommon;
1283
+ };
1284
+ /**
1285
+ * return list of nodes which are expected to be autofocused inside a given top nodes
1286
+ * @param entries
1287
+ * @param visibilityCache
1288
+ */
1289
+ var allParentAutofocusables = function (entries, visibilityCache) {
1290
+ return entries.reduce(function (acc, node) {
1291
+ return acc.concat(parentAutofocusables(node, visibilityCache));
1292
+ }, []);
1293
+ };
1294
+
1295
+ var reorderNodes = function (srcNodes, dstNodes) {
1296
+ var remap = new Map();
1297
+ // no Set(dstNodes) for IE11 :(
1298
+ dstNodes.forEach(function (entity) {
1299
+ return remap.set(entity.node, entity);
1300
+ });
1301
+ // remap to dstNodes
1302
+ return srcNodes.map(function (node) {
1303
+ return remap.get(node);
1304
+ }).filter(isDefined);
1305
+ };
1306
+ /**
1307
+ * contains the main logic of the `focus-lock` package.
1308
+ *
1309
+ * ! you probably dont need this function !
1310
+ *
1311
+ * given top node(s) and the last active element returns the element to be focused next
1312
+ * @returns element which should be focused to move focus inside
1313
+ * @param topNode
1314
+ * @param lastNode
1315
+ */
1316
+ var focusSolver = function (topNode, lastNode) {
1317
+ var activeElement = getActiveElement(asArray(topNode).length > 0 ? document : getFirst(topNode).ownerDocument);
1318
+ var entries = getAllAffectedNodes(topNode).filter(isNotAGuard);
1319
+ var commonParent = getTopCommonParent(activeElement || topNode, topNode, entries);
1320
+ var visibilityCache = new Map();
1321
+ var anyFocusable = getFocusableNodes(entries, visibilityCache);
1322
+ var innerElements = getTabbableNodes(entries, visibilityCache).filter(function (_a) {
1323
+ var node = _a.node;
1324
+ return isNotAGuard(node);
1325
+ });
1326
+ if (!innerElements[0]) {
1327
+ innerElements = anyFocusable;
1328
+ if (!innerElements[0]) {
1329
+ return undefined;
1330
+ }
1331
+ }
1332
+ var outerNodes = getFocusableNodes([commonParent], visibilityCache).map(function (_a) {
1333
+ var node = _a.node;
1334
+ return node;
1335
+ });
1336
+ var orderedInnerElements = reorderNodes(outerNodes, innerElements);
1337
+ var innerNodes = orderedInnerElements.map(function (_a) {
1338
+ var node = _a.node;
1339
+ return node;
1340
+ });
1341
+ var newId = newFocus(innerNodes, outerNodes, activeElement, lastNode);
1342
+ if (newId === NEW_FOCUS) {
1343
+ var focusNode = pickAutofocus(anyFocusable, innerNodes, allParentAutofocusables(entries, visibilityCache));
1344
+ if (focusNode) {
1345
+ return {
1346
+ node: focusNode
1347
+ };
1348
+ } else {
1349
+ console.warn('focus-lock: cannot find any node to move focus into');
1350
+ return undefined;
1351
+ }
1352
+ }
1353
+ if (newId === undefined) {
1354
+ return newId;
1355
+ }
1356
+ return orderedInnerElements[newId];
1357
+ };
1358
+
1359
+ /**
1360
+ * @returns list of focusable elements inside a given top node
1361
+ * @see {@link getFocusableNodes} for lower level access
1362
+ */
1363
+ var expandFocusableNodes = function (topNode) {
1364
+ var entries = getAllAffectedNodes(topNode).filter(isNotAGuard);
1365
+ var commonParent = getTopCommonParent(topNode, topNode, entries);
1366
+ var visibilityCache = new Map();
1367
+ var outerNodes = getTabbableNodes([commonParent], visibilityCache, true);
1368
+ var innerElements = getTabbableNodes(entries, visibilityCache).filter(function (_a) {
1369
+ var node = _a.node;
1370
+ return isNotAGuard(node);
1371
+ }).map(function (_a) {
1372
+ var node = _a.node;
1373
+ return node;
1374
+ });
1375
+ return outerNodes.map(function (_a) {
1376
+ var node = _a.node,
1377
+ index = _a.index;
1378
+ return {
1379
+ node: node,
1380
+ index: index,
1381
+ lockItem: innerElements.indexOf(node) >= 0,
1382
+ guard: isGuard(node)
1383
+ };
1384
+ });
1385
+ };
1386
+
1387
+ var focusOn = function (target, focusOptions) {
1388
+ if ('focus' in target) {
1389
+ target.focus(focusOptions);
1390
+ }
1391
+ if ('contentWindow' in target && target.contentWindow) {
1392
+ target.contentWindow.focus();
1393
+ }
1394
+ };
1395
+
1396
+ var guardCount = 0;
1397
+ var lockDisabled = false;
1398
+ /**
1399
+ * The main functionality of the focus-lock package
1400
+ *
1401
+ * Contains focus at a given node.
1402
+ * The last focused element will help to determine which element(first or last) should be focused.
1403
+ * The found element will be focused.
1404
+ *
1405
+ * This is one time action (move), not a persistent focus-lock
1406
+ *
1407
+ * HTML markers (see {@link import('./constants').FOCUS_AUTO} constants) can control autofocus
1408
+ * @see {@link focusSolver} for the same functionality without autofocus
1409
+ */
1410
+ var moveFocusInside = function (topNode, lastNode, options) {
1411
+ if (options === void 0) {
1412
+ options = {};
1413
+ }
1414
+ var focusable = focusSolver(topNode, lastNode);
1415
+ // global local side effect to countain recursive lock activation and resolve focus-fighting
1416
+ if (lockDisabled) {
1417
+ return;
1418
+ }
1419
+ if (focusable) {
1420
+ /** +FOCUS-FIGHTING prevention **/
1421
+ if (guardCount > 2) {
1422
+ // we have recursive entered back the lock activation
1423
+ console.error('FocusLock: focus-fighting detected. Only one focus management system could be active. ' + 'See https://github.com/theKashey/focus-lock/#focus-fighting');
1424
+ lockDisabled = true;
1425
+ setTimeout(function () {
1426
+ lockDisabled = false;
1427
+ }, 1);
1428
+ return;
1429
+ }
1430
+ guardCount++;
1431
+ focusOn(focusable.node, options.focusOptions);
1432
+ guardCount--;
1433
+ }
1434
+ };
1435
+
1436
+ function deferAction(action) {
1437
+ setTimeout(action, 1);
1438
+ }
1439
+
1440
+ /* eslint-disable no-mixed-operators */
1441
+ var focusOnBody = function focusOnBody() {
1442
+ return document && document.activeElement === document.body;
1443
+ };
1444
+ var isFreeFocus = function isFreeFocus() {
1445
+ return focusOnBody() || focusIsHidden();
1446
+ };
1447
+ var lastActiveTrap = null;
1448
+ var lastActiveFocus = null;
1449
+ var lastPortaledElement = null;
1450
+ var focusWasOutsideWindow = false;
1451
+ var defaultWhitelist = function defaultWhitelist() {
1452
+ return true;
1453
+ };
1454
+ var focusWhitelisted = function focusWhitelisted(activeElement) {
1455
+ return (lastActiveTrap.whiteList || defaultWhitelist)(activeElement);
1456
+ };
1457
+ var recordPortal = function recordPortal(observerNode, portaledElement) {
1458
+ lastPortaledElement = {
1459
+ observerNode: observerNode,
1460
+ portaledElement: portaledElement
1461
+ };
1462
+ };
1463
+ var focusIsPortaledPair = function focusIsPortaledPair(element) {
1464
+ return lastPortaledElement && lastPortaledElement.portaledElement === element;
1465
+ };
1466
+ function autoGuard(startIndex, end, step, allNodes) {
1467
+ var lastGuard = null;
1468
+ var i = startIndex;
1469
+ do {
1470
+ var item = allNodes[i];
1471
+ if (item.guard) {
1472
+ if (item.node.dataset.focusAutoGuard) {
1473
+ lastGuard = item;
1474
+ }
1475
+ } else if (item.lockItem) {
1476
+ if (i !== startIndex) {
1477
+ // we will tab to the next element
1478
+ return;
1479
+ }
1480
+ lastGuard = null;
1481
+ } else {
1482
+ break;
1483
+ }
1484
+ } while ((i += step) !== end);
1485
+ if (lastGuard) {
1486
+ lastGuard.node.tabIndex = 0;
1487
+ }
1488
+ }
1489
+ var extractRef = function extractRef(ref) {
1490
+ return ref && 'current' in ref ? ref.current : ref;
1491
+ };
1492
+ var focusWasOutside = function focusWasOutside(crossFrameOption) {
1493
+ if (crossFrameOption) {
1494
+ // with cross frame return true for any value
1495
+ return Boolean(focusWasOutsideWindow);
1496
+ } // in other case return only of focus went a while aho
1497
+
1498
+ return focusWasOutsideWindow === 'meanwhile';
1499
+ };
1500
+ var checkInHost = function checkInHost(check, el, boundary) {
1501
+ return el && (
1502
+ // find host equal to active element and check nested active element
1503
+ el.host === check && (!el.activeElement || boundary.contains(el.activeElement)) // dive up
1504
+ || el.parentNode && checkInHost(check, el.parentNode, boundary));
1505
+ };
1506
+ var withinHost = function withinHost(activeElement, workingArea) {
1507
+ return workingArea.some(function (area) {
1508
+ return checkInHost(activeElement, area, area);
1509
+ });
1510
+ };
1511
+ var activateTrap = function activateTrap() {
1512
+ var result = false;
1513
+ if (lastActiveTrap) {
1514
+ var _lastActiveTrap = lastActiveTrap,
1515
+ observed = _lastActiveTrap.observed,
1516
+ persistentFocus = _lastActiveTrap.persistentFocus,
1517
+ autoFocus = _lastActiveTrap.autoFocus,
1518
+ shards = _lastActiveTrap.shards,
1519
+ crossFrame = _lastActiveTrap.crossFrame,
1520
+ focusOptions = _lastActiveTrap.focusOptions;
1521
+ var workingNode = observed || lastPortaledElement && lastPortaledElement.portaledElement;
1522
+ var activeElement = document && document.activeElement;
1523
+ if (workingNode) {
1524
+ var workingArea = [workingNode].concat(shards.map(extractRef).filter(Boolean));
1525
+ if (!activeElement || focusWhitelisted(activeElement)) {
1526
+ if (persistentFocus || focusWasOutside(crossFrame) || !isFreeFocus() || !lastActiveFocus && autoFocus) {
1527
+ if (workingNode && !(
1528
+ // active element is "inside" working area
1529
+ focusInside(workingArea) ||
1530
+ // check for shadow-dom contained elements
1531
+ activeElement && withinHost(activeElement, workingArea) || focusIsPortaledPair(activeElement))) {
1532
+ if (document && !lastActiveFocus && activeElement && !autoFocus) {
1533
+ // Check if blur() exists, which is missing on certain elements on IE
1534
+ if (activeElement.blur) {
1535
+ activeElement.blur();
1536
+ }
1537
+ document.body.focus();
1538
+ } else {
1539
+ result = moveFocusInside(workingArea, lastActiveFocus, {
1540
+ focusOptions: focusOptions
1541
+ });
1542
+ lastPortaledElement = {};
1543
+ }
1544
+ }
1545
+ focusWasOutsideWindow = false;
1546
+ lastActiveFocus = document && document.activeElement;
1547
+ }
1548
+ }
1549
+ if (document) {
1550
+ var newActiveElement = document && document.activeElement;
1551
+ var allNodes = expandFocusableNodes(workingArea);
1552
+ var focusedIndex = allNodes.map(function (_ref) {
1553
+ var node = _ref.node;
1554
+ return node;
1555
+ }).indexOf(newActiveElement);
1556
+ if (focusedIndex > -1) {
1557
+ // remove old focus
1558
+ allNodes.filter(function (_ref2) {
1559
+ var guard = _ref2.guard,
1560
+ node = _ref2.node;
1561
+ return guard && node.dataset.focusAutoGuard;
1562
+ }).forEach(function (_ref3) {
1563
+ var node = _ref3.node;
1564
+ return node.removeAttribute('tabIndex');
1565
+ });
1566
+ autoGuard(focusedIndex, allNodes.length, +1, allNodes);
1567
+ autoGuard(focusedIndex, -1, -1, allNodes);
1568
+ }
1569
+ }
1570
+ }
1571
+ }
1572
+ return result;
1573
+ };
1574
+ var onTrap = function onTrap(event) {
1575
+ if (activateTrap() && event) {
1576
+ // prevent scroll jump
1577
+ event.stopPropagation();
1578
+ event.preventDefault();
1579
+ }
1580
+ };
1581
+ var onBlur = function onBlur() {
1582
+ return deferAction(activateTrap);
1583
+ };
1584
+ var onFocus = function onFocus(event) {
1585
+ // detect portal
1586
+ var source = event.target;
1587
+ var currentNode = event.currentTarget;
1588
+ if (!currentNode.contains(source)) {
1589
+ recordPortal(currentNode, source);
1590
+ }
1591
+ };
1592
+ var FocusWatcher = function FocusWatcher() {
1593
+ return null;
1594
+ };
1595
+ var onWindowBlur = function onWindowBlur() {
1596
+ focusWasOutsideWindow = 'just'; // using setTimeout to set this variable after React/sidecar reaction
1597
+
1598
+ deferAction(function () {
1599
+ focusWasOutsideWindow = 'meanwhile';
1600
+ });
1601
+ };
1602
+ var attachHandler = function attachHandler() {
1603
+ document.addEventListener('focusin', onTrap);
1604
+ document.addEventListener('focusout', onBlur);
1605
+ window.addEventListener('blur', onWindowBlur);
1606
+ };
1607
+ var detachHandler = function detachHandler() {
1608
+ document.removeEventListener('focusin', onTrap);
1609
+ document.removeEventListener('focusout', onBlur);
1610
+ window.removeEventListener('blur', onWindowBlur);
1611
+ };
1612
+ function reducePropsToState(propsList) {
1613
+ return propsList.filter(function (_ref5) {
1614
+ var disabled = _ref5.disabled;
1615
+ return !disabled;
1616
+ });
1617
+ }
1618
+ function handleStateChangeOnClient(traps) {
1619
+ var trap = traps.slice(-1)[0];
1620
+ if (trap && !lastActiveTrap) {
1621
+ attachHandler();
1622
+ }
1623
+ var lastTrap = lastActiveTrap;
1624
+ var sameTrap = lastTrap && trap && trap.id === lastTrap.id;
1625
+ lastActiveTrap = trap;
1626
+ if (lastTrap && !sameTrap) {
1627
+ lastTrap.onDeactivation(); // return focus only of last trap was removed
1628
+
1629
+ if (!traps.filter(function (_ref6) {
1630
+ var id = _ref6.id;
1631
+ return id === lastTrap.id;
1632
+ }).length) {
1633
+ // allow defer is no other trap is awaiting restore
1634
+ lastTrap.returnFocus(!trap);
1635
+ }
1636
+ }
1637
+ if (trap) {
1638
+ lastActiveFocus = null;
1639
+ if (!sameTrap || lastTrap.observed !== trap.observed) {
1640
+ trap.onActivation();
1641
+ }
1642
+ activateTrap();
1643
+ deferAction(activateTrap);
1644
+ } else {
1645
+ detachHandler();
1646
+ lastActiveFocus = null;
1647
+ }
1648
+ } // bind medium
1649
+
1650
+ mediumFocus.assignSyncMedium(onFocus);
1651
+ mediumBlur.assignMedium(onBlur);
1652
+ mediumEffect.assignMedium(function (cb) {
1653
+ return cb({
1654
+ moveFocusInside: moveFocusInside,
1655
+ focusInside: focusInside
1656
+ });
1657
+ });
1658
+ var FocusTrap = lib(reducePropsToState, handleStateChangeOnClient)(FocusWatcher);
1659
+
1660
+ /* that would be a BREAKING CHANGE!
1661
+ // delaying sidecar execution till the first usage
1662
+ const RequireSideCar = (props) => {
1663
+ // eslint-disable-next-line global-require
1664
+ const SideCar = require('./Trap').default;
1665
+ return <SideCar {...props} />;
1666
+ };
1667
+ */
1668
+
1669
+ var FocusLockCombination = /*#__PURE__*/React__namespace.forwardRef(function FocusLockUICombination(props, ref) {
1670
+ return /*#__PURE__*/React__namespace.createElement(FocusLock$1, _extends({
1671
+ sideCar: FocusTrap,
1672
+ ref: ref
1673
+ }, props));
1674
+ });
1675
+ var _ref = FocusLock$1.propTypes || {};
1676
+ _ref.sideCar;
1677
+ _objectWithoutPropertiesLoose(_ref, ["sideCar"]);
1678
+ FocusLockCombination.propTypes = {};
1679
+
1680
+ var FocusLock = React__namespace.default.forwardRef(function (_a) {
1681
+ var restoreFocus = _a.restoreFocus, disabled = _a.disabled, children = _a.children;
1682
+ return (jsxRuntime.jsx(FocusLockCombination, __assign({ returnFocus: restoreFocus, disabled: disabled, persistentFocus: false, autoFocus: false }, { children: children })));
1683
+ });
1684
+
1685
+ exports.FocusLock = FocusLock;
1686
+
1687
+ }));
1688
+ //# sourceMappingURL=ct-design-focus-lock.umd.js.map