@dso-toolkit/core 53.0.0 → 53.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.
Files changed (136) hide show
  1. package/dist/cjs/dso-accordion-section.cjs.entry.js +39 -1404
  2. package/dist/cjs/dso-action-list-item.cjs.entry.js +27 -0
  3. package/dist/cjs/dso-action-list.cjs.entry.js +20 -0
  4. package/dist/cjs/dso-annotation-output.cjs.entry.js +1 -1
  5. package/dist/cjs/dso-date-picker.cjs.entry.js +1 -1
  6. package/dist/cjs/dso-dropdown-menu.cjs.entry.js +18 -3
  7. package/dist/cjs/dso-expandable-heading.cjs.entry.js +1 -1
  8. package/dist/cjs/dso-expandable.cjs.entry.js +1433 -2
  9. package/dist/cjs/dso-header.cjs.entry.js +16 -1
  10. package/dist/cjs/dso-helpcenter-panel.cjs.entry.js +2 -2
  11. package/dist/cjs/dso-image-overlay.cjs.entry.js +2 -2
  12. package/dist/cjs/dso-info_2.cjs.entry.js +3 -2
  13. package/dist/cjs/dso-list-button.cjs.entry.js +3 -3
  14. package/dist/cjs/dso-modal.cjs.entry.js +2 -2
  15. package/dist/cjs/dso-ozon-content.cjs.entry.js +1 -1
  16. package/dist/cjs/dso-table.cjs.entry.js +2 -2
  17. package/dist/cjs/dso-toolkit.cjs.js +1 -1
  18. package/dist/cjs/dso-tooltip.cjs.entry.js +1 -1
  19. package/dist/cjs/dso-viewer-grid.cjs.entry.js +2 -2
  20. package/dist/cjs/expandable.interfaces-19b608b9.js +7 -0
  21. package/dist/cjs/{focus-trap.esm-c501d382.js → focus-trap.esm-a5b7273f.js} +134 -51
  22. package/dist/cjs/{has-overflow-b1b4f3f3.js → has-overflow-dd552ec8.js} +3 -4
  23. package/dist/cjs/index.cjs.js +2 -0
  24. package/dist/cjs/{index.esm-03a9e0b4.js → index.esm-0e935715.js} +97 -17
  25. package/dist/cjs/loader.cjs.js +1 -1
  26. package/dist/collection/collection-manifest.json +2 -0
  27. package/dist/collection/components/accordion/accordion.js +1 -1
  28. package/dist/collection/components/accordion/components/accordion-section.css +60 -10
  29. package/dist/collection/components/accordion/components/accordion-section.js +41 -100
  30. package/dist/collection/components/action-list/action-list.css +25 -0
  31. package/dist/collection/components/action-list/action-list.js +42 -0
  32. package/dist/collection/components/action-list/components/action-list-item.css +81 -0
  33. package/dist/collection/components/action-list/components/action-list-item.js +120 -0
  34. package/dist/collection/components/annotation-output/annotation-output.js +1 -1
  35. package/dist/collection/components/date-picker/date-picker.css +1 -1
  36. package/dist/collection/components/date-picker/date-picker.js +1 -1
  37. package/dist/collection/components/dropdown-menu/dropdown-menu.js +36 -1
  38. package/dist/collection/components/expandable/expandable.css +12 -1
  39. package/dist/collection/components/expandable/expandable.interfaces.js +3 -0
  40. package/dist/collection/components/expandable/expandable.js +246 -2
  41. package/dist/collection/components/expandable-heading/expandable-heading.js +1 -1
  42. package/dist/collection/components/header/header.js +18 -2
  43. package/dist/collection/components/list-button/list-button.css +2 -2
  44. package/dist/collection/components/selectable/selectable.css +22 -9
  45. package/dist/collection/components/selectable/selectable.js +2 -1
  46. package/dist/collection/index.js +1 -0
  47. package/dist/components/dropdown-menu.js +17 -1
  48. package/dist/components/dso-accordion-section.js +52 -1407
  49. package/dist/components/dso-action-list-item.d.ts +11 -0
  50. package/dist/components/dso-action-list-item.js +53 -0
  51. package/dist/components/dso-action-list.d.ts +11 -0
  52. package/dist/components/dso-action-list.js +36 -0
  53. package/dist/components/dso-annotation-output.js +1 -1
  54. package/dist/components/dso-date-picker.js +2 -2
  55. package/dist/components/dso-expandable-heading.js +1 -1
  56. package/dist/components/dso-header.js +18 -2
  57. package/dist/components/dso-list-button.js +1 -1
  58. package/dist/components/expandable.js +1440 -4
  59. package/dist/components/focus-trap.esm.js +133 -50
  60. package/dist/components/has-overflow.js +3 -4
  61. package/dist/components/index.d.ts +2 -0
  62. package/dist/components/index.esm.js +97 -17
  63. package/dist/components/index.js +3 -1
  64. package/dist/components/selectable.js +3 -2
  65. package/dist/dso-toolkit/dso-toolkit.esm.js +1 -1
  66. package/dist/dso-toolkit/index.esm.js +1 -1
  67. package/dist/dso-toolkit/{p-e4f667b3.entry.js → p-0b6fa7d3.entry.js} +1 -1
  68. package/dist/dso-toolkit/p-36224d6f.entry.js +1 -0
  69. package/dist/dso-toolkit/{p-9b07b034.entry.js → p-398a8e0b.entry.js} +1 -1
  70. package/dist/dso-toolkit/{p-d2805c02.entry.js → p-3b91c3e9.entry.js} +1 -1
  71. package/dist/dso-toolkit/p-452b1234.js +1 -0
  72. package/dist/dso-toolkit/p-5950644a.js +5 -0
  73. package/dist/dso-toolkit/{p-b3f4645f.entry.js → p-5de8b79a.entry.js} +1 -1
  74. package/dist/dso-toolkit/p-5e50b616.entry.js +1 -0
  75. package/dist/dso-toolkit/p-6a99d7f8.entry.js +1 -0
  76. package/dist/dso-toolkit/p-91963e3d.js +5 -0
  77. package/dist/dso-toolkit/p-96f44d35.entry.js +1 -0
  78. package/dist/dso-toolkit/p-975c172a.entry.js +1 -0
  79. package/dist/dso-toolkit/{p-092dde2f.entry.js → p-a1616935.entry.js} +1 -1
  80. package/dist/dso-toolkit/{p-ba330644.entry.js → p-bb90ea4c.entry.js} +1 -1
  81. package/dist/dso-toolkit/p-bf750b97.js +1 -0
  82. package/dist/dso-toolkit/{p-aab458c4.entry.js → p-c86a5bcb.entry.js} +1 -1
  83. package/dist/dso-toolkit/{p-f2b76233.entry.js → p-cf9b79df.entry.js} +1 -1
  84. package/dist/dso-toolkit/{p-43f3d736.entry.js → p-d10ec2b3.entry.js} +1 -1
  85. package/dist/dso-toolkit/p-e8a6ccf5.entry.js +1 -0
  86. package/dist/dso-toolkit/p-eaae698e.entry.js +1 -0
  87. package/dist/dso-toolkit/p-fa2f1a1c.entry.js +1 -0
  88. package/dist/dso-toolkit/p-fe7ca25f.entry.js +1 -0
  89. package/dist/esm/dso-accordion-section.entry.js +39 -1404
  90. package/dist/esm/dso-action-list-item.entry.js +23 -0
  91. package/dist/esm/dso-action-list.entry.js +16 -0
  92. package/dist/esm/dso-annotation-output.entry.js +1 -1
  93. package/dist/esm/dso-date-picker.entry.js +1 -1
  94. package/dist/esm/dso-dropdown-menu.entry.js +18 -3
  95. package/dist/esm/dso-expandable-heading.entry.js +1 -1
  96. package/dist/esm/dso-expandable.entry.js +1434 -3
  97. package/dist/esm/dso-header.entry.js +16 -1
  98. package/dist/esm/dso-helpcenter-panel.entry.js +2 -2
  99. package/dist/esm/dso-image-overlay.entry.js +2 -2
  100. package/dist/esm/dso-info_2.entry.js +3 -2
  101. package/dist/esm/dso-list-button.entry.js +3 -3
  102. package/dist/esm/dso-modal.entry.js +2 -2
  103. package/dist/esm/dso-ozon-content.entry.js +1 -1
  104. package/dist/esm/dso-table.entry.js +2 -2
  105. package/dist/esm/dso-toolkit.js +1 -1
  106. package/dist/esm/dso-tooltip.entry.js +1 -1
  107. package/dist/esm/dso-viewer-grid.entry.js +2 -2
  108. package/dist/esm/expandable.interfaces-9b1afbe8.js +5 -0
  109. package/dist/esm/{focus-trap.esm-94794d92.js → focus-trap.esm-2a49a38f.js} +134 -51
  110. package/dist/esm/{has-overflow-c44a8a0a.js → has-overflow-fdc85d8f.js} +3 -4
  111. package/dist/esm/{index.esm-8fc07ad8.js → index.esm-3d6c8190.js} +97 -17
  112. package/dist/esm/index.js +1 -0
  113. package/dist/esm/loader.js +1 -1
  114. package/dist/types/components/accordion/accordion.interfaces.d.ts +1 -1
  115. package/dist/types/components/accordion/components/accordion-section.d.ts +4 -8
  116. package/dist/types/components/action-list/action-list.d.ts +5 -0
  117. package/dist/types/components/action-list/components/action-list-item.d.ts +15 -0
  118. package/dist/types/components/dropdown-menu/dropdown-menu.d.ts +5 -0
  119. package/dist/types/components/expandable/expandable.d.ts +25 -1
  120. package/dist/types/components/expandable/expandable.interfaces.d.ts +10 -0
  121. package/dist/types/components/header/header.d.ts +3 -0
  122. package/dist/types/components/modal/modal.controller.d.ts +2 -3
  123. package/dist/types/components/modal/modal.interfaces.d.ts +11 -0
  124. package/dist/types/components.d.ts +77 -0
  125. package/dist/types/index.d.ts +1 -0
  126. package/package.json +11 -11
  127. package/dist/dso-toolkit/p-147ec7bd.entry.js +0 -1
  128. package/dist/dso-toolkit/p-3635427a.js +0 -5
  129. package/dist/dso-toolkit/p-452c7fbb.entry.js +0 -1
  130. package/dist/dso-toolkit/p-460e6134.entry.js +0 -1
  131. package/dist/dso-toolkit/p-4ae40ddc.entry.js +0 -1
  132. package/dist/dso-toolkit/p-4c8426b7.entry.js +0 -1
  133. package/dist/dso-toolkit/p-57ceabab.js +0 -5
  134. package/dist/dso-toolkit/p-d3ed00f6.js +0 -1
  135. package/dist/dso-toolkit/p-e3bd7689.entry.js +0 -1
  136. package/dist/dso-toolkit/p-f3f0d6c9.entry.js +0 -1
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- const index_esm = require('./index.esm-03a9e0b4.js');
3
+ const index_esm = require('./index.esm-0e935715.js');
4
4
 
5
5
  /*!
6
- * focus-trap 7.1.0
6
+ * focus-trap 7.4.3
7
7
  * @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
8
8
  */
9
9
 
@@ -29,6 +29,7 @@ function _objectSpread2(target) {
29
29
  return target;
30
30
  }
31
31
  function _defineProperty(obj, key, value) {
32
+ key = _toPropertyKey(key);
32
33
  if (key in obj) {
33
34
  Object.defineProperty(obj, key, {
34
35
  value: value,
@@ -41,8 +42,21 @@ function _defineProperty(obj, key, value) {
41
42
  }
42
43
  return obj;
43
44
  }
45
+ function _toPrimitive(input, hint) {
46
+ if (typeof input !== "object" || input === null) return input;
47
+ var prim = input[Symbol.toPrimitive];
48
+ if (prim !== undefined) {
49
+ var res = prim.call(input, hint || "default");
50
+ if (typeof res !== "object") return res;
51
+ throw new TypeError("@@toPrimitive must return a primitive value.");
52
+ }
53
+ return (hint === "string" ? String : Number)(input);
54
+ }
55
+ function _toPropertyKey(arg) {
56
+ var key = _toPrimitive(arg, "string");
57
+ return typeof key === "symbol" ? key : String(key);
58
+ }
44
59
 
45
- var rooTrapStack = [];
46
60
  var activeFocusTraps = {
47
61
  activateTrap: function activateTrap(trapStack, trap) {
48
62
  if (trapStack.length > 0) {
@@ -79,6 +93,16 @@ var isEscapeEvent = function isEscapeEvent(e) {
79
93
  var isTabEvent = function isTabEvent(e) {
80
94
  return e.key === 'Tab' || e.keyCode === 9;
81
95
  };
96
+
97
+ // checks for TAB by default
98
+ var isKeyForward = function isKeyForward(e) {
99
+ return isTabEvent(e) && !e.shiftKey;
100
+ };
101
+
102
+ // checks for SHIFT+TAB by default
103
+ var isKeyBackward = function isKeyBackward(e) {
104
+ return isTabEvent(e) && e.shiftKey;
105
+ };
82
106
  var delay = function delay(fn) {
83
107
  return setTimeout(fn, 0);
84
108
  };
@@ -122,15 +146,21 @@ var getActualTarget = function getActualTarget(event) {
122
146
  // composedPath()[0] === event.target always).
123
147
  return event.target.shadowRoot && typeof event.composedPath === 'function' ? event.composedPath()[0] : event.target;
124
148
  };
149
+
150
+ // NOTE: this must be _outside_ `createFocusTrap()` to make sure all traps in this
151
+ // current instance use the same stack if `userOptions.trapStack` isn't specified
152
+ var internalTrapStack = [];
125
153
  var createFocusTrap = function createFocusTrap(elements, userOptions) {
126
154
  // SSR: a live trap shouldn't be created in this type of environment so this
127
155
  // should be safe code to execute if the `document` option isn't specified
128
156
  var doc = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.document) || document;
129
- var trapStack = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.trapStack) || rooTrapStack;
157
+ var trapStack = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.trapStack) || internalTrapStack;
130
158
  var config = _objectSpread2({
131
159
  returnFocusOnDeactivate: true,
132
160
  escapeDeactivates: true,
133
- delayInitialFocus: true
161
+ delayInitialFocus: true,
162
+ isKeyForward: isKeyForward,
163
+ isKeyBackward: isKeyBackward
134
164
  }, userOptions);
135
165
  var state = {
136
166
  // containers given to createFocusTrap()
@@ -182,23 +212,24 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
182
212
  /**
183
213
  * Finds the index of the container that contains the element.
184
214
  * @param {HTMLElement} element
215
+ * @param {Event} [event]
185
216
  * @returns {number} Index of the container in either `state.containers` or
186
217
  * `state.containerGroups` (the order/length of these lists are the same); -1
187
218
  * if the element isn't found.
188
219
  */
189
- var findContainerIndex = function findContainerIndex(element) {
220
+ var findContainerIndex = function findContainerIndex(element, event) {
221
+ var composedPath = typeof (event === null || event === void 0 ? void 0 : event.composedPath) === 'function' ? event.composedPath() : undefined;
190
222
  // NOTE: search `containerGroups` because it's possible a group contains no tabbable
191
223
  // nodes, but still contains focusable nodes (e.g. if they all have `tabindex=-1`)
192
224
  // and we still need to find the element in there
193
225
  return state.containerGroups.findIndex(function (_ref) {
194
226
  var container = _ref.container,
195
227
  tabbableNodes = _ref.tabbableNodes;
196
- return container.contains(element) ||
197
- // fall back to explicit tabbable search which will take into consideration any
228
+ return container.contains(element) || ( // fall back to explicit tabbable search which will take into consideration any
198
229
  // web components if the `tabbableOptions.getShadowRoot` option was used for
199
230
  // the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't
200
231
  // look inside web components even if open)
201
- tabbableNodes.find(function (node) {
232
+ composedPath === null || composedPath === void 0 ? void 0 : composedPath.includes(container)) || tabbableNodes.find(function (node) {
202
233
  return node === element;
203
234
  });
204
235
  });
@@ -254,8 +285,8 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
254
285
  if (node === false) {
255
286
  return false;
256
287
  }
257
- if (node === undefined) {
258
- // option not specified: use fallback options
288
+ if (node === undefined || !index_esm.isFocusable(node, config.tabbableOptions)) {
289
+ // option not specified nor focusable: use fallback options
259
290
  if (findContainerIndex(doc.activeElement) >= 0) {
260
291
  node = doc.activeElement;
261
292
  } else {
@@ -359,25 +390,20 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
359
390
  // so that it precedes the focus event.
360
391
  var checkPointerDown = function checkPointerDown(e) {
361
392
  var target = getActualTarget(e);
362
- if (findContainerIndex(target) >= 0) {
393
+ if (findContainerIndex(target, e) >= 0) {
363
394
  // allow the click since it ocurred inside the trap
364
395
  return;
365
396
  }
366
397
  if (valueOrHandler(config.clickOutsideDeactivates, e)) {
367
398
  // immediately deactivate the trap
368
399
  trap.deactivate({
369
- // if, on deactivation, we should return focus to the node originally-focused
370
- // when the trap was activated (or the configured `setReturnFocus` node),
371
- // then assume it's also OK to return focus to the outside node that was
372
- // just clicked, causing deactivation, as long as that node is focusable;
373
- // if it isn't focusable, then return focus to the original node focused
374
- // on activation (or the configured `setReturnFocus` node)
375
400
  // NOTE: by setting `returnFocus: false`, deactivate() will do nothing,
376
401
  // which will result in the outside click setting focus to the node
377
- // that was clicked, whether it's focusable or not; by setting
402
+ // that was clicked (and if not focusable, to "nothing"); by setting
378
403
  // `returnFocus: true`, we'll attempt to re-focus the node originally-focused
379
- // on activation (or the configured `setReturnFocus` node)
380
- returnFocus: config.returnFocusOnDeactivate && !index_esm.isFocusable(target, config.tabbableOptions)
404
+ // on activation (or the configured `setReturnFocus` node), whether the
405
+ // outside click was on a focusable node or not
406
+ returnFocus: config.returnFocusOnDeactivate
381
407
  });
382
408
  return;
383
409
  }
@@ -397,7 +423,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
397
423
  // In case focus escapes the trap for some strange reason, pull it back in.
398
424
  var checkFocusIn = function checkFocusIn(e) {
399
425
  var target = getActualTarget(e);
400
- var targetContained = findContainerIndex(target) >= 0;
426
+ var targetContained = findContainerIndex(target, e) >= 0;
401
427
 
402
428
  // In Firefox when you Tab out of an iframe the Document is briefly focused.
403
429
  if (targetContained || target instanceof Document) {
@@ -411,31 +437,32 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
411
437
  }
412
438
  };
413
439
 
414
- // Hijack Tab events on the first and last focusable nodes of the trap,
440
+ // Hijack key nav events on the first and last focusable nodes of the trap,
415
441
  // in order to prevent focus from escaping. If it escapes for even a
416
442
  // moment it can end up scrolling the page and causing confusion so we
417
443
  // kind of need to capture the action at the keydown phase.
418
- var checkTab = function checkTab(e) {
419
- var target = getActualTarget(e);
444
+ var checkKeyNav = function checkKeyNav(event) {
445
+ var isBackward = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
446
+ var target = getActualTarget(event);
420
447
  updateTabbableNodes();
421
448
  var destinationNode = null;
422
449
  if (state.tabbableGroups.length > 0) {
423
450
  // make sure the target is actually contained in a group
424
451
  // NOTE: the target may also be the container itself if it's focusable
425
452
  // with tabIndex='-1' and was given initial focus
426
- var containerIndex = findContainerIndex(target);
453
+ var containerIndex = findContainerIndex(target, event);
427
454
  var containerGroup = containerIndex >= 0 ? state.containerGroups[containerIndex] : undefined;
428
455
  if (containerIndex < 0) {
429
456
  // target not found in any group: quite possible focus has escaped the trap,
430
- // so bring it back in to...
431
- if (e.shiftKey) {
457
+ // so bring it back into...
458
+ if (isBackward) {
432
459
  // ...the last node in the last group
433
460
  destinationNode = state.tabbableGroups[state.tabbableGroups.length - 1].lastTabbableNode;
434
461
  } else {
435
462
  // ...the first node in the first group
436
463
  destinationNode = state.tabbableGroups[0].firstTabbableNode;
437
464
  }
438
- } else if (e.shiftKey) {
465
+ } else if (isBackward) {
439
466
  // REVERSE
440
467
 
441
468
  // is the target the first tabbable node in a group?
@@ -459,6 +486,10 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
459
486
  var destinationGroupIndex = startOfGroupIndex === 0 ? state.tabbableGroups.length - 1 : startOfGroupIndex - 1;
460
487
  var destinationGroup = state.tabbableGroups[destinationGroupIndex];
461
488
  destinationNode = destinationGroup.lastTabbableNode;
489
+ } else if (!isTabEvent(event)) {
490
+ // user must have customized the nav keys so we have to move focus manually _within_
491
+ // the active group: do this based on the order determined by tabbable()
492
+ destinationNode = containerGroup.nextTabbableNode(target, false);
462
493
  }
463
494
  } else {
464
495
  // FORWARD
@@ -484,33 +515,43 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
484
515
  var _destinationGroupIndex = lastOfGroupIndex === state.tabbableGroups.length - 1 ? 0 : lastOfGroupIndex + 1;
485
516
  var _destinationGroup = state.tabbableGroups[_destinationGroupIndex];
486
517
  destinationNode = _destinationGroup.firstTabbableNode;
518
+ } else if (!isTabEvent(event)) {
519
+ // user must have customized the nav keys so we have to move focus manually _within_
520
+ // the active group: do this based on the order determined by tabbable()
521
+ destinationNode = containerGroup.nextTabbableNode(target);
487
522
  }
488
523
  }
489
524
  } else {
525
+ // no groups available
490
526
  // NOTE: the fallbackFocus option does not support returning false to opt-out
491
527
  destinationNode = getNodeForOption('fallbackFocus');
492
528
  }
493
529
  if (destinationNode) {
494
- e.preventDefault();
530
+ if (isTabEvent(event)) {
531
+ // since tab natively moves focus, we wouldn't have a destination node unless we
532
+ // were on the edge of a container and had to move to the next/previous edge, in
533
+ // which case we want to prevent default to keep the browser from moving focus
534
+ // to where it normally would
535
+ event.preventDefault();
536
+ }
495
537
  tryFocus(destinationNode);
496
538
  }
497
539
  // else, let the browser take care of [shift+]tab and move the focus
498
540
  };
499
541
 
500
- var checkKey = function checkKey(e) {
501
- if (isEscapeEvent(e) && valueOrHandler(config.escapeDeactivates, e) !== false) {
502
- e.preventDefault();
542
+ var checkKey = function checkKey(event) {
543
+ if (isEscapeEvent(event) && valueOrHandler(config.escapeDeactivates, event) !== false) {
544
+ event.preventDefault();
503
545
  trap.deactivate();
504
546
  return;
505
547
  }
506
- if (isTabEvent(e)) {
507
- checkTab(e);
508
- return;
548
+ if (config.isKeyForward(event) || config.isKeyBackward(event)) {
549
+ checkKeyNav(event, config.isKeyBackward(event));
509
550
  }
510
551
  };
511
552
  var checkClick = function checkClick(e) {
512
553
  var target = getActualTarget(e);
513
- if (findContainerIndex(target) >= 0) {
554
+ if (findContainerIndex(target, e) >= 0) {
514
555
  return;
515
556
  }
516
557
  if (valueOrHandler(config.clickOutsideDeactivates, e)) {
@@ -571,6 +612,43 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
571
612
  return trap;
572
613
  };
573
614
 
615
+ //
616
+ // MUTATION OBSERVER
617
+ //
618
+
619
+ var checkDomRemoval = function checkDomRemoval(mutations) {
620
+ var isFocusedNodeRemoved = mutations.some(function (mutation) {
621
+ var removedNodes = Array.from(mutation.removedNodes);
622
+ return removedNodes.some(function (node) {
623
+ return node === state.mostRecentlyFocusedNode;
624
+ });
625
+ });
626
+
627
+ // If the currently focused is removed then browsers will move focus to the
628
+ // <body> element. If this happens, try to move focus back into the trap.
629
+ if (isFocusedNodeRemoved) {
630
+ tryFocus(getInitialFocusNode());
631
+ }
632
+ };
633
+
634
+ // Use MutationObserver - if supported - to detect if focused node is removed
635
+ // from the DOM.
636
+ var mutationObserver = typeof window !== 'undefined' && 'MutationObserver' in window ? new MutationObserver(checkDomRemoval) : undefined;
637
+ var updateObservedNodes = function updateObservedNodes() {
638
+ if (!mutationObserver) {
639
+ return;
640
+ }
641
+ mutationObserver.disconnect();
642
+ if (state.active && !state.paused) {
643
+ state.containers.map(function (container) {
644
+ mutationObserver.observe(container, {
645
+ subtree: true,
646
+ childList: true
647
+ });
648
+ });
649
+ }
650
+ };
651
+
574
652
  //
575
653
  // TRAP DEFINITION
576
654
  //
@@ -595,17 +673,14 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
595
673
  state.active = true;
596
674
  state.paused = false;
597
675
  state.nodeFocusedBeforeActivation = doc.activeElement;
598
- if (onActivate) {
599
- onActivate();
600
- }
676
+ onActivate === null || onActivate === void 0 ? void 0 : onActivate();
601
677
  var finishActivation = function finishActivation() {
602
678
  if (checkCanFocusTrap) {
603
679
  updateTabbableNodes();
604
680
  }
605
681
  addListeners();
606
- if (onPostActivate) {
607
- onPostActivate();
608
- }
682
+ updateObservedNodes();
683
+ onPostActivate === null || onPostActivate === void 0 ? void 0 : onPostActivate();
609
684
  };
610
685
  if (checkCanFocusTrap) {
611
686
  checkCanFocusTrap(state.containers.concat()).then(finishActivation, finishActivation);
@@ -628,22 +703,19 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
628
703
  removeListeners();
629
704
  state.active = false;
630
705
  state.paused = false;
706
+ updateObservedNodes();
631
707
  activeFocusTraps.deactivateTrap(trapStack, trap);
632
708
  var onDeactivate = getOption(options, 'onDeactivate');
633
709
  var onPostDeactivate = getOption(options, 'onPostDeactivate');
634
710
  var checkCanReturnFocus = getOption(options, 'checkCanReturnFocus');
635
711
  var returnFocus = getOption(options, 'returnFocus', 'returnFocusOnDeactivate');
636
- if (onDeactivate) {
637
- onDeactivate();
638
- }
712
+ onDeactivate === null || onDeactivate === void 0 ? void 0 : onDeactivate();
639
713
  var finishDeactivation = function finishDeactivation() {
640
714
  delay(function () {
641
715
  if (returnFocus) {
642
716
  tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
643
717
  }
644
- if (onPostDeactivate) {
645
- onPostDeactivate();
646
- }
718
+ onPostDeactivate === null || onPostDeactivate === void 0 ? void 0 : onPostDeactivate();
647
719
  });
648
720
  };
649
721
  if (returnFocus && checkCanReturnFocus) {
@@ -653,21 +725,31 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
653
725
  finishDeactivation();
654
726
  return this;
655
727
  },
656
- pause: function pause() {
728
+ pause: function pause(pauseOptions) {
657
729
  if (state.paused || !state.active) {
658
730
  return this;
659
731
  }
732
+ var onPause = getOption(pauseOptions, 'onPause');
733
+ var onPostPause = getOption(pauseOptions, 'onPostPause');
660
734
  state.paused = true;
735
+ onPause === null || onPause === void 0 ? void 0 : onPause();
661
736
  removeListeners();
737
+ updateObservedNodes();
738
+ onPostPause === null || onPostPause === void 0 ? void 0 : onPostPause();
662
739
  return this;
663
740
  },
664
- unpause: function unpause() {
741
+ unpause: function unpause(unpauseOptions) {
665
742
  if (!state.paused || !state.active) {
666
743
  return this;
667
744
  }
745
+ var onUnpause = getOption(unpauseOptions, 'onUnpause');
746
+ var onPostUnpause = getOption(unpauseOptions, 'onPostUnpause');
668
747
  state.paused = false;
748
+ onUnpause === null || onUnpause === void 0 ? void 0 : onUnpause();
669
749
  updateTabbableNodes();
670
750
  addListeners();
751
+ updateObservedNodes();
752
+ onPostUnpause === null || onPostUnpause === void 0 ? void 0 : onPostUnpause();
671
753
  return this;
672
754
  },
673
755
  updateContainerElements: function updateContainerElements(containerElements) {
@@ -678,6 +760,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
678
760
  if (state.active) {
679
761
  updateTabbableNodes();
680
762
  }
763
+ updateObservedNodes();
681
764
  return this;
682
765
  }
683
766
  };
@@ -163,7 +163,7 @@ var round = Math.round;
163
163
  function getUAString() {
164
164
  var uaData = navigator.userAgentData;
165
165
 
166
- if (uaData != null && uaData.brands) {
166
+ if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {
167
167
  return uaData.brands.map(function (item) {
168
168
  return item.brand + "/" + item.version;
169
169
  }).join(' ');
@@ -482,10 +482,9 @@ var unsetSides = {
482
482
  // Zooming can change the DPR, but it seems to report a value that will
483
483
  // cleanly divide the values into the appropriate subpixels.
484
484
 
485
- function roundOffsetsByDPR(_ref) {
485
+ function roundOffsetsByDPR(_ref, win) {
486
486
  var x = _ref.x,
487
487
  y = _ref.y;
488
- var win = window;
489
488
  var dpr = win.devicePixelRatio || 1;
490
489
  return {
491
490
  x: round(x * dpr) / dpr || 0,
@@ -568,7 +567,7 @@ function mapToStyles(_ref2) {
568
567
  var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
569
568
  x: x,
570
569
  y: y
571
- }) : {
570
+ }, getWindow(popper)) : {
572
571
  x: x,
573
572
  y: y
574
573
  };
@@ -2,6 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ const expandable_interfaces = require('./expandable.interfaces-19b608b9.js');
5
6
  const mapControls_interfaces = require('./map-controls.interfaces-5ceec716.js');
6
7
 
7
8
  class DsoModalRef {
@@ -70,5 +71,6 @@ class DsoModalController {
70
71
  }
71
72
  }
72
73
 
74
+ exports.isExpandable = expandable_interfaces.isExpandable;
73
75
  exports.transitionDuration = mapControls_interfaces.transitionDuration;
74
76
  exports.DsoModalController = DsoModalController;
@@ -1,17 +1,66 @@
1
1
  'use strict';
2
2
 
3
3
  /*!
4
- * tabbable 6.0.1
4
+ * tabbable 6.1.2
5
5
  * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
6
6
  */
7
- var candidateSelectors = ['input', 'select', 'textarea', 'a[href]', 'button', '[tabindex]:not(slot)', 'audio[controls]', 'video[controls]', '[contenteditable]:not([contenteditable="false"])', 'details>summary:first-of-type', 'details'];
7
+ // NOTE: separate `:not()` selectors has broader browser support than the newer
8
+ // `:not([inert], [inert] *)` (Feb 2023)
9
+ // CAREFUL: JSDom does not support `:not([inert] *)` as a selector; using it causes
10
+ // the entire query to fail, resulting in no nodes found, which will break a lot
11
+ // of things... so we have to rely on JS to identify nodes inside an inert container
12
+ var candidateSelectors = ['input:not([inert])', 'select:not([inert])', 'textarea:not([inert])', 'a[href]:not([inert])', 'button:not([inert])', '[tabindex]:not(slot):not([inert])', 'audio[controls]:not([inert])', 'video[controls]:not([inert])', '[contenteditable]:not([contenteditable="false"]):not([inert])', 'details>summary:first-of-type:not([inert])', 'details:not([inert])'];
8
13
  var candidateSelector = /* #__PURE__ */candidateSelectors.join(',');
9
14
  var NoElement = typeof Element === 'undefined';
10
15
  var matches = NoElement ? function () {} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
11
16
  var getRootNode = !NoElement && Element.prototype.getRootNode ? function (element) {
12
- return element.getRootNode();
17
+ var _element$getRootNode;
18
+ return element === null || element === void 0 ? void 0 : (_element$getRootNode = element.getRootNode) === null || _element$getRootNode === void 0 ? void 0 : _element$getRootNode.call(element);
13
19
  } : function (element) {
14
- return element.ownerDocument;
20
+ return element === null || element === void 0 ? void 0 : element.ownerDocument;
21
+ };
22
+
23
+ /**
24
+ * Determines if a node is inert or in an inert ancestor.
25
+ * @param {Element} [node]
26
+ * @param {boolean} [lookUp] If true and `node` is not inert, looks up at ancestors to
27
+ * see if any of them are inert. If false, only `node` itself is considered.
28
+ * @returns {boolean} True if inert itself or by way of being in an inert ancestor.
29
+ * False if `node` is falsy.
30
+ */
31
+ var isInert = function isInert(node, lookUp) {
32
+ var _node$getAttribute;
33
+ if (lookUp === void 0) {
34
+ lookUp = true;
35
+ }
36
+ // CAREFUL: JSDom does not support inert at all, so we can't use the `HTMLElement.inert`
37
+ // JS API property; we have to check the attribute, which can either be empty or 'true';
38
+ // if it's `null` (not specified) or 'false', it's an active element
39
+ var inertAtt = node === null || node === void 0 ? void 0 : (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.call(node, 'inert');
40
+ var inert = inertAtt === '' || inertAtt === 'true';
41
+
42
+ // NOTE: this could also be handled with `node.matches('[inert], :is([inert] *)')`
43
+ // if it weren't for `matches()` not being a function on shadow roots; the following
44
+ // code works for any kind of node
45
+ // CAREFUL: JSDom does not appear to support certain selectors like `:not([inert] *)`
46
+ // so it likely would not support `:is([inert] *)` either...
47
+ var result = inert || lookUp && node && isInert(node.parentNode); // recursive
48
+
49
+ return result;
50
+ };
51
+
52
+ /**
53
+ * Determines if a node's content is editable.
54
+ * @param {Element} [node]
55
+ * @returns True if it's content-editable; false if it's not or `node` is falsy.
56
+ */
57
+ var isContentEditable = function isContentEditable(node) {
58
+ var _node$getAttribute2;
59
+ // CAREFUL: JSDom does not support the `HTMLElement.isContentEditable` API so we have
60
+ // to use the attribute directly to check for this, which can either be empty or 'true';
61
+ // if it's `null` (not specified) or 'false', it's a non-editable element
62
+ var attValue = node === null || node === void 0 ? void 0 : (_node$getAttribute2 = node.getAttribute) === null || _node$getAttribute2 === void 0 ? void 0 : _node$getAttribute2.call(node, 'contenteditable');
63
+ return attValue === '' || attValue === 'true';
15
64
  };
16
65
 
17
66
  /**
@@ -21,6 +70,11 @@ var getRootNode = !NoElement && Element.prototype.getRootNode ? function (elemen
21
70
  * @returns {Element[]}
22
71
  */
23
72
  var getCandidates = function getCandidates(el, includeContainer, filter) {
73
+ // even if `includeContainer=false`, we still have to check it for inertness because
74
+ // if it's inert, all its children are inert
75
+ if (isInert(el)) {
76
+ return [];
77
+ }
24
78
  var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector));
25
79
  if (includeContainer && matches.call(el, candidateSelector)) {
26
80
  candidates.unshift(el);
@@ -68,6 +122,11 @@ var getCandidatesIteratively = function getCandidatesIteratively(elements, inclu
68
122
  var elementsToCheck = Array.from(elements);
69
123
  while (elementsToCheck.length) {
70
124
  var element = elementsToCheck.shift();
125
+ if (isInert(element, false)) {
126
+ // no need to look up since we're drilling down
127
+ // anything inside this container will also be inert
128
+ continue;
129
+ }
71
130
  if (element.tagName === 'SLOT') {
72
131
  // add shadow dom slot scope (slot itself cannot be focusable)
73
132
  var assigned = element.assignedElements();
@@ -92,7 +151,11 @@ var getCandidatesIteratively = function getCandidatesIteratively(elements, inclu
92
151
  var shadowRoot = element.shadowRoot ||
93
152
  // check for an undisclosed shadow
94
153
  typeof options.getShadowRoot === 'function' && options.getShadowRoot(element);
95
- var validShadowRoot = !options.shadowRootFilter || options.shadowRootFilter(element);
154
+
155
+ // no inert look up because we're already drilling down and checking for inertness
156
+ // on the way down, so all containers to this root node should have already been
157
+ // vetted as non-inert
158
+ var validShadowRoot = !isInert(shadowRoot, false) && (!options.shadowRootFilter || options.shadowRootFilter(element));
96
159
  if (shadowRoot && validShadowRoot) {
97
160
  // add shadow dom scope IIF a shadow root node was given; otherwise, an undisclosed
98
161
  // shadow exists, so look at light dom children as fallback BUT create a scope for any
@@ -131,7 +194,7 @@ var getTabindex = function getTabindex(node, isScope) {
131
194
  // isScope is positive for custom element with shadow root or slot that by default
132
195
  // have tabIndex -1, but need to be sorted by document order in order for their
133
196
  // content to be inserted in the correct position
134
- if ((isScope || /^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || node.isContentEditable) && isNaN(parseInt(node.getAttribute('tabindex'), 10))) {
197
+ if ((isScope || /^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && isNaN(parseInt(node.getAttribute('tabindex'), 10))) {
135
198
  return 0;
136
199
  }
137
200
  }
@@ -191,7 +254,7 @@ var isNonTabbableRadio = function isNonTabbableRadio(node) {
191
254
 
192
255
  // determines if a node is ultimately attached to the window's document
193
256
  var isNodeAttached = function isNodeAttached(node) {
194
- var _nodeRootHost;
257
+ var _nodeRoot;
195
258
  // The root node is the shadow root if the node is in a shadow DOM; some document otherwise
196
259
  // (but NOT _the_ document; see second 'If' comment below for more).
197
260
  // If rootNode is shadow root, it'll have a host, which is the element to which the shadow
@@ -211,15 +274,28 @@ var isNodeAttached = function isNodeAttached(node) {
211
274
  // to ignore the rootNode at this point, and use `node.ownerDocument`. Otherwise,
212
275
  // using `rootNode.contains(node)` will _always_ be true we'll get false-positives when
213
276
  // node is actually detached.
214
- var nodeRootHost = getRootNode(node).host;
215
- var attached = !!((_nodeRootHost = nodeRootHost) !== null && _nodeRootHost !== void 0 && _nodeRootHost.ownerDocument.contains(nodeRootHost) || node.ownerDocument.contains(node));
216
- while (!attached && nodeRootHost) {
217
- var _nodeRootHost2;
218
- // since it's not attached and we have a root host, the node MUST be in a nested shadow DOM,
219
- // which means we need to get the host's host and check if that parent host is contained
220
- // in (i.e. attached to) the document
221
- nodeRootHost = getRootNode(nodeRootHost).host;
222
- attached = !!((_nodeRootHost2 = nodeRootHost) !== null && _nodeRootHost2 !== void 0 && _nodeRootHost2.ownerDocument.contains(nodeRootHost));
277
+ // NOTE: If `nodeRootHost` or `node` happens to be the `document` itself (which is possible
278
+ // if a tabbable/focusable node was quickly added to the DOM, focused, and then removed
279
+ // from the DOM as in https://github.com/focus-trap/focus-trap-react/issues/905), then
280
+ // `ownerDocument` will be `null`, hence the optional chaining on it.
281
+ var nodeRoot = node && getRootNode(node);
282
+ var nodeRootHost = (_nodeRoot = nodeRoot) === null || _nodeRoot === void 0 ? void 0 : _nodeRoot.host;
283
+
284
+ // in some cases, a detached node will return itself as the root instead of a document or
285
+ // shadow root object, in which case, we shouldn't try to look further up the host chain
286
+ var attached = false;
287
+ if (nodeRoot && nodeRoot !== node) {
288
+ var _nodeRootHost, _nodeRootHost$ownerDo, _node$ownerDocument;
289
+ attached = !!((_nodeRootHost = nodeRootHost) !== null && _nodeRootHost !== void 0 && (_nodeRootHost$ownerDo = _nodeRootHost.ownerDocument) !== null && _nodeRootHost$ownerDo !== void 0 && _nodeRootHost$ownerDo.contains(nodeRootHost) || node !== null && node !== void 0 && (_node$ownerDocument = node.ownerDocument) !== null && _node$ownerDocument !== void 0 && _node$ownerDocument.contains(node));
290
+ while (!attached && nodeRootHost) {
291
+ var _nodeRoot2, _nodeRootHost2, _nodeRootHost2$ownerD;
292
+ // since it's not attached and we have a root host, the node MUST be in a nested shadow DOM,
293
+ // which means we need to get the host's host and check if that parent host is contained
294
+ // in (i.e. attached to) the document
295
+ nodeRoot = getRootNode(nodeRootHost);
296
+ nodeRootHost = (_nodeRoot2 = nodeRoot) === null || _nodeRoot2 === void 0 ? void 0 : _nodeRoot2.host;
297
+ attached = !!((_nodeRootHost2 = nodeRootHost) !== null && _nodeRootHost2 !== void 0 && (_nodeRootHost2$ownerD = _nodeRootHost2.ownerDocument) !== null && _nodeRootHost2$ownerD !== void 0 && _nodeRootHost2$ownerD.contains(nodeRootHost));
298
+ }
223
299
  }
224
300
  return attached;
225
301
  };
@@ -354,7 +430,11 @@ var isDisabledFromFieldset = function isDisabledFromFieldset(node) {
354
430
  return false;
355
431
  };
356
432
  var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable(options, node) {
357
- if (node.disabled || isHiddenInput(node) || isHidden(node, options) ||
433
+ if (node.disabled ||
434
+ // we must do an inert look up to filter out any elements inside an inert ancestor
435
+ // because we're limited in the type of selectors we can use in JSDom (see related
436
+ // note related to `candidateSelectors`)
437
+ isInert(node) || isHiddenInput(node) || isHidden(node, options) ||
358
438
  // For a details element with a summary, the summary element gets the focus
359
439
  isDetailsWithSummary(node) || isDisabledFromFieldset(node)) {
360
440
  return false;