@haiilo/catalyst 5.2.3 → 5.4.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 (189) hide show
  1. package/dist/catalyst/catalyst.css +56 -39
  2. package/dist/catalyst/catalyst.esm.js +1 -1
  3. package/dist/catalyst/catalyst.esm.js.map +1 -1
  4. package/dist/catalyst/index.cdn.js +1 -0
  5. package/dist/catalyst/index.esm.js +2 -2
  6. package/dist/catalyst/index.esm.js.map +1 -1
  7. package/dist/catalyst/p-34e0cbba.entry.js +10 -0
  8. package/dist/catalyst/p-34e0cbba.entry.js.map +1 -0
  9. package/dist/catalyst/{p-d1fb9d96.js → p-ce6a1db2.js} +1 -1
  10. package/dist/catalyst/p-ce6a1db2.js.map +1 -0
  11. package/dist/catalyst/p-cf32399c.js +2 -0
  12. package/dist/catalyst/p-cf32399c.js.map +1 -0
  13. package/dist/catalyst/scss/_snippets/_checkbox-hint.scss +20 -0
  14. package/dist/catalyst/scss/_snippets/_form-label.scss +2 -1
  15. package/dist/catalyst/scss/utils/_border.scss +14 -0
  16. package/dist/catalyst/scss/utils/_media.mixins.scss +0 -1
  17. package/dist/catalyst/scss/utils/_typography.mixins.scss +1 -0
  18. package/dist/cjs/{cat-alert_24.cjs.entry.js → cat-alert_27.cjs.entry.js} +3777 -192
  19. package/dist/cjs/cat-alert_27.cjs.entry.js.map +1 -0
  20. package/dist/cjs/{cat-icon-registry-671af264.js → cat-icon-registry-228164a1.js} +43 -2
  21. package/dist/cjs/cat-icon-registry-228164a1.js.map +1 -0
  22. package/dist/cjs/catalyst.cjs.js +3 -3
  23. package/dist/cjs/catalyst.cjs.js.map +1 -1
  24. package/dist/cjs/{index-01312a2e.js → index-4258b31e.js} +8 -1
  25. package/dist/{catalyst/p-d1fb9d96.js.map → cjs/index-4258b31e.js.map} +1 -1
  26. package/dist/cjs/index.cjs.js +2 -2
  27. package/dist/cjs/index.cjs.js.map +1 -1
  28. package/dist/cjs/loader.cjs.js +3 -3
  29. package/dist/cjs/loader.cjs.js.map +1 -1
  30. package/dist/collection/collection-manifest.json +5 -2
  31. package/dist/collection/components/cat-alert/cat-alert.js +5 -5
  32. package/dist/collection/components/cat-alert/cat-alert.js.map +1 -1
  33. package/dist/collection/components/cat-button/cat-button.css +27 -9
  34. package/dist/collection/components/cat-button/cat-button.js +27 -25
  35. package/dist/collection/components/cat-button/cat-button.js.map +1 -1
  36. package/dist/collection/components/cat-button-group/cat-button-group.css +15 -0
  37. package/dist/collection/components/cat-button-group/cat-button-group.js +51 -0
  38. package/dist/collection/components/cat-button-group/cat-button-group.js.map +1 -0
  39. package/dist/collection/components/cat-checkbox/cat-checkbox.css +24 -1
  40. package/dist/collection/components/cat-checkbox/cat-checkbox.js +8 -4
  41. package/dist/collection/components/cat-checkbox/cat-checkbox.js.map +1 -1
  42. package/dist/collection/components/cat-datepicker/cat-datepicker.css +381 -0
  43. package/dist/collection/components/cat-datepicker/cat-datepicker.js +873 -0
  44. package/dist/collection/components/cat-datepicker/cat-datepicker.js.map +1 -0
  45. package/dist/collection/components/cat-datepicker/datepicker-type.js +8 -0
  46. package/dist/collection/components/cat-datepicker/datepicker-type.js.map +1 -0
  47. package/dist/collection/components/cat-datepicker/dayjs.config.js +8 -0
  48. package/dist/collection/components/cat-datepicker/dayjs.config.js.map +1 -0
  49. package/dist/collection/components/cat-datepicker/vanillajs-datepicker.config.js +46 -0
  50. package/dist/collection/components/cat-datepicker/vanillajs-datepicker.config.js.map +1 -0
  51. package/dist/collection/components/cat-dropdown/cat-dropdown.css +1 -0
  52. package/dist/collection/components/cat-dropdown/cat-dropdown.js +26 -7
  53. package/dist/collection/components/cat-dropdown/cat-dropdown.js.map +1 -1
  54. package/dist/collection/components/cat-form-group/cat-form-group.js +29 -1
  55. package/dist/collection/components/cat-form-group/cat-form-group.js.map +1 -1
  56. package/dist/collection/components/cat-icon/cat-icon-registry.js +29 -1
  57. package/dist/collection/components/cat-icon/cat-icon-registry.js.map +1 -1
  58. package/dist/collection/components/cat-input/cat-input.css +392 -15
  59. package/dist/collection/components/cat-input/cat-input.js +8 -4
  60. package/dist/collection/components/cat-input/cat-input.js.map +1 -1
  61. package/dist/collection/components/cat-label/cat-label.js +19 -0
  62. package/dist/collection/components/cat-label/cat-label.js.map +1 -1
  63. package/dist/collection/components/cat-notification/cat-notification.js +1 -1
  64. package/dist/collection/components/cat-notification/cat-notification.js.map +1 -1
  65. package/dist/collection/components/cat-pagination/cat-pagination.js +28 -6
  66. package/dist/collection/components/cat-pagination/cat-pagination.js.map +1 -1
  67. package/dist/collection/components/cat-radio/cat-radio.css +24 -1
  68. package/dist/collection/components/cat-radio/cat-radio.js +8 -4
  69. package/dist/collection/components/cat-radio/cat-radio.js.map +1 -1
  70. package/dist/collection/components/cat-radio-group/cat-radio-group.js +7 -3
  71. package/dist/collection/components/cat-radio-group/cat-radio-group.js.map +1 -1
  72. package/dist/collection/components/cat-scrollable/cat-scrollable.css +1 -4
  73. package/dist/collection/components/cat-select/cat-select.css +98 -11
  74. package/dist/collection/components/cat-select/cat-select.js +73 -23
  75. package/dist/collection/components/cat-select/cat-select.js.map +1 -1
  76. package/dist/collection/components/cat-skeleton/cat-skeleton.css +1 -1
  77. package/dist/collection/components/cat-textarea/cat-textarea.css +17 -16
  78. package/dist/collection/components/cat-textarea/cat-textarea.js +8 -4
  79. package/dist/collection/components/cat-textarea/cat-textarea.js.map +1 -1
  80. package/dist/collection/components/cat-timepicker/cat-timepicker.css +5 -0
  81. package/dist/collection/components/cat-timepicker/cat-timepicker.js +668 -0
  82. package/dist/collection/components/cat-timepicker/cat-timepicker.js.map +1 -0
  83. package/dist/collection/components/cat-toggle/cat-toggle.css +24 -1
  84. package/dist/collection/components/cat-toggle/cat-toggle.js +8 -4
  85. package/dist/collection/components/cat-toggle/cat-toggle.js.map +1 -1
  86. package/dist/collection/components/cat-tooltip/cat-tooltip.css +1 -8
  87. package/dist/collection/components/cat-tooltip/cat-tooltip.js +22 -18
  88. package/dist/collection/components/cat-tooltip/cat-tooltip.js.map +1 -1
  89. package/dist/collection/index.cdn.js +1 -0
  90. package/dist/collection/scss/_snippets/_checkbox-hint.scss +20 -0
  91. package/dist/collection/scss/_snippets/_form-label.scss +2 -1
  92. package/dist/collection/scss/utils/_border.scss +14 -0
  93. package/dist/collection/scss/utils/_media.mixins.scss +0 -1
  94. package/dist/collection/scss/utils/_typography.mixins.scss +1 -0
  95. package/dist/components/cat-alert.js +5 -5
  96. package/dist/components/cat-alert.js.map +1 -1
  97. package/dist/components/cat-button-group.d.ts +11 -0
  98. package/dist/components/cat-button-group.js +46 -0
  99. package/dist/components/cat-button-group.js.map +1 -0
  100. package/dist/components/cat-button2.js +12 -10
  101. package/dist/components/cat-button2.js.map +1 -1
  102. package/dist/components/cat-checkbox2.js +2 -2
  103. package/dist/components/cat-checkbox2.js.map +1 -1
  104. package/dist/components/cat-datepicker.d.ts +11 -0
  105. package/dist/components/cat-datepicker.js +3210 -0
  106. package/dist/components/cat-datepicker.js.map +1 -0
  107. package/dist/components/cat-dropdown2.js +640 -43
  108. package/dist/components/cat-dropdown2.js.map +1 -1
  109. package/dist/components/cat-form-group.js +11 -2
  110. package/dist/components/cat-form-group.js.map +1 -1
  111. package/dist/components/cat-icon-registry.js +42 -1
  112. package/dist/components/cat-icon-registry.js.map +1 -1
  113. package/dist/components/cat-input.js +1 -226
  114. package/dist/components/cat-input.js.map +1 -1
  115. package/dist/components/cat-input2.js +230 -0
  116. package/dist/components/cat-input2.js.map +1 -0
  117. package/dist/components/cat-label.js +2 -0
  118. package/dist/components/cat-label.js.map +1 -1
  119. package/dist/components/cat-pagination.js +10 -5
  120. package/dist/components/cat-pagination.js.map +1 -1
  121. package/dist/components/cat-radio-group.js.map +1 -1
  122. package/dist/components/cat-radio.js +2 -2
  123. package/dist/components/cat-radio.js.map +1 -1
  124. package/dist/components/cat-scrollable2.js +7 -5
  125. package/dist/components/cat-scrollable2.js.map +1 -1
  126. package/dist/components/cat-select-demo.js +2 -2
  127. package/dist/components/cat-select-demo.js.map +1 -1
  128. package/dist/components/cat-select2.js +46 -17
  129. package/dist/components/cat-select2.js.map +1 -1
  130. package/dist/components/cat-skeleton2.js +1 -1
  131. package/dist/components/cat-skeleton2.js.map +1 -1
  132. package/dist/components/cat-textarea.js +3 -3
  133. package/dist/components/cat-textarea.js.map +1 -1
  134. package/dist/components/cat-timepicker.d.ts +11 -0
  135. package/dist/components/cat-timepicker.js +258 -0
  136. package/dist/components/cat-timepicker.js.map +1 -0
  137. package/dist/components/cat-toggle.js +2 -2
  138. package/dist/components/cat-toggle.js.map +1 -1
  139. package/dist/components/cat-tooltip.js +24 -20
  140. package/dist/components/cat-tooltip.js.map +1 -1
  141. package/dist/components/floating-ui.dom.esm.js +142 -56
  142. package/dist/components/floating-ui.dom.esm.js.map +1 -1
  143. package/dist/components/index.js +1 -1
  144. package/dist/components/index.js.map +1 -1
  145. package/dist/esm/{cat-alert_24.entry.js → cat-alert_27.entry.js} +3775 -193
  146. package/dist/esm/cat-alert_27.entry.js.map +1 -0
  147. package/dist/esm/{cat-icon-registry-d6b80490.js → cat-icon-registry-4bd597f4.js} +43 -2
  148. package/dist/esm/cat-icon-registry-4bd597f4.js.map +1 -0
  149. package/dist/esm/catalyst.js +4 -4
  150. package/dist/esm/catalyst.js.map +1 -1
  151. package/dist/esm/{index-fc2f91a4.js → index-636ce8d6.js} +8 -1
  152. package/dist/esm/index-636ce8d6.js.map +1 -0
  153. package/dist/esm/index.js +3 -3
  154. package/dist/esm/index.js.map +1 -1
  155. package/dist/esm/loader.js +4 -4
  156. package/dist/esm/loader.js.map +1 -1
  157. package/dist/types/components/cat-button/cat-button.d.ts +4 -5
  158. package/dist/types/components/cat-button-group/cat-button-group.d.ts +11 -0
  159. package/dist/types/components/cat-checkbox/cat-checkbox.d.ts +1 -1
  160. package/dist/types/components/cat-datepicker/cat-datepicker.d.ts +187 -0
  161. package/dist/types/components/cat-datepicker/datepicker-type.d.ts +7 -0
  162. package/dist/types/components/cat-datepicker/datepicker.d.ts +1 -0
  163. package/dist/types/components/cat-datepicker/dayjs.config.d.ts +3 -0
  164. package/dist/types/components/cat-datepicker/vanillajs-datepicker.config.d.ts +4 -0
  165. package/dist/types/components/cat-form-group/cat-form-group.d.ts +5 -0
  166. package/dist/types/components/cat-input/cat-input.d.ts +1 -1
  167. package/dist/types/components/cat-label/cat-label.d.ts +4 -0
  168. package/dist/types/components/cat-pagination/cat-pagination.d.ts +6 -0
  169. package/dist/types/components/cat-radio/cat-radio.d.ts +1 -1
  170. package/dist/types/components/cat-radio-group/cat-radio-group.d.ts +1 -1
  171. package/dist/types/components/cat-select/cat-select.d.ts +10 -1
  172. package/dist/types/components/cat-textarea/cat-textarea.d.ts +1 -1
  173. package/dist/types/components/cat-timepicker/cat-timepicker.d.ts +158 -0
  174. package/dist/types/components/cat-toggle/cat-toggle.d.ts +1 -1
  175. package/dist/types/components/cat-tooltip/cat-tooltip.d.ts +2 -2
  176. package/dist/types/components.d.ts +585 -17
  177. package/package.json +22 -18
  178. package/dist/catalyst/p-ccfebe33.js +0 -2
  179. package/dist/catalyst/p-ccfebe33.js.map +0 -1
  180. package/dist/catalyst/p-d135d677.entry.js +0 -10
  181. package/dist/catalyst/p-d135d677.entry.js.map +0 -1
  182. package/dist/cjs/cat-alert_24.cjs.entry.js.map +0 -1
  183. package/dist/cjs/cat-icon-registry-671af264.js.map +0 -1
  184. package/dist/cjs/index-01312a2e.js.map +0 -1
  185. package/dist/components/first-tabbable.js +0 -464
  186. package/dist/components/first-tabbable.js.map +0 -1
  187. package/dist/esm/cat-alert_24.entry.js.map +0 -1
  188. package/dist/esm/cat-icon-registry-d6b80490.js.map +0 -1
  189. package/dist/esm/index-fc2f91a4.js.map +0 -1
@@ -1,6 +1,5 @@
1
1
  import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
2
- import { a as autoUpdate, c as computePosition, o as offset, f as flip } from './floating-ui.dom.esm.js';
3
- import { t as tabbable, f as focusable, i as isTabbable, a as isFocusable, b as firstTabbable } from './first-tabbable.js';
2
+ import { a as autoUpdate, c as computePosition, o as offset, f as flip, s as size } from './floating-ui.dom.esm.js';
4
3
 
5
4
  /**
6
5
  * Auto-generated file. Do not edit directly.
@@ -8,7 +7,544 @@ import { t as tabbable, f as focusable, i as isTabbable, a as isFocusable, b as
8
7
  const timeTransitionS = 125;
9
8
 
10
9
  /*!
11
- * focus-trap 7.2.0
10
+ * tabbable 6.1.2
11
+ * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
12
+ */
13
+ // NOTE: separate `:not()` selectors has broader browser support than the newer
14
+ // `:not([inert], [inert] *)` (Feb 2023)
15
+ // CAREFUL: JSDom does not support `:not([inert] *)` as a selector; using it causes
16
+ // the entire query to fail, resulting in no nodes found, which will break a lot
17
+ // of things... so we have to rely on JS to identify nodes inside an inert container
18
+ 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])'];
19
+ var candidateSelector = /* #__PURE__ */candidateSelectors.join(',');
20
+ var NoElement = typeof Element === 'undefined';
21
+ var matches = NoElement ? function () {} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
22
+ var getRootNode = !NoElement && Element.prototype.getRootNode ? function (element) {
23
+ var _element$getRootNode;
24
+ return element === null || element === void 0 ? void 0 : (_element$getRootNode = element.getRootNode) === null || _element$getRootNode === void 0 ? void 0 : _element$getRootNode.call(element);
25
+ } : function (element) {
26
+ return element === null || element === void 0 ? void 0 : element.ownerDocument;
27
+ };
28
+
29
+ /**
30
+ * Determines if a node is inert or in an inert ancestor.
31
+ * @param {Element} [node]
32
+ * @param {boolean} [lookUp] If true and `node` is not inert, looks up at ancestors to
33
+ * see if any of them are inert. If false, only `node` itself is considered.
34
+ * @returns {boolean} True if inert itself or by way of being in an inert ancestor.
35
+ * False if `node` is falsy.
36
+ */
37
+ var isInert = function isInert(node, lookUp) {
38
+ var _node$getAttribute;
39
+ if (lookUp === void 0) {
40
+ lookUp = true;
41
+ }
42
+ // CAREFUL: JSDom does not support inert at all, so we can't use the `HTMLElement.inert`
43
+ // JS API property; we have to check the attribute, which can either be empty or 'true';
44
+ // if it's `null` (not specified) or 'false', it's an active element
45
+ 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');
46
+ var inert = inertAtt === '' || inertAtt === 'true';
47
+
48
+ // NOTE: this could also be handled with `node.matches('[inert], :is([inert] *)')`
49
+ // if it weren't for `matches()` not being a function on shadow roots; the following
50
+ // code works for any kind of node
51
+ // CAREFUL: JSDom does not appear to support certain selectors like `:not([inert] *)`
52
+ // so it likely would not support `:is([inert] *)` either...
53
+ var result = inert || lookUp && node && isInert(node.parentNode); // recursive
54
+
55
+ return result;
56
+ };
57
+
58
+ /**
59
+ * Determines if a node's content is editable.
60
+ * @param {Element} [node]
61
+ * @returns True if it's content-editable; false if it's not or `node` is falsy.
62
+ */
63
+ var isContentEditable = function isContentEditable(node) {
64
+ var _node$getAttribute2;
65
+ // CAREFUL: JSDom does not support the `HTMLElement.isContentEditable` API so we have
66
+ // to use the attribute directly to check for this, which can either be empty or 'true';
67
+ // if it's `null` (not specified) or 'false', it's a non-editable element
68
+ 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');
69
+ return attValue === '' || attValue === 'true';
70
+ };
71
+
72
+ /**
73
+ * @param {Element} el container to check in
74
+ * @param {boolean} includeContainer add container to check
75
+ * @param {(node: Element) => boolean} filter filter candidates
76
+ * @returns {Element[]}
77
+ */
78
+ var getCandidates = function getCandidates(el, includeContainer, filter) {
79
+ // even if `includeContainer=false`, we still have to check it for inertness because
80
+ // if it's inert, all its children are inert
81
+ if (isInert(el)) {
82
+ return [];
83
+ }
84
+ var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector));
85
+ if (includeContainer && matches.call(el, candidateSelector)) {
86
+ candidates.unshift(el);
87
+ }
88
+ candidates = candidates.filter(filter);
89
+ return candidates;
90
+ };
91
+
92
+ /**
93
+ * @callback GetShadowRoot
94
+ * @param {Element} element to check for shadow root
95
+ * @returns {ShadowRoot|boolean} ShadowRoot if available or boolean indicating if a shadowRoot is attached but not available.
96
+ */
97
+
98
+ /**
99
+ * @callback ShadowRootFilter
100
+ * @param {Element} shadowHostNode the element which contains shadow content
101
+ * @returns {boolean} true if a shadow root could potentially contain valid candidates.
102
+ */
103
+
104
+ /**
105
+ * @typedef {Object} CandidateScope
106
+ * @property {Element} scopeParent contains inner candidates
107
+ * @property {Element[]} candidates list of candidates found in the scope parent
108
+ */
109
+
110
+ /**
111
+ * @typedef {Object} IterativeOptions
112
+ * @property {GetShadowRoot|boolean} getShadowRoot true if shadow support is enabled; falsy if not;
113
+ * if a function, implies shadow support is enabled and either returns the shadow root of an element
114
+ * or a boolean stating if it has an undisclosed shadow root
115
+ * @property {(node: Element) => boolean} filter filter candidates
116
+ * @property {boolean} flatten if true then result will flatten any CandidateScope into the returned list
117
+ * @property {ShadowRootFilter} shadowRootFilter filter shadow roots;
118
+ */
119
+
120
+ /**
121
+ * @param {Element[]} elements list of element containers to match candidates from
122
+ * @param {boolean} includeContainer add container list to check
123
+ * @param {IterativeOptions} options
124
+ * @returns {Array.<Element|CandidateScope>}
125
+ */
126
+ var getCandidatesIteratively = function getCandidatesIteratively(elements, includeContainer, options) {
127
+ var candidates = [];
128
+ var elementsToCheck = Array.from(elements);
129
+ while (elementsToCheck.length) {
130
+ var element = elementsToCheck.shift();
131
+ if (isInert(element, false)) {
132
+ // no need to look up since we're drilling down
133
+ // anything inside this container will also be inert
134
+ continue;
135
+ }
136
+ if (element.tagName === 'SLOT') {
137
+ // add shadow dom slot scope (slot itself cannot be focusable)
138
+ var assigned = element.assignedElements();
139
+ var content = assigned.length ? assigned : element.children;
140
+ var nestedCandidates = getCandidatesIteratively(content, true, options);
141
+ if (options.flatten) {
142
+ candidates.push.apply(candidates, nestedCandidates);
143
+ } else {
144
+ candidates.push({
145
+ scopeParent: element,
146
+ candidates: nestedCandidates
147
+ });
148
+ }
149
+ } else {
150
+ // check candidate element
151
+ var validCandidate = matches.call(element, candidateSelector);
152
+ if (validCandidate && options.filter(element) && (includeContainer || !elements.includes(element))) {
153
+ candidates.push(element);
154
+ }
155
+
156
+ // iterate over shadow content if possible
157
+ var shadowRoot = element.shadowRoot ||
158
+ // check for an undisclosed shadow
159
+ typeof options.getShadowRoot === 'function' && options.getShadowRoot(element);
160
+
161
+ // no inert look up because we're already drilling down and checking for inertness
162
+ // on the way down, so all containers to this root node should have already been
163
+ // vetted as non-inert
164
+ var validShadowRoot = !isInert(shadowRoot, false) && (!options.shadowRootFilter || options.shadowRootFilter(element));
165
+ if (shadowRoot && validShadowRoot) {
166
+ // add shadow dom scope IIF a shadow root node was given; otherwise, an undisclosed
167
+ // shadow exists, so look at light dom children as fallback BUT create a scope for any
168
+ // child candidates found because they're likely slotted elements (elements that are
169
+ // children of the web component element (which has the shadow), in the light dom, but
170
+ // slotted somewhere _inside_ the undisclosed shadow) -- the scope is created below,
171
+ // _after_ we return from this recursive call
172
+ var _nestedCandidates = getCandidatesIteratively(shadowRoot === true ? element.children : shadowRoot.children, true, options);
173
+ if (options.flatten) {
174
+ candidates.push.apply(candidates, _nestedCandidates);
175
+ } else {
176
+ candidates.push({
177
+ scopeParent: element,
178
+ candidates: _nestedCandidates
179
+ });
180
+ }
181
+ } else {
182
+ // there's not shadow so just dig into the element's (light dom) children
183
+ // __without__ giving the element special scope treatment
184
+ elementsToCheck.unshift.apply(elementsToCheck, element.children);
185
+ }
186
+ }
187
+ }
188
+ return candidates;
189
+ };
190
+ var getTabindex = function getTabindex(node, isScope) {
191
+ if (node.tabIndex < 0) {
192
+ // in Chrome, <details/>, <audio controls/> and <video controls/> elements get a default
193
+ // `tabIndex` of -1 when the 'tabindex' attribute isn't specified in the DOM,
194
+ // yet they are still part of the regular tab order; in FF, they get a default
195
+ // `tabIndex` of 0; since Chrome still puts those elements in the regular tab
196
+ // order, consider their tab index to be 0.
197
+ // Also browsers do not return `tabIndex` correctly for contentEditable nodes;
198
+ // so if they don't have a tabindex attribute specifically set, assume it's 0.
199
+ //
200
+ // isScope is positive for custom element with shadow root or slot that by default
201
+ // have tabIndex -1, but need to be sorted by document order in order for their
202
+ // content to be inserted in the correct position
203
+ if ((isScope || /^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && isNaN(parseInt(node.getAttribute('tabindex'), 10))) {
204
+ return 0;
205
+ }
206
+ }
207
+ return node.tabIndex;
208
+ };
209
+ var sortOrderedTabbables = function sortOrderedTabbables(a, b) {
210
+ return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex;
211
+ };
212
+ var isInput = function isInput(node) {
213
+ return node.tagName === 'INPUT';
214
+ };
215
+ var isHiddenInput = function isHiddenInput(node) {
216
+ return isInput(node) && node.type === 'hidden';
217
+ };
218
+ var isDetailsWithSummary = function isDetailsWithSummary(node) {
219
+ var r = node.tagName === 'DETAILS' && Array.prototype.slice.apply(node.children).some(function (child) {
220
+ return child.tagName === 'SUMMARY';
221
+ });
222
+ return r;
223
+ };
224
+ var getCheckedRadio = function getCheckedRadio(nodes, form) {
225
+ for (var i = 0; i < nodes.length; i++) {
226
+ if (nodes[i].checked && nodes[i].form === form) {
227
+ return nodes[i];
228
+ }
229
+ }
230
+ };
231
+ var isTabbableRadio = function isTabbableRadio(node) {
232
+ if (!node.name) {
233
+ return true;
234
+ }
235
+ var radioScope = node.form || getRootNode(node);
236
+ var queryRadios = function queryRadios(name) {
237
+ return radioScope.querySelectorAll('input[type="radio"][name="' + name + '"]');
238
+ };
239
+ var radioSet;
240
+ if (typeof window !== 'undefined' && typeof window.CSS !== 'undefined' && typeof window.CSS.escape === 'function') {
241
+ radioSet = queryRadios(window.CSS.escape(node.name));
242
+ } else {
243
+ try {
244
+ radioSet = queryRadios(node.name);
245
+ } catch (err) {
246
+ // eslint-disable-next-line no-console
247
+ console.error('Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s', err.message);
248
+ return false;
249
+ }
250
+ }
251
+ var checked = getCheckedRadio(radioSet, node.form);
252
+ return !checked || checked === node;
253
+ };
254
+ var isRadio = function isRadio(node) {
255
+ return isInput(node) && node.type === 'radio';
256
+ };
257
+ var isNonTabbableRadio = function isNonTabbableRadio(node) {
258
+ return isRadio(node) && !isTabbableRadio(node);
259
+ };
260
+
261
+ // determines if a node is ultimately attached to the window's document
262
+ var isNodeAttached = function isNodeAttached(node) {
263
+ var _nodeRoot;
264
+ // The root node is the shadow root if the node is in a shadow DOM; some document otherwise
265
+ // (but NOT _the_ document; see second 'If' comment below for more).
266
+ // If rootNode is shadow root, it'll have a host, which is the element to which the shadow
267
+ // is attached, and the one we need to check if it's in the document or not (because the
268
+ // shadow, and all nodes it contains, is never considered in the document since shadows
269
+ // behave like self-contained DOMs; but if the shadow's HOST, which is part of the document,
270
+ // is hidden, or is not in the document itself but is detached, it will affect the shadow's
271
+ // visibility, including all the nodes it contains). The host could be any normal node,
272
+ // or a custom element (i.e. web component). Either way, that's the one that is considered
273
+ // part of the document, not the shadow root, nor any of its children (i.e. the node being
274
+ // tested).
275
+ // To further complicate things, we have to look all the way up until we find a shadow HOST
276
+ // that is attached (or find none) because the node might be in nested shadows...
277
+ // If rootNode is not a shadow root, it won't have a host, and so rootNode should be the
278
+ // document (per the docs) and while it's a Document-type object, that document does not
279
+ // appear to be the same as the node's `ownerDocument` for some reason, so it's safer
280
+ // to ignore the rootNode at this point, and use `node.ownerDocument`. Otherwise,
281
+ // using `rootNode.contains(node)` will _always_ be true we'll get false-positives when
282
+ // node is actually detached.
283
+ // NOTE: If `nodeRootHost` or `node` happens to be the `document` itself (which is possible
284
+ // if a tabbable/focusable node was quickly added to the DOM, focused, and then removed
285
+ // from the DOM as in https://github.com/focus-trap/focus-trap-react/issues/905), then
286
+ // `ownerDocument` will be `null`, hence the optional chaining on it.
287
+ var nodeRoot = node && getRootNode(node);
288
+ var nodeRootHost = (_nodeRoot = nodeRoot) === null || _nodeRoot === void 0 ? void 0 : _nodeRoot.host;
289
+
290
+ // in some cases, a detached node will return itself as the root instead of a document or
291
+ // shadow root object, in which case, we shouldn't try to look further up the host chain
292
+ var attached = false;
293
+ if (nodeRoot && nodeRoot !== node) {
294
+ var _nodeRootHost, _nodeRootHost$ownerDo, _node$ownerDocument;
295
+ 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));
296
+ while (!attached && nodeRootHost) {
297
+ var _nodeRoot2, _nodeRootHost2, _nodeRootHost2$ownerD;
298
+ // since it's not attached and we have a root host, the node MUST be in a nested shadow DOM,
299
+ // which means we need to get the host's host and check if that parent host is contained
300
+ // in (i.e. attached to) the document
301
+ nodeRoot = getRootNode(nodeRootHost);
302
+ nodeRootHost = (_nodeRoot2 = nodeRoot) === null || _nodeRoot2 === void 0 ? void 0 : _nodeRoot2.host;
303
+ attached = !!((_nodeRootHost2 = nodeRootHost) !== null && _nodeRootHost2 !== void 0 && (_nodeRootHost2$ownerD = _nodeRootHost2.ownerDocument) !== null && _nodeRootHost2$ownerD !== void 0 && _nodeRootHost2$ownerD.contains(nodeRootHost));
304
+ }
305
+ }
306
+ return attached;
307
+ };
308
+ var isZeroArea = function isZeroArea(node) {
309
+ var _node$getBoundingClie = node.getBoundingClientRect(),
310
+ width = _node$getBoundingClie.width,
311
+ height = _node$getBoundingClie.height;
312
+ return width === 0 && height === 0;
313
+ };
314
+ var isHidden = function isHidden(node, _ref) {
315
+ var displayCheck = _ref.displayCheck,
316
+ getShadowRoot = _ref.getShadowRoot;
317
+ // NOTE: visibility will be `undefined` if node is detached from the document
318
+ // (see notes about this further down), which means we will consider it visible
319
+ // (this is legacy behavior from a very long way back)
320
+ // NOTE: we check this regardless of `displayCheck="none"` because this is a
321
+ // _visibility_ check, not a _display_ check
322
+ if (getComputedStyle(node).visibility === 'hidden') {
323
+ return true;
324
+ }
325
+ var isDirectSummary = matches.call(node, 'details>summary:first-of-type');
326
+ var nodeUnderDetails = isDirectSummary ? node.parentElement : node;
327
+ if (matches.call(nodeUnderDetails, 'details:not([open]) *')) {
328
+ return true;
329
+ }
330
+ if (!displayCheck || displayCheck === 'full' || displayCheck === 'legacy-full') {
331
+ if (typeof getShadowRoot === 'function') {
332
+ // figure out if we should consider the node to be in an undisclosed shadow and use the
333
+ // 'non-zero-area' fallback
334
+ var originalNode = node;
335
+ while (node) {
336
+ var parentElement = node.parentElement;
337
+ var rootNode = getRootNode(node);
338
+ if (parentElement && !parentElement.shadowRoot && getShadowRoot(parentElement) === true // check if there's an undisclosed shadow
339
+ ) {
340
+ // node has an undisclosed shadow which means we can only treat it as a black box, so we
341
+ // fall back to a non-zero-area test
342
+ return isZeroArea(node);
343
+ } else if (node.assignedSlot) {
344
+ // iterate up slot
345
+ node = node.assignedSlot;
346
+ } else if (!parentElement && rootNode !== node.ownerDocument) {
347
+ // cross shadow boundary
348
+ node = rootNode.host;
349
+ } else {
350
+ // iterate up normal dom
351
+ node = parentElement;
352
+ }
353
+ }
354
+ node = originalNode;
355
+ }
356
+ // else, `getShadowRoot` might be true, but all that does is enable shadow DOM support
357
+ // (i.e. it does not also presume that all nodes might have undisclosed shadows); or
358
+ // it might be a falsy value, which means shadow DOM support is disabled
359
+
360
+ // Since we didn't find it sitting in an undisclosed shadow (or shadows are disabled)
361
+ // now we can just test to see if it would normally be visible or not, provided it's
362
+ // attached to the main document.
363
+ // NOTE: We must consider case where node is inside a shadow DOM and given directly to
364
+ // `isTabbable()` or `isFocusable()` -- regardless of `getShadowRoot` option setting.
365
+
366
+ if (isNodeAttached(node)) {
367
+ // this works wherever the node is: if there's at least one client rect, it's
368
+ // somehow displayed; it also covers the CSS 'display: contents' case where the
369
+ // node itself is hidden in place of its contents; and there's no need to search
370
+ // up the hierarchy either
371
+ return !node.getClientRects().length;
372
+ }
373
+
374
+ // Else, the node isn't attached to the document, which means the `getClientRects()`
375
+ // API will __always__ return zero rects (this can happen, for example, if React
376
+ // is used to render nodes onto a detached tree, as confirmed in this thread:
377
+ // https://github.com/facebook/react/issues/9117#issuecomment-284228870)
378
+ //
379
+ // It also means that even window.getComputedStyle(node).display will return `undefined`
380
+ // because styles are only computed for nodes that are in the document.
381
+ //
382
+ // NOTE: THIS HAS BEEN THE CASE FOR YEARS. It is not new, nor is it caused by tabbable
383
+ // somehow. Though it was never stated officially, anyone who has ever used tabbable
384
+ // APIs on nodes in detached containers has actually implicitly used tabbable in what
385
+ // was later (as of v5.2.0 on Apr 9, 2021) called `displayCheck="none"` mode -- essentially
386
+ // considering __everything__ to be visible because of the innability to determine styles.
387
+ //
388
+ // v6.0.0: As of this major release, the default 'full' option __no longer treats detached
389
+ // nodes as visible with the 'none' fallback.__
390
+ if (displayCheck !== 'legacy-full') {
391
+ return true; // hidden
392
+ }
393
+ // else, fallback to 'none' mode and consider the node visible
394
+ } else if (displayCheck === 'non-zero-area') {
395
+ // NOTE: Even though this tests that the node's client rect is non-zero to determine
396
+ // whether it's displayed, and that a detached node will __always__ have a zero-area
397
+ // client rect, we don't special-case for whether the node is attached or not. In
398
+ // this mode, we do want to consider nodes that have a zero area to be hidden at all
399
+ // times, and that includes attached or not.
400
+ return isZeroArea(node);
401
+ }
402
+
403
+ // visible, as far as we can tell, or per current `displayCheck=none` mode, we assume
404
+ // it's visible
405
+ return false;
406
+ };
407
+
408
+ // form fields (nested) inside a disabled fieldset are not focusable/tabbable
409
+ // unless they are in the _first_ <legend> element of the top-most disabled
410
+ // fieldset
411
+ var isDisabledFromFieldset = function isDisabledFromFieldset(node) {
412
+ if (/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(node.tagName)) {
413
+ var parentNode = node.parentElement;
414
+ // check if `node` is contained in a disabled <fieldset>
415
+ while (parentNode) {
416
+ if (parentNode.tagName === 'FIELDSET' && parentNode.disabled) {
417
+ // look for the first <legend> among the children of the disabled <fieldset>
418
+ for (var i = 0; i < parentNode.children.length; i++) {
419
+ var child = parentNode.children.item(i);
420
+ // when the first <legend> (in document order) is found
421
+ if (child.tagName === 'LEGEND') {
422
+ // if its parent <fieldset> is not nested in another disabled <fieldset>,
423
+ // return whether `node` is a descendant of its first <legend>
424
+ return matches.call(parentNode, 'fieldset[disabled] *') ? true : !child.contains(node);
425
+ }
426
+ }
427
+ // the disabled <fieldset> containing `node` has no <legend>
428
+ return true;
429
+ }
430
+ parentNode = parentNode.parentElement;
431
+ }
432
+ }
433
+
434
+ // else, node's tabbable/focusable state should not be affected by a fieldset's
435
+ // enabled/disabled state
436
+ return false;
437
+ };
438
+ var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable(options, node) {
439
+ if (node.disabled ||
440
+ // we must do an inert look up to filter out any elements inside an inert ancestor
441
+ // because we're limited in the type of selectors we can use in JSDom (see related
442
+ // note related to `candidateSelectors`)
443
+ isInert(node) || isHiddenInput(node) || isHidden(node, options) ||
444
+ // For a details element with a summary, the summary element gets the focus
445
+ isDetailsWithSummary(node) || isDisabledFromFieldset(node)) {
446
+ return false;
447
+ }
448
+ return true;
449
+ };
450
+ var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable(options, node) {
451
+ if (isNonTabbableRadio(node) || getTabindex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
452
+ return false;
453
+ }
454
+ return true;
455
+ };
456
+ var isValidShadowRootTabbable = function isValidShadowRootTabbable(shadowHostNode) {
457
+ var tabIndex = parseInt(shadowHostNode.getAttribute('tabindex'), 10);
458
+ if (isNaN(tabIndex) || tabIndex >= 0) {
459
+ return true;
460
+ }
461
+ // If a custom element has an explicit negative tabindex,
462
+ // browsers will not allow tab targeting said element's children.
463
+ return false;
464
+ };
465
+
466
+ /**
467
+ * @param {Array.<Element|CandidateScope>} candidates
468
+ * @returns Element[]
469
+ */
470
+ var sortByOrder = function sortByOrder(candidates) {
471
+ var regularTabbables = [];
472
+ var orderedTabbables = [];
473
+ candidates.forEach(function (item, i) {
474
+ var isScope = !!item.scopeParent;
475
+ var element = isScope ? item.scopeParent : item;
476
+ var candidateTabindex = getTabindex(element, isScope);
477
+ var elements = isScope ? sortByOrder(item.candidates) : element;
478
+ if (candidateTabindex === 0) {
479
+ isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element);
480
+ } else {
481
+ orderedTabbables.push({
482
+ documentOrder: i,
483
+ tabIndex: candidateTabindex,
484
+ item: item,
485
+ isScope: isScope,
486
+ content: elements
487
+ });
488
+ }
489
+ });
490
+ return orderedTabbables.sort(sortOrderedTabbables).reduce(function (acc, sortable) {
491
+ sortable.isScope ? acc.push.apply(acc, sortable.content) : acc.push(sortable.content);
492
+ return acc;
493
+ }, []).concat(regularTabbables);
494
+ };
495
+ var tabbable = function tabbable(el, options) {
496
+ options = options || {};
497
+ var candidates;
498
+ if (options.getShadowRoot) {
499
+ candidates = getCandidatesIteratively([el], options.includeContainer, {
500
+ filter: isNodeMatchingSelectorTabbable.bind(null, options),
501
+ flatten: false,
502
+ getShadowRoot: options.getShadowRoot,
503
+ shadowRootFilter: isValidShadowRootTabbable
504
+ });
505
+ } else {
506
+ candidates = getCandidates(el, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
507
+ }
508
+ return sortByOrder(candidates);
509
+ };
510
+ var focusable = function focusable(el, options) {
511
+ options = options || {};
512
+ var candidates;
513
+ if (options.getShadowRoot) {
514
+ candidates = getCandidatesIteratively([el], options.includeContainer, {
515
+ filter: isNodeMatchingSelectorFocusable.bind(null, options),
516
+ flatten: true,
517
+ getShadowRoot: options.getShadowRoot
518
+ });
519
+ } else {
520
+ candidates = getCandidates(el, options.includeContainer, isNodeMatchingSelectorFocusable.bind(null, options));
521
+ }
522
+ return candidates;
523
+ };
524
+ var isTabbable = function isTabbable(node, options) {
525
+ options = options || {};
526
+ if (!node) {
527
+ throw new Error('No node provided');
528
+ }
529
+ if (matches.call(node, candidateSelector) === false) {
530
+ return false;
531
+ }
532
+ return isNodeMatchingSelectorTabbable(options, node);
533
+ };
534
+ var focusableCandidateSelector = /* #__PURE__ */candidateSelectors.concat('iframe').join(',');
535
+ var isFocusable = function isFocusable(node, options) {
536
+ options = options || {};
537
+ if (!node) {
538
+ throw new Error('No node provided');
539
+ }
540
+ if (matches.call(node, focusableCandidateSelector) === false) {
541
+ return false;
542
+ }
543
+ return isNodeMatchingSelectorFocusable(options, node);
544
+ };
545
+
546
+ /*!
547
+ * focus-trap 7.4.3
12
548
  * @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
13
549
  */
14
550
 
@@ -217,23 +753,24 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
217
753
  /**
218
754
  * Finds the index of the container that contains the element.
219
755
  * @param {HTMLElement} element
756
+ * @param {Event} [event]
220
757
  * @returns {number} Index of the container in either `state.containers` or
221
758
  * `state.containerGroups` (the order/length of these lists are the same); -1
222
759
  * if the element isn't found.
223
760
  */
224
- var findContainerIndex = function findContainerIndex(element) {
761
+ var findContainerIndex = function findContainerIndex(element, event) {
762
+ var composedPath = typeof (event === null || event === void 0 ? void 0 : event.composedPath) === 'function' ? event.composedPath() : undefined;
225
763
  // NOTE: search `containerGroups` because it's possible a group contains no tabbable
226
764
  // nodes, but still contains focusable nodes (e.g. if they all have `tabindex=-1`)
227
765
  // and we still need to find the element in there
228
766
  return state.containerGroups.findIndex(function (_ref) {
229
767
  var container = _ref.container,
230
768
  tabbableNodes = _ref.tabbableNodes;
231
- return container.contains(element) ||
232
- // fall back to explicit tabbable search which will take into consideration any
769
+ return container.contains(element) || ( // fall back to explicit tabbable search which will take into consideration any
233
770
  // web components if the `tabbableOptions.getShadowRoot` option was used for
234
771
  // the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't
235
772
  // look inside web components even if open)
236
- tabbableNodes.find(function (node) {
773
+ composedPath === null || composedPath === void 0 ? void 0 : composedPath.includes(container)) || tabbableNodes.find(function (node) {
237
774
  return node === element;
238
775
  });
239
776
  });
@@ -289,8 +826,8 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
289
826
  if (node === false) {
290
827
  return false;
291
828
  }
292
- if (node === undefined) {
293
- // option not specified: use fallback options
829
+ if (node === undefined || !isFocusable(node, config.tabbableOptions)) {
830
+ // option not specified nor focusable: use fallback options
294
831
  if (findContainerIndex(doc.activeElement) >= 0) {
295
832
  node = doc.activeElement;
296
833
  } else {
@@ -394,25 +931,20 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
394
931
  // so that it precedes the focus event.
395
932
  var checkPointerDown = function checkPointerDown(e) {
396
933
  var target = getActualTarget(e);
397
- if (findContainerIndex(target) >= 0) {
934
+ if (findContainerIndex(target, e) >= 0) {
398
935
  // allow the click since it ocurred inside the trap
399
936
  return;
400
937
  }
401
938
  if (valueOrHandler(config.clickOutsideDeactivates, e)) {
402
939
  // immediately deactivate the trap
403
940
  trap.deactivate({
404
- // if, on deactivation, we should return focus to the node originally-focused
405
- // when the trap was activated (or the configured `setReturnFocus` node),
406
- // then assume it's also OK to return focus to the outside node that was
407
- // just clicked, causing deactivation, as long as that node is focusable;
408
- // if it isn't focusable, then return focus to the original node focused
409
- // on activation (or the configured `setReturnFocus` node)
410
941
  // NOTE: by setting `returnFocus: false`, deactivate() will do nothing,
411
942
  // which will result in the outside click setting focus to the node
412
- // that was clicked, whether it's focusable or not; by setting
943
+ // that was clicked (and if not focusable, to "nothing"); by setting
413
944
  // `returnFocus: true`, we'll attempt to re-focus the node originally-focused
414
- // on activation (or the configured `setReturnFocus` node)
415
- returnFocus: config.returnFocusOnDeactivate && !isFocusable(target, config.tabbableOptions)
945
+ // on activation (or the configured `setReturnFocus` node), whether the
946
+ // outside click was on a focusable node or not
947
+ returnFocus: config.returnFocusOnDeactivate
416
948
  });
417
949
  return;
418
950
  }
@@ -432,7 +964,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
432
964
  // In case focus escapes the trap for some strange reason, pull it back in.
433
965
  var checkFocusIn = function checkFocusIn(e) {
434
966
  var target = getActualTarget(e);
435
- var targetContained = findContainerIndex(target) >= 0;
967
+ var targetContained = findContainerIndex(target, e) >= 0;
436
968
 
437
969
  // In Firefox when you Tab out of an iframe the Document is briefly focused.
438
970
  if (targetContained || target instanceof Document) {
@@ -459,7 +991,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
459
991
  // make sure the target is actually contained in a group
460
992
  // NOTE: the target may also be the container itself if it's focusable
461
993
  // with tabIndex='-1' and was given initial focus
462
- var containerIndex = findContainerIndex(target);
994
+ var containerIndex = findContainerIndex(target, event);
463
995
  var containerGroup = containerIndex >= 0 ? state.containerGroups[containerIndex] : undefined;
464
996
  if (containerIndex < 0) {
465
997
  // target not found in any group: quite possible focus has escaped the trap,
@@ -560,7 +1092,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
560
1092
  };
561
1093
  var checkClick = function checkClick(e) {
562
1094
  var target = getActualTarget(e);
563
- if (findContainerIndex(target) >= 0) {
1095
+ if (findContainerIndex(target, e) >= 0) {
564
1096
  return;
565
1097
  }
566
1098
  if (valueOrHandler(config.clickOutsideDeactivates, e)) {
@@ -621,6 +1153,43 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
621
1153
  return trap;
622
1154
  };
623
1155
 
1156
+ //
1157
+ // MUTATION OBSERVER
1158
+ //
1159
+
1160
+ var checkDomRemoval = function checkDomRemoval(mutations) {
1161
+ var isFocusedNodeRemoved = mutations.some(function (mutation) {
1162
+ var removedNodes = Array.from(mutation.removedNodes);
1163
+ return removedNodes.some(function (node) {
1164
+ return node === state.mostRecentlyFocusedNode;
1165
+ });
1166
+ });
1167
+
1168
+ // If the currently focused is removed then browsers will move focus to the
1169
+ // <body> element. If this happens, try to move focus back into the trap.
1170
+ if (isFocusedNodeRemoved) {
1171
+ tryFocus(getInitialFocusNode());
1172
+ }
1173
+ };
1174
+
1175
+ // Use MutationObserver - if supported - to detect if focused node is removed
1176
+ // from the DOM.
1177
+ var mutationObserver = typeof window !== 'undefined' && 'MutationObserver' in window ? new MutationObserver(checkDomRemoval) : undefined;
1178
+ var updateObservedNodes = function updateObservedNodes() {
1179
+ if (!mutationObserver) {
1180
+ return;
1181
+ }
1182
+ mutationObserver.disconnect();
1183
+ if (state.active && !state.paused) {
1184
+ state.containers.map(function (container) {
1185
+ mutationObserver.observe(container, {
1186
+ subtree: true,
1187
+ childList: true
1188
+ });
1189
+ });
1190
+ }
1191
+ };
1192
+
624
1193
  //
625
1194
  // TRAP DEFINITION
626
1195
  //
@@ -645,17 +1214,14 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
645
1214
  state.active = true;
646
1215
  state.paused = false;
647
1216
  state.nodeFocusedBeforeActivation = doc.activeElement;
648
- if (onActivate) {
649
- onActivate();
650
- }
1217
+ onActivate === null || onActivate === void 0 ? void 0 : onActivate();
651
1218
  var finishActivation = function finishActivation() {
652
1219
  if (checkCanFocusTrap) {
653
1220
  updateTabbableNodes();
654
1221
  }
655
1222
  addListeners();
656
- if (onPostActivate) {
657
- onPostActivate();
658
- }
1223
+ updateObservedNodes();
1224
+ onPostActivate === null || onPostActivate === void 0 ? void 0 : onPostActivate();
659
1225
  };
660
1226
  if (checkCanFocusTrap) {
661
1227
  checkCanFocusTrap(state.containers.concat()).then(finishActivation, finishActivation);
@@ -678,22 +1244,19 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
678
1244
  removeListeners();
679
1245
  state.active = false;
680
1246
  state.paused = false;
1247
+ updateObservedNodes();
681
1248
  activeFocusTraps.deactivateTrap(trapStack, trap);
682
1249
  var onDeactivate = getOption(options, 'onDeactivate');
683
1250
  var onPostDeactivate = getOption(options, 'onPostDeactivate');
684
1251
  var checkCanReturnFocus = getOption(options, 'checkCanReturnFocus');
685
1252
  var returnFocus = getOption(options, 'returnFocus', 'returnFocusOnDeactivate');
686
- if (onDeactivate) {
687
- onDeactivate();
688
- }
1253
+ onDeactivate === null || onDeactivate === void 0 ? void 0 : onDeactivate();
689
1254
  var finishDeactivation = function finishDeactivation() {
690
1255
  delay(function () {
691
1256
  if (returnFocus) {
692
1257
  tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
693
1258
  }
694
- if (onPostDeactivate) {
695
- onPostDeactivate();
696
- }
1259
+ onPostDeactivate === null || onPostDeactivate === void 0 ? void 0 : onPostDeactivate();
697
1260
  });
698
1261
  };
699
1262
  if (returnFocus && checkCanReturnFocus) {
@@ -703,21 +1266,31 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
703
1266
  finishDeactivation();
704
1267
  return this;
705
1268
  },
706
- pause: function pause() {
1269
+ pause: function pause(pauseOptions) {
707
1270
  if (state.paused || !state.active) {
708
1271
  return this;
709
1272
  }
1273
+ var onPause = getOption(pauseOptions, 'onPause');
1274
+ var onPostPause = getOption(pauseOptions, 'onPostPause');
710
1275
  state.paused = true;
1276
+ onPause === null || onPause === void 0 ? void 0 : onPause();
711
1277
  removeListeners();
1278
+ updateObservedNodes();
1279
+ onPostPause === null || onPostPause === void 0 ? void 0 : onPostPause();
712
1280
  return this;
713
1281
  },
714
- unpause: function unpause() {
1282
+ unpause: function unpause(unpauseOptions) {
715
1283
  if (!state.paused || !state.active) {
716
1284
  return this;
717
1285
  }
1286
+ var onUnpause = getOption(unpauseOptions, 'onUnpause');
1287
+ var onPostUnpause = getOption(unpauseOptions, 'onPostUnpause');
718
1288
  state.paused = false;
1289
+ onUnpause === null || onUnpause === void 0 ? void 0 : onUnpause();
719
1290
  updateTabbableNodes();
720
1291
  addListeners();
1292
+ updateObservedNodes();
1293
+ onPostUnpause === null || onPostUnpause === void 0 ? void 0 : onPostUnpause();
721
1294
  return this;
722
1295
  },
723
1296
  updateContainerElements: function updateContainerElements(containerElements) {
@@ -728,6 +1301,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
728
1301
  if (state.active) {
729
1302
  updateTabbableNodes();
730
1303
  }
1304
+ updateObservedNodes();
731
1305
  return this;
732
1306
  }
733
1307
  };
@@ -737,7 +1311,11 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
737
1311
  return trap;
738
1312
  };
739
1313
 
740
- const catDropdownCss = ":host{display:contents}:host([hidden]){display:none}::slotted(nav){padding-top:0.5rem;padding-bottom:0.5rem;min-width:8rem;max-width:16rem}.content{position:fixed;background:white;display:none;-webkit-overflow-scrolling:touch;min-height:2rem;max-height:calc(100vh - 48px);box-shadow:0 4px 6px -2px rgba(27, 31, 38, 0.03), 0 12px 16px -4px rgba(27, 31, 38, 0.08);border-radius:var(--cat-border-radius-m, 0.25rem);z-index:100;opacity:0;transition:transform 0.13s cubic-bezier(0.3, 0, 0.8, 0.15), opacity 0.13s cubic-bezier(0.3, 0, 0.8, 0.15)}.content[data-placement^=top]{transform:translateY(1rem)}.content[data-placement^=left]{transform:translateX(1rem)}.content[data-placement^=right]{transform:translateX(-1rem)}.content[data-placement^=bottom]{transform:translateY(-1rem)}.content.show{opacity:1;transform:translateX(0);transform:translateY(0);transition:transform 0.5s cubic-bezier(0.05, 0.7, 0.1, 1), opacity 0.5s cubic-bezier(0.05, 0.7, 0.1, 1)}.content.overflow-auto{overflow:auto}";
1314
+ const firstTabbable = (container) => {
1315
+ return (container ? tabbable(container, { includeContainer: true, getShadowRoot: true }) : []).shift();
1316
+ };
1317
+
1318
+ const catDropdownCss = ":host{display:contents}:host([hidden]){display:none}::slotted(nav){padding-top:0.5rem;padding-bottom:0.5rem;min-width:8rem;max-width:16rem}.content{position:fixed;background:white;display:none;-webkit-overflow-scrolling:touch;min-height:2rem;max-height:calc(100vh - 48px);box-shadow:0 4px 6px -2px rgba(27, 31, 38, 0.03), 0 12px 16px -4px rgba(27, 31, 38, 0.08);border-radius:var(--cat-border-radius-m, 0.25rem);border:1px solid rgb(var(--cat-border-color, 235, 236, 240));z-index:100;opacity:0;transition:transform 0.13s cubic-bezier(0.3, 0, 0.8, 0.15), opacity 0.13s cubic-bezier(0.3, 0, 0.8, 0.15)}.content[data-placement^=top]{transform:translateY(1rem)}.content[data-placement^=left]{transform:translateX(1rem)}.content[data-placement^=right]{transform:translateX(-1rem)}.content[data-placement^=bottom]{transform:translateY(-1rem)}.content.show{opacity:1;transform:translateX(0);transform:translateY(0);transition:transform 0.5s cubic-bezier(0.05, 0.7, 0.1, 1), opacity 0.5s cubic-bezier(0.05, 0.7, 0.1, 1)}.content.overflow-auto{overflow:auto}";
741
1319
 
742
1320
  let nextUniqueId = 0;
743
1321
  const CatDropdown = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
@@ -761,8 +1339,9 @@ const CatDropdown = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
761
1339
  this.initTrigger();
762
1340
  this.toggle();
763
1341
  }
1342
+ const button = event.target;
764
1343
  // hide dropdown on button click
765
- if (!this.noAutoClose && event.composedPath().includes(this.content)) {
1344
+ if (!this.noAutoClose && event.composedPath().includes(this.content) && button.slot !== 'trigger') {
766
1345
  this.close();
767
1346
  }
768
1347
  }
@@ -795,9 +1374,15 @@ const CatDropdown = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
795
1374
  getShadowRoot: true
796
1375
  },
797
1376
  allowOutsideClick: true,
798
- clickOutsideDeactivates: event => !this.noAutoClose &&
799
- !event.composedPath().includes(this.content) &&
800
- (!this.trigger || !event.composedPath().includes(this.trigger)),
1377
+ clickOutsideDeactivates: event => {
1378
+ const shouldClose = !this.noAutoClose &&
1379
+ !event.composedPath().includes(this.content) &&
1380
+ (!this.trigger || !event.composedPath().includes(this.trigger));
1381
+ if (shouldClose) {
1382
+ this.close();
1383
+ }
1384
+ return shouldClose;
1385
+ },
801
1386
  onPostDeactivate: () => this.close()
802
1387
  });
803
1388
  this.trap.activate();
@@ -807,7 +1392,7 @@ const CatDropdown = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
807
1392
  * Closes the dropdown.
808
1393
  */
809
1394
  async close() {
810
- if (this.isOpen === null) {
1395
+ if (this.isOpen === null || !this.isOpen) {
811
1396
  return; // busy
812
1397
  }
813
1398
  this.isOpen = null;
@@ -879,7 +1464,19 @@ const CatDropdown = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
879
1464
  computePosition(this.trigger, this.content, {
880
1465
  strategy: 'fixed',
881
1466
  placement: this.placement,
882
- middleware: [offset(CatDropdown.OFFSET), flip()]
1467
+ middleware: [
1468
+ offset(CatDropdown.OFFSET),
1469
+ flip(),
1470
+ size({
1471
+ padding: CatDropdown.OFFSET,
1472
+ apply({ availableWidth, availableHeight, elements }) {
1473
+ Object.assign(elements.floating.style, {
1474
+ maxWidth: `${availableWidth}px`,
1475
+ maxHeight: `${availableHeight}px`
1476
+ });
1477
+ }
1478
+ })
1479
+ ]
883
1480
  }).then(({ x, y, placement }) => {
884
1481
  this.content.dataset.placement = placement;
885
1482
  Object.assign(this.content.style, {