@oscarpalmer/oui 0.18.0 → 0.19.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 (44) hide show
  1. package/dist/css/badge.css +10 -10
  2. package/dist/css/button.css +9 -9
  3. package/dist/css/color.css +99 -99
  4. package/dist/css/content.css +1 -1
  5. package/dist/css/flex.css +39 -39
  6. package/dist/css/form.css +29 -56
  7. package/dist/css/message.css +6 -6
  8. package/dist/css/reset.css +3 -2
  9. package/dist/css/table.css +4 -4
  10. package/dist/css/tooltip.css +18 -1
  11. package/dist/js/attributable.full.js +29 -41
  12. package/dist/js/floatable.full.js +322 -337
  13. package/dist/js/focus-trap/embedded.full.js +252 -195
  14. package/dist/js/focus-trap/standalone.full.js +283 -238
  15. package/dist/js/index.js +3 -3
  16. package/dist/js/oui.full.js +1170 -1193
  17. package/dist/js/popover.full.js +568 -630
  18. package/dist/js/popover.js +1 -1
  19. package/dist/js/splitter.full.js +533 -369
  20. package/dist/js/splitter.js +2 -2
  21. package/dist/js/tooltip.full.js +488 -554
  22. package/dist/js/tooltip.js +1 -1
  23. package/package.json +19 -19
  24. package/src/css/a11y.scss +1 -1
  25. package/src/css/badge.scss +23 -19
  26. package/src/css/button.scss +9 -9
  27. package/src/css/color.scss +99 -99
  28. package/src/css/content.scss +6 -8
  29. package/src/css/flex.scss +21 -20
  30. package/src/css/form.scss +37 -60
  31. package/src/css/message.scss +8 -12
  32. package/src/css/mixins.scss +11 -12
  33. package/src/css/popover.scss +2 -2
  34. package/src/css/reset.scss +14 -14
  35. package/src/css/splitter.scss +15 -13
  36. package/src/css/table.scss +11 -11
  37. package/src/css/tooltip.scss +25 -4
  38. package/src/js/attributable.ts +3 -10
  39. package/src/js/floatable.ts +7 -25
  40. package/src/js/focus-trap/embedded.ts +6 -24
  41. package/src/js/popover.ts +3 -3
  42. package/src/js/splitter.ts +9 -39
  43. package/src/js/tooltip.ts +5 -17
  44. package/dist/css/value.css +0 -1
@@ -1,39 +1,54 @@
1
1
  function isNumber(value) {
2
2
  return typeof value === "number" && !Number.isNaN(value);
3
3
  }
4
-
5
4
  function getString(value) {
6
5
  if (typeof value === "string") return value;
7
6
  if (value == null) return "";
7
+ if (typeof value === "function") return getString(value());
8
8
  if (typeof value !== "object") return String(value);
9
9
  const asString = String(value.valueOf?.() ?? value);
10
10
  return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
11
11
  }
12
-
13
12
  function isNullableOrWhitespace(value) {
14
13
  return value == null || EXPRESSION_WHITESPACE.test(getString(value));
15
14
  }
16
15
  var EXPRESSION_WHITESPACE = /^\s*$/;
17
-
18
16
  function getFocusable(parent) {
19
- return getValidElements(parent, FILTERS_FOCUSABLE);
17
+ return getValidElements(parent, FILTERS_FOCUSABLE, false);
20
18
  }
21
19
  function getItem(element, tabbable) {
22
20
  return {
23
21
  element,
24
- tabIndex: TABINDEX_DEFAULT
22
+ tabIndex: tabbable ? getTabIndex(element) : TABINDEX_DEFAULT
25
23
  };
26
24
  }
25
+ function getTabIndex(element) {
26
+ const tabIndex = element?.tabIndex ?? TABINDEX_DEFAULT;
27
+ if (tabIndex < TABINDEX_BASE && (EXPRESSION_SPECIAL_TABINDEX.test(element.tagName) || isEditable(element)) && !hasTabIndex(element)) return TABINDEX_BASE;
28
+ return tabIndex;
29
+ }
27
30
  function getValidElements(parent, filters, tabbable) {
28
31
  if (!(parent instanceof Element)) return [];
29
32
  const elements = [...parent.querySelectorAll(SELECTOR_FULL)];
30
33
  const items = [];
31
34
  let { length } = elements;
32
- for (let index = 0; index < length; index += 1) {
33
- const item = getItem(elements[index]);
35
+ for (let index$1 = 0; index$1 < length; index$1 += 1) {
36
+ const item = getItem(elements[index$1], tabbable);
34
37
  if (!filters.some((filter) => filter(item))) items.push(item);
35
38
  }
36
- return items.map((item) => item.element);
39
+ if (!tabbable) return items.map((item) => item.element);
40
+ const indiced = [];
41
+ const zeroed = [];
42
+ length = items.length;
43
+ for (let index$1 = 0; index$1 < length; index$1 += 1) {
44
+ const item = items[index$1];
45
+ if (item.tabIndex === TABINDEX_BASE) zeroed.push(item.element);
46
+ else indiced[item.tabIndex] = [...indiced[item.tabIndex] ?? [], item.element];
47
+ }
48
+ return [...indiced.flat(), ...zeroed];
49
+ }
50
+ function hasTabIndex(element) {
51
+ return !Number.isNaN(Number.parseInt(element.getAttribute(ATTRIBUTE_TABINDEX), 10));
37
52
  }
38
53
  function isDisabled$1(item) {
39
54
  if (EXPRESSION_DISABLEABLE.test(item.element.tagName) && isDisabledFromFieldset(item.element)) return true;
@@ -45,8 +60,8 @@ function isDisabledFromFieldset(element) {
45
60
  if (parent instanceof HTMLFieldSetElement && parent.disabled) {
46
61
  const children = Array.from(parent.children);
47
62
  const { length } = children;
48
- for (let index = 0; index < length; index += 1) {
49
- const child = children[index];
63
+ for (let index$1 = 0; index$1 < length; index$1 += 1) {
64
+ const child = children[index$1];
50
65
  if (child instanceof HTMLLegendElement) return parent.matches(SELECTOR_FIELDSET_DISABLED) || !child.contains(element);
51
66
  }
52
67
  return true;
@@ -55,6 +70,9 @@ function isDisabledFromFieldset(element) {
55
70
  }
56
71
  return false;
57
72
  }
73
+ function isEditable(element) {
74
+ return EXPRESSION_TRUEISH.test(element.getAttribute(ATTRIBUTE_CONTENTEDITABLE));
75
+ }
58
76
  function isHidden(item) {
59
77
  if ((item.element.hidden ?? false) || item.element instanceof HTMLInputElement && item.element.type === STYLE_HIDDEN) return true;
60
78
  if ((item.element.matches(SELECTOR_SUMMARY_FIRST) ? item.element.parentElement : item.element)?.matches(SELECTOR_DETAILS_CLOSED_CHILDREN) ?? false) return true;
@@ -65,13 +83,18 @@ function isHidden(item) {
65
83
  }
66
84
  function isInert(item) {
67
85
  return (item.element.inert ?? false) || EXPRESSION_TRUEISH.test(item.element.getAttribute(ATTRIBUTE_INERT)) || item.element.parentElement != null && isInert({
68
- element: item.element.parentElement});
86
+ element: item.element.parentElement,
87
+ tabIndex: TABINDEX_DEFAULT
88
+ });
69
89
  }
70
90
  function isSummarised(item) {
71
91
  return item.element instanceof HTMLDetailsElement && [...item.element.children].some((child) => EXPRESSION_SUMMARY.test(child.tagName));
72
92
  }
93
+ var ATTRIBUTE_CONTENTEDITABLE = "contenteditable";
73
94
  var ATTRIBUTE_INERT = "inert";
95
+ var ATTRIBUTE_TABINDEX = "tabindex";
74
96
  var EXPRESSION_DISABLEABLE = /^(button|input|select|textarea)$/i;
97
+ var EXPRESSION_SPECIAL_TABINDEX = /^(audio|details|video)$/i;
75
98
  var EXPRESSION_SUMMARY = /^summary$/i;
76
99
  var EXPRESSION_TRUEISH = /^(|true)$/i;
77
100
  var FILTERS_FOCUSABLE = [
@@ -80,6 +103,7 @@ var FILTERS_FOCUSABLE = [
80
103
  isHidden,
81
104
  isSummarised
82
105
  ];
106
+ [...FILTERS_FOCUSABLE];
83
107
  var SELECTOR_DETAILS_CLOSED_CHILDREN = "details:not([open]) *";
84
108
  var SELECTOR_FIELDSET_DISABLED = "fieldset[disabled] *";
85
109
  var SELECTOR_SUMMARY_FIRST = "details > summary:first-of-type";
@@ -98,26 +122,9 @@ var SELECTOR_FULL = [
98
122
  ].map((selector) => `${selector}:not([inert])`).join(",");
99
123
  var STYLE_HIDDEN = "hidden";
100
124
  var STYLE_NONE = "none";
125
+ var TABINDEX_BASE = 0;
101
126
  var TABINDEX_DEFAULT = -1;
102
-
103
- function isEventTarget(value) {
104
- return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
105
- }
106
-
107
- function getBoolean(value, defaultValue) {
108
- return typeof value === "boolean" ? value : defaultValue ?? false;
109
- }
110
-
111
- function clamp(value, minimum, maximum, loop) {
112
- if (![
113
- value,
114
- minimum,
115
- maximum
116
- ].every(isNumber)) return NaN;
117
- if (value < minimum) return maximum ;
118
- return value > maximum ? minimum : value;
119
- }
120
-
127
+ function noop() {}
121
128
  function calculate() {
122
129
  return new Promise((resolve) => {
123
130
  const values = [];
@@ -125,37 +132,131 @@ function calculate() {
125
132
  function step(now) {
126
133
  if (last != null) values.push(now - last);
127
134
  last = now;
128
- if (values.length >= CALCULATION_TOTAL) {
129
- const median = values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - CALCULATION_TRIM);
130
- resolve(median);
131
- } else requestAnimationFrame(step);
135
+ if (values.length >= TOTAL) resolve(values.sort().slice(TRIM_PART, -TRIM_PART).reduce((first, second) => first + second, 0) / (values.length - TRIM_TOTAL));
136
+ else requestAnimationFrame(step);
132
137
  }
133
138
  requestAnimationFrame(step);
134
139
  });
135
140
  }
136
- function noop() {}
137
- var CALCULATION_TOTAL = 10;
138
- var CALCULATION_TRIM = 4;
139
- calculate().then((value) => {
140
- });
141
-
141
+ var TOTAL = 10;
142
+ var TRIM_PART = 2;
143
+ var TRIM_TOTAL = 4;
144
+ await calculate();
145
+ function clamp(value, minimum, maximum, loop) {
146
+ if (![
147
+ value,
148
+ minimum,
149
+ maximum
150
+ ].every(isNumber)) return NaN;
151
+ if (value < minimum) return loop === true ? maximum : minimum;
152
+ return value > maximum ? loop === true ? minimum : maximum : value;
153
+ }
154
+ function getBoolean(value, defaultValue) {
155
+ return typeof value === "boolean" ? value : defaultValue ?? false;
156
+ }
157
+ function isEventTarget(value) {
158
+ return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
159
+ }
160
+ function addDelegatedHandler(doc, type, name, passive) {
161
+ if (DELEGATED.has(name)) return;
162
+ DELEGATED.add(name);
163
+ doc.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
164
+ }
165
+ function addDelegatedListener(target, type, name, listener, passive) {
166
+ target[name] ??= /* @__PURE__ */ new Set();
167
+ target[name].add(listener);
168
+ addDelegatedHandler(document, type, name, passive);
169
+ return () => {
170
+ removeDelegatedListener(target, name, listener);
171
+ };
172
+ }
173
+ function delegatedEventHandler(event) {
174
+ const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
175
+ const items = event.composedPath();
176
+ const { length } = items;
177
+ let target = items[0];
178
+ Object.defineProperties(event, {
179
+ currentTarget: {
180
+ configurable: true,
181
+ get() {
182
+ return target;
183
+ }
184
+ },
185
+ target: {
186
+ configurable: true,
187
+ value: target
188
+ }
189
+ });
190
+ for (let index$1 = 0; index$1 < length; index$1 += 1) {
191
+ const item = items[index$1];
192
+ const listeners = item[key];
193
+ if (item.disabled || listeners == null) continue;
194
+ target = item;
195
+ for (const listener of listeners) {
196
+ listener.call(item, event);
197
+ if (event.cancelBubble) return;
198
+ }
199
+ }
200
+ }
201
+ function getDelegatedName(target, type, options) {
202
+ if (isEventTarget(target) && EVENT_TYPES.has(type) && !options.capture && !options.once && options.signal == null) return `${EVENT_PREFIX}${type}${options.passive ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
203
+ }
204
+ function removeDelegatedListener(target, name, listener) {
205
+ const handlers = target[name];
206
+ if (handlers == null || !handlers.has(listener)) return false;
207
+ handlers.delete(listener);
208
+ if (handlers.size === 0) target[name] = void 0;
209
+ return true;
210
+ }
211
+ var DELEGATED = /* @__PURE__ */ new Set();
212
+ var EVENT_PREFIX = "@";
213
+ var EVENT_SUFFIX_ACTIVE = ":active";
214
+ var EVENT_SUFFIX_PASSIVE = ":passive";
215
+ var EVENT_TYPES = new Set([
216
+ "beforeinput",
217
+ "click",
218
+ "dblclick",
219
+ "contextmenu",
220
+ "focusin",
221
+ "focusout",
222
+ "input",
223
+ "keydown",
224
+ "keyup",
225
+ "mousedown",
226
+ "mousemove",
227
+ "mouseout",
228
+ "mouseover",
229
+ "mouseup",
230
+ "pointerdown",
231
+ "pointermove",
232
+ "pointerout",
233
+ "pointerover",
234
+ "pointerup",
235
+ "touchend",
236
+ "touchmove",
237
+ "touchstart"
238
+ ]);
239
+ var HANDLER_ACTIVE = delegatedEventHandler.bind(false);
240
+ var HANDLER_PASSIVE = delegatedEventHandler.bind(true);
142
241
  function createEventOptions(options) {
143
242
  return {
144
243
  capture: getBoolean(options?.capture),
145
244
  once: getBoolean(options?.once),
146
245
  passive: getBoolean(options?.passive, true),
147
- signal: options?.signal
246
+ signal: options?.signal instanceof AbortSignal ? options.signal : void 0
148
247
  };
149
248
  }
150
249
  function on(target, type, listener, options) {
151
250
  if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return noop;
152
251
  const extended = createEventOptions(options);
252
+ const delegated = getDelegatedName(target, type, extended);
253
+ if (delegated != null) return addDelegatedListener(target, type, delegated, listener, extended.passive);
153
254
  target.addEventListener(type, listener, extended);
255
+ if (extended.once) return noop;
154
256
  return () => {
155
257
  target.removeEventListener(type, listener, extended);
156
258
  };
157
259
  }
158
-
159
260
  function findAncestor(origin, selector) {
160
261
  if (!(origin instanceof Element) || selector == null) return null;
161
262
  if (typeof selector === "string") {
@@ -171,652 +272,489 @@ function findAncestor(origin, selector) {
171
272
  }
172
273
  return parent;
173
274
  }
174
-
175
- class Floatable {
176
- options;
177
- active = false;
178
- disabled = false;
179
- frame;
180
- ignoreFocus = false;
181
- constructor(options) {
182
- this.options = options;
183
- initialize(this);
184
- }
185
- destroy() {
186
- stop(this);
187
- const state = getState();
188
- state?.active.delete(this);
189
- state?.mapped.delete(this.options.anchor);
190
- state?.mapped.delete(this.options.content);
191
- this.options.anchor = undefined;
192
- this.options.content = undefined;
193
- }
194
- disable() {
195
- if (this.disabled) {
196
- return;
197
- }
198
- this.disabled = true;
199
- stop(this);
200
- getState()?.active.delete(this);
201
- }
202
- enable() {
203
- if (!this.disabled) {
204
- return;
205
- }
206
- this.disabled = false;
207
- initialize(this);
208
- }
209
- toggle(active, ignoreFocus) {
210
- if (this.disabled || this.active === active) {
211
- return;
212
- }
213
- const state = getState();
214
- if (state == null) {
215
- return;
216
- }
217
- this.ignoreFocus = !active && (ignoreFocus ?? false);
218
- stop(this);
219
- if (active) {
220
- state.active.add(this);
221
- }
222
- else {
223
- state.active.delete(this);
224
- }
225
- if (this.options.interactive) {
226
- if (active) {
227
- state.order.push(this);
228
- }
229
- else {
230
- const index = state.order.indexOf(this);
231
- if (index > -1) {
232
- state.order.splice(index, 1);
233
- }
234
- }
235
- }
236
- if (active) {
237
- activate(this);
238
- }
239
- else {
240
- deactivate(this);
241
- }
242
- }
243
- }
244
- //
275
+ var Floatable = class {
276
+ active = false;
277
+ disabled = false;
278
+ frame;
279
+ ignoreFocus = false;
280
+ constructor(options) {
281
+ this.options = options;
282
+ initialize(this);
283
+ }
284
+ destroy() {
285
+ stop(this);
286
+ const state = getState();
287
+ state?.active.delete(this);
288
+ state?.mapped.delete(this.options.anchor);
289
+ state?.mapped.delete(this.options.content);
290
+ this.options.anchor = void 0;
291
+ this.options.content = void 0;
292
+ }
293
+ disable() {
294
+ if (this.disabled) return;
295
+ this.disabled = true;
296
+ stop(this);
297
+ getState()?.active.delete(this);
298
+ }
299
+ enable() {
300
+ if (!this.disabled) return;
301
+ this.disabled = false;
302
+ initialize(this);
303
+ }
304
+ toggle(active, ignoreFocus) {
305
+ if (this.disabled || this.active === active) return;
306
+ const state = getState();
307
+ if (state == null) return;
308
+ this.ignoreFocus = !active && (ignoreFocus ?? false);
309
+ stop(this);
310
+ if (active) state.active.add(this);
311
+ else state.active.delete(this);
312
+ if (this.options.interactive) if (active) state.order.push(this);
313
+ else {
314
+ const index$1 = state.order.indexOf(this);
315
+ if (index$1 > -1) state.order.splice(index$1, 1);
316
+ }
317
+ if (active) activate(this);
318
+ else deactivate(this);
319
+ }
320
+ };
245
321
  function activate(floatable) {
246
- floatable.active = true;
247
- document.body.append(floatable.options.content);
248
- floatable.options.content.hidden = false;
249
- updatePosition(floatable);
322
+ floatable.active = true;
323
+ document.body.append(floatable.options.content);
324
+ floatable.options.content.hidden = false;
325
+ updatePosition(floatable);
250
326
  }
251
327
  function closeAbove(element) {
252
- const state = getState();
253
- if (state == null) {
254
- return;
255
- }
256
- const index = state.order.findIndex(floatable => floatable.options.anchor === element ||
257
- floatable.options.content === element);
258
- if (index === -1 || index === state.order.length - 1) {
259
- return;
260
- }
261
- while (index < state.order.length - 1) {
262
- void state.order.pop()?.toggle(false, true);
263
- }
328
+ const state = getState();
329
+ if (state == null) return;
330
+ const index$1 = state.order.findIndex((floatable) => floatable.options.anchor === element || floatable.options.content === element);
331
+ if (index$1 === -1 || index$1 === state.order.length - 1) return;
332
+ while (index$1 < state.order.length - 1) state.order.pop()?.toggle(false, true);
264
333
  }
265
334
  function closeAll() {
266
- const state = getState();
267
- const floatables = [...(state?.active ?? [])];
268
- state?.active.clear();
269
- for (const floatable of floatables) {
270
- void floatable.toggle(false, true);
271
- }
335
+ const state = getState();
336
+ const floatables = [...state?.active ?? []];
337
+ state?.active.clear();
338
+ for (const floatable of floatables) floatable.toggle(false, true);
272
339
  }
273
340
  function closeNonInteractive(state) {
274
- for (const floatable of state.active) {
275
- if (!floatable.options.interactive) {
276
- void floatable.toggle(false);
277
- }
278
- }
341
+ for (const floatable of state.active) if (!floatable.options.interactive) floatable.toggle(false);
279
342
  }
280
343
  function deactivate(floatable) {
281
- floatable.active = false;
282
- floatable.options.content.hidden = true;
283
- floatable.options.anchor.insertAdjacentElement(INSERT_AFTEREND, floatable.options.content);
284
- floatable.options.onAfter?.(false);
344
+ floatable.active = false;
345
+ floatable.options.content.hidden = true;
346
+ floatable.options.anchor.insertAdjacentElement(INSERT_AFTEREND, floatable.options.content);
347
+ floatable.options.onAfter?.(false);
285
348
  }
286
349
  function getState() {
287
- return window._oscarpalmer_oui_floatable;
350
+ return window._oscarpalmer_oui_floatable;
288
351
  }
289
352
  function getX(anchor, content, position) {
290
- if (position.endsWith(POSITION_SUFFIX_END)) {
291
- const end = anchor.right - content.width;
292
- return end < 0 ? 0 : end;
293
- }
294
- if (position.endsWith(POSITION_SUFFIX_START)) {
295
- const start = anchor.left;
296
- return start + content.width > window.innerWidth
297
- ? window.innerWidth - content.width
298
- : start;
299
- }
300
- if (position.startsWith(POSITION_END)) {
301
- return anchor.right;
302
- }
303
- if (position.startsWith(POSITION_START)) {
304
- return anchor.left - content.width;
305
- }
306
- if (position.startsWith(POSITION_HORIZONTAL)) {
307
- if (anchor.right + content.width <= window.innerWidth) {
308
- return anchor.right;
309
- }
310
- return anchor.left - content.width;
311
- }
312
- const left = anchor.left + (anchor.width - content.width) / 2;
313
- return left < 0 ? 0 : left;
353
+ if (position.endsWith(POSITION_SUFFIX_END)) {
354
+ const end = anchor.right - content.width;
355
+ return end < 0 ? 0 : end;
356
+ }
357
+ if (position.endsWith(POSITION_SUFFIX_START)) {
358
+ const start = anchor.left;
359
+ return start + content.width > window.innerWidth ? window.innerWidth - content.width : start;
360
+ }
361
+ if (position.startsWith(POSITION_END)) return anchor.right;
362
+ if (position.startsWith(POSITION_START)) return anchor.left - content.width;
363
+ if (position.startsWith(POSITION_HORIZONTAL)) {
364
+ if (anchor.right + content.width <= window.innerWidth) return anchor.right;
365
+ return anchor.left - content.width;
366
+ }
367
+ const left = anchor.left + (anchor.width - content.width) / 2;
368
+ return left < 0 ? 0 : left;
314
369
  }
315
370
  function getY(anchor, content, position, preferAbove) {
316
- if (position.startsWith(POSITION_ABOVE)) {
317
- return anchor.top - content.height;
318
- }
319
- if (position.startsWith(POSITION_BELOW)) {
320
- return anchor.bottom;
321
- }
322
- if (position.endsWith(POSITION_BOTTOM)) {
323
- const bottom = anchor.bottom - content.height;
324
- return bottom < 0 ? 0 : bottom;
325
- }
326
- if (position.endsWith(POSITION_TOP)) {
327
- const top = anchor.top;
328
- return top + content.height > window.innerHeight
329
- ? window.innerHeight - content.height
330
- : top;
331
- }
332
- if (position.startsWith(POSITION_VERTICAL)) {
333
- if (preferAbove && anchor.top - content.height >= 0) {
334
- return anchor.top - content.height;
335
- }
336
- if (anchor.bottom + content.height <= document.body.clientHeight) {
337
- return anchor.bottom;
338
- }
339
- return anchor.top - content.height;
340
- }
341
- return anchor.top + (anchor.height - content.height) / 2;
371
+ if (position.startsWith(POSITION_ABOVE)) return anchor.top - content.height;
372
+ if (position.startsWith(POSITION_BELOW)) return anchor.bottom;
373
+ if (position.endsWith(POSITION_BOTTOM)) {
374
+ const bottom = anchor.bottom - content.height;
375
+ return bottom < 0 ? 0 : bottom;
376
+ }
377
+ if (position.endsWith(POSITION_TOP)) {
378
+ const top = anchor.top;
379
+ return top + content.height > window.innerHeight ? window.innerHeight - content.height : top;
380
+ }
381
+ if (position.startsWith(POSITION_VERTICAL)) {
382
+ if (preferAbove && anchor.top - content.height >= 0) return anchor.top - content.height;
383
+ if (anchor.bottom + content.height <= document.body.clientHeight) return anchor.bottom;
384
+ return anchor.top - content.height;
385
+ }
386
+ return anchor.top + (anchor.height - content.height) / 2;
342
387
  }
343
388
  function initialize(floatable) {
344
- const { anchor, content, interactive } = floatable.options;
345
- if (interactive) {
346
- anchor.setAttribute(ATTRIBUTE_ANCHOR, '');
347
- content.setAttribute(ATTRIBUTE_CONTENT, '');
348
- }
349
- content.style.position = 'fixed';
350
- content.style.inset = '0 auto auto 0';
351
- content.style.zIndex = '10';
352
- const state = getState();
353
- state?.mapped.set(anchor, floatable);
354
- state?.mapped.set(content, floatable);
389
+ const { anchor, content, interactive } = floatable.options;
390
+ if (interactive) {
391
+ anchor.setAttribute(ATTRIBUTE_ANCHOR, "");
392
+ content.setAttribute(ATTRIBUTE_CONTENT, "");
393
+ }
394
+ content.style.position = "fixed";
395
+ content.style.inset = "0 auto auto 0";
396
+ content.style.zIndex = "10";
397
+ const state = getState();
398
+ state?.mapped.set(anchor, floatable);
399
+ state?.mapped.set(content, floatable);
355
400
  }
356
401
  function isDisabled(element) {
357
- return (element.disabled ||
358
- element.readOnly ||
359
- element.getAttribute('aria-disabled') === 'true');
402
+ return element.disabled || element.readOnly || element.getAttribute("aria-disabled") === "true";
360
403
  }
361
404
  function onClick(event) {
362
- const related = findAncestor(event.target, SELECTOR_ALL);
363
- if (!(related instanceof HTMLElement)) {
364
- closeAll();
365
- }
366
- else if (related.hasAttribute(ATTRIBUTE_CONTENT)) {
367
- closeAbove(related);
368
- }
369
- else if (!isDisabled(related)) {
370
- toggle(related);
371
- }
405
+ const related = findAncestor(event.target, SELECTOR_ALL);
406
+ if (!(related instanceof HTMLElement)) closeAll();
407
+ else if (related.hasAttribute(ATTRIBUTE_CONTENT)) closeAbove(related);
408
+ else if (!isDisabled(related)) toggle(related);
372
409
  }
373
410
  function onKeyDown(event) {
374
- if (event.key !== 'Escape') {
375
- return;
376
- }
377
- const state = getState();
378
- if (state == null || state.active.size === 0) {
379
- return;
380
- }
381
- closeNonInteractive(state);
382
- const related = findAncestor(event.target, SELECTOR_CONTENT$1);
383
- if (!(related instanceof HTMLElement)) {
384
- return;
385
- }
386
- closeAbove(related);
387
- const floatable = state.mapped.get(related);
388
- if (floatable != null) {
389
- void floatable.toggle(false);
390
- }
411
+ if (event.key !== "Escape") return;
412
+ const state = getState();
413
+ if (state == null || state.active.size === 0) return;
414
+ closeNonInteractive(state);
415
+ const related = findAncestor(event.target, SELECTOR_CONTENT$1);
416
+ if (!(related instanceof HTMLElement)) return;
417
+ closeAbove(related);
418
+ const floatable = state.mapped.get(related);
419
+ if (floatable != null) floatable.toggle(false);
391
420
  }
392
421
  function stop(floatable) {
393
- if (floatable.frame != null) {
394
- cancelAnimationFrame(floatable.frame);
395
- }
396
- floatable.frame = undefined;
422
+ if (floatable.frame != null) cancelAnimationFrame(floatable.frame);
423
+ floatable.frame = void 0;
397
424
  }
398
425
  function toggle(anchor) {
399
- const floatable = getState()?.mapped.get(anchor);
400
- if (floatable == null) {
401
- closeAll();
402
- return;
403
- }
404
- const active = Boolean(floatable.active);
405
- const content = findAncestor(floatable.options.anchor, SELECTOR_CONTENT$1);
406
- if (content == null) {
407
- closeAll();
408
- }
409
- else {
410
- closeAbove(content);
411
- }
412
- void floatable.toggle(!active);
426
+ const floatable = getState()?.mapped.get(anchor);
427
+ if (floatable == null) {
428
+ closeAll();
429
+ return;
430
+ }
431
+ const active = Boolean(floatable.active);
432
+ const content = findAncestor(floatable.options.anchor, SELECTOR_CONTENT$1);
433
+ if (content == null) closeAll();
434
+ else closeAbove(content);
435
+ floatable.toggle(!active);
413
436
  }
414
437
  function updatePosition(floatable) {
415
- let position = floatable.options.anchor
416
- .getAttribute(floatable.options.positionAttribute)
417
- ?.trim() ?? floatable.options.defaultPosition;
418
- if (!POSITIONS.has(position)) {
419
- position = floatable.options.defaultPosition;
420
- }
421
- let previousAnchor;
422
- let previousContent;
423
- let calculated = false;
424
- let runOnAfter = false;
425
- function run() {
426
- const anchor = floatable.options.anchor.getBoundingClientRect();
427
- const content = floatable.options.content.getBoundingClientRect();
428
- if (calculated) {
429
- if (previousAnchor != null && previousContent != null) {
430
- if (PROPERTIES.every(property => anchor[property] === previousAnchor[property]) &&
431
- PROPERTIES.every(property => content[property] === previousContent[property])) {
432
- floatable.frame = requestAnimationFrame(run);
433
- return;
434
- }
435
- }
436
- }
437
- else {
438
- calculated = true;
439
- }
440
- update(anchor, content);
441
- }
442
- function update(anchor, content) {
443
- previousAnchor = anchor;
444
- previousContent = content;
445
- const left = getX(anchor, content, position);
446
- const top = getY(anchor, content, position, floatable.options.preferAbove);
447
- if (top + content.height > window.innerHeight) {
448
- floatable.options.content.style.height = `${window.innerHeight - top}px`;
449
- }
450
- else {
451
- floatable.options.content.style.height = '';
452
- }
453
- if (left + content.width > window.innerWidth) {
454
- floatable.options.content.style.width = `${window.innerWidth - left}px`;
455
- }
456
- else {
457
- floatable.options.content.style.width = '';
458
- }
459
- // floatable.options.content.style.inset = `${top}px auto auto ${left}px`;
460
- floatable.options.content.style.transform = `translate3d(${left}px, ${top}px, 0)`;
461
- floatable.frame = requestAnimationFrame(run);
462
- if (!runOnAfter) {
463
- runOnAfter = true;
464
- floatable.options.onAfter?.(true);
465
- }
466
- }
467
- floatable.frame = requestAnimationFrame(run);
468
- }
469
- //
470
- const ATTRIBUTE_ANCHOR = 'oui-floatable-anchor';
471
- const ATTRIBUTE_CONTENT = 'oui-floatable-content';
472
- const INSERT_AFTEREND = 'afterend';
473
- const POSITION_ABOVE = 'above';
474
- const POSITION_BELOW = 'below';
475
- const POSITION_BOTTOM = 'bottom';
476
- const POSITION_END = 'end';
477
- const POSITION_HORIZONTAL = 'horizontal';
478
- const POSITION_START = 'start';
479
- const POSITION_SUFFIX_END = '-end';
480
- const POSITION_SUFFIX_START = '-start';
481
- const POSITION_TOP = 'top';
482
- const POSITION_VERTICAL = 'vertical';
438
+ let position = floatable.options.anchor.getAttribute(floatable.options.positionAttribute)?.trim() ?? floatable.options.defaultPosition;
439
+ if (!POSITIONS.has(position)) position = floatable.options.defaultPosition;
440
+ let previousAnchor;
441
+ let previousContent;
442
+ let calculated = false;
443
+ let runOnAfter = false;
444
+ function run() {
445
+ const anchor = floatable.options.anchor.getBoundingClientRect();
446
+ const content = floatable.options.content.getBoundingClientRect();
447
+ if (calculated) {
448
+ if (previousAnchor != null && previousContent != null) {
449
+ if (PROPERTIES.every((property) => anchor[property] === previousAnchor[property]) && PROPERTIES.every((property) => content[property] === previousContent[property])) {
450
+ floatable.frame = requestAnimationFrame(run);
451
+ return;
452
+ }
453
+ }
454
+ } else calculated = true;
455
+ update(anchor, content);
456
+ }
457
+ function update(anchor, content) {
458
+ previousAnchor = anchor;
459
+ previousContent = content;
460
+ const left = getX(anchor, content, position);
461
+ const top = getY(anchor, content, position, floatable.options.preferAbove);
462
+ if (top + content.height > window.innerHeight) floatable.options.content.style.height = `${window.innerHeight - top}px`;
463
+ else floatable.options.content.style.height = "";
464
+ if (left + content.width > window.innerWidth) floatable.options.content.style.width = `${window.innerWidth - left}px`;
465
+ else floatable.options.content.style.width = "";
466
+ floatable.options.content.style.transform = `translate3d(${left}px, ${top}px, 0)`;
467
+ floatable.frame = requestAnimationFrame(run);
468
+ if (!runOnAfter) {
469
+ runOnAfter = true;
470
+ floatable.options.onAfter?.(true);
471
+ }
472
+ }
473
+ floatable.frame = requestAnimationFrame(run);
474
+ }
475
+ const ATTRIBUTE_ANCHOR = "oui-floatable-anchor";
476
+ const ATTRIBUTE_CONTENT = "oui-floatable-content";
477
+ const INSERT_AFTEREND = "afterend";
478
+ const POSITION_ABOVE = "above";
479
+ const POSITION_BELOW = "below";
480
+ const POSITION_BOTTOM = "bottom";
481
+ const POSITION_END = "end";
482
+ const POSITION_HORIZONTAL = "horizontal";
483
+ const POSITION_START = "start";
484
+ const POSITION_SUFFIX_END = "-end";
485
+ const POSITION_SUFFIX_START = "-start";
486
+ const POSITION_TOP = "top";
487
+ const POSITION_VERTICAL = "vertical";
483
488
  const POSITIONS = new Set([
484
- 'above',
485
- 'above-end',
486
- 'above-start',
487
- 'below',
488
- 'below-end',
489
- 'below-start',
490
- 'end',
491
- 'end-bottom',
492
- 'end-top',
493
- 'horizontal',
494
- 'horizontal-bottom',
495
- 'horizontal-top',
496
- 'start',
497
- 'start-bottom',
498
- 'start-top',
499
- 'vertical',
500
- 'vertical-end',
501
- 'vertical-start',
489
+ "above",
490
+ "above-end",
491
+ "above-start",
492
+ "below",
493
+ "below-end",
494
+ "below-start",
495
+ "end",
496
+ "end-bottom",
497
+ "end-top",
498
+ "horizontal",
499
+ "horizontal-bottom",
500
+ "horizontal-top",
501
+ "start",
502
+ "start-bottom",
503
+ "start-top",
504
+ "vertical",
505
+ "vertical-end",
506
+ "vertical-start"
502
507
  ]);
503
- const PROPERTIES = ['bottom', 'left', 'right', 'top'];
508
+ const PROPERTIES = [
509
+ "bottom",
510
+ "left",
511
+ "right",
512
+ "top"
513
+ ];
504
514
  const SELECTOR_ALL = `[${ATTRIBUTE_ANCHOR}], [${ATTRIBUTE_CONTENT}]`;
505
515
  const SELECTOR_CONTENT$1 = `[${ATTRIBUTE_CONTENT}]`;
506
- //
507
516
  if (window._oscarpalmer_oui_floatable == null) {
508
- Object.defineProperty(window, '_oscarpalmer_oui_floatable', {
509
- enumerable: false,
510
- value: {
511
- active: new Set(),
512
- mapped: new Map(),
513
- order: [],
514
- },
515
- writable: false,
516
- });
517
- on(document, 'keydown', event => {
518
- onKeyDown(event);
519
- });
520
- on(document, 'click', event => {
521
- onClick(event);
522
- });
523
- }
524
-
525
- class FocusTrap {
526
- disabled = false;
527
- connected = true;
528
- element;
529
- embedded;
530
- get contain() {
531
- return this.element.hasAttribute(FOCUS_TRAP_CONTAIN);
532
- }
533
- get noescape() {
534
- return this.element.hasAttribute(FOCUS_TRAP_NOESCAPE);
535
- }
536
- constructor(element, options) {
537
- this.element = element;
538
- this.embedded = options != null;
539
- element.setAttribute('tabindex', '-1');
540
- if (options != null) {
541
- element.setAttribute(FOCUS_TRAP_SELECTOR, '');
542
- }
543
- if (options?.noescape) {
544
- element.setAttribute(FOCUS_TRAP_NOESCAPE, '');
545
- }
546
- }
547
- connect() {
548
- setConnected(this, true);
549
- }
550
- destroy() {
551
- this.element = undefined;
552
- }
553
- disable() {
554
- if (!(this.disabled || this.noescape)) {
555
- setDisabled(this, true);
556
- }
557
- }
558
- disconnect() {
559
- setConnected(this, false);
560
- }
561
- enable() {
562
- if (this.disabled) {
563
- setDisabled(this, false);
564
- }
565
- }
566
- focus(last) {
567
- tabToTrap(this, getFocusable(this.element), this.element, last ? -1 : 0);
568
- }
569
- }
570
- //
517
+ Object.defineProperty(window, "_oscarpalmer_oui_floatable", {
518
+ enumerable: false,
519
+ value: {
520
+ active: /* @__PURE__ */ new Set(),
521
+ mapped: /* @__PURE__ */ new Map(),
522
+ order: []
523
+ },
524
+ writable: false
525
+ });
526
+ on(document, "keydown", (event) => {
527
+ onKeyDown(event);
528
+ });
529
+ on(document, "click", (event) => {
530
+ onClick(event);
531
+ });
532
+ }
533
+ var FocusTrap = class {
534
+ disabled = false;
535
+ connected = true;
536
+ element;
537
+ embedded;
538
+ get contain() {
539
+ return this.element.hasAttribute(FOCUS_TRAP_CONTAIN);
540
+ }
541
+ get noescape() {
542
+ return this.element.hasAttribute(FOCUS_TRAP_NOESCAPE);
543
+ }
544
+ constructor(element, options) {
545
+ this.element = element;
546
+ this.embedded = options != null;
547
+ element.setAttribute("tabindex", "-1");
548
+ if (options != null) element.setAttribute(FOCUS_TRAP_SELECTOR, "");
549
+ if (options?.noescape) element.setAttribute(FOCUS_TRAP_NOESCAPE, "");
550
+ }
551
+ connect() {
552
+ setConnected(this, true);
553
+ }
554
+ destroy() {
555
+ this.element = void 0;
556
+ }
557
+ disable() {
558
+ if (!(this.disabled || this.noescape)) setDisabled(this, true);
559
+ }
560
+ disconnect() {
561
+ setConnected(this, false);
562
+ }
563
+ enable() {
564
+ if (this.disabled) setDisabled(this, false);
565
+ }
566
+ focus(last) {
567
+ tabToTrap(this, getFocusable(this.element), this.element, last ? -1 : 0);
568
+ }
569
+ };
571
570
  function createFocusTrap(element, options) {
572
- let focusTrap = FOCUSTRAPS_ALL.get(element);
573
- if (focusTrap == null) {
574
- focusTrap = new FocusTrap(element, options);
575
- FOCUSTRAPS_ALL.set(element, focusTrap);
576
- }
577
- return focusTrap;
571
+ let focusTrap = FOCUSTRAPS_ALL.get(element);
572
+ if (focusTrap == null) {
573
+ focusTrap = new FocusTrap(element, options);
574
+ FOCUSTRAPS_ALL.set(element, focusTrap);
575
+ }
576
+ return focusTrap;
578
577
  }
579
578
  function onEscape(event) {
580
- let element = findAncestor(event.target, ATTRIBUTE_SELECTOR);
581
- let focusTrap = FOCUSTRAPS_ALL.get(element);
582
- if (element == null || focusTrap == null) {
583
- return;
584
- }
585
- while (focusTrap.disabled) {
586
- element = findAncestor(focusTrap.element.parentElement, ATTRIBUTE_SELECTOR);
587
- focusTrap = FOCUSTRAPS_ALL.get(element);
588
- if (element == null || focusTrap == null) {
589
- return;
590
- }
591
- if (!focusTrap.disabled) {
592
- break;
593
- }
594
- }
595
- focusTrap?.disable();
579
+ let element = findAncestor(event.target, ATTRIBUTE_SELECTOR);
580
+ let focusTrap = FOCUSTRAPS_ALL.get(element);
581
+ if (element == null || focusTrap == null) return;
582
+ while (focusTrap.disabled) {
583
+ element = findAncestor(focusTrap.element.parentElement, ATTRIBUTE_SELECTOR);
584
+ focusTrap = FOCUSTRAPS_ALL.get(element);
585
+ if (element == null || focusTrap == null) return;
586
+ if (!focusTrap.disabled) break;
587
+ }
588
+ focusTrap?.disable();
596
589
  }
597
590
  function onFocusIn(event) {
598
- const focusTrap = FOCUSTRAPS_ALL.get(findAncestor(event.target, ATTRIBUTE_SELECTOR));
599
- lastTarget = focusTrap == null ? undefined : event.target;
591
+ lastTarget = FOCUSTRAPS_ALL.get(findAncestor(event.target, ATTRIBUTE_SELECTOR)) == null ? void 0 : event.target;
600
592
  }
601
593
  function onKeydown(event) {
602
- switch (event.key) {
603
- case 'Escape':
604
- onEscape(event);
605
- break;
606
- case 'Tab':
607
- onTab(event);
608
- break;
609
- default:
610
- return;
611
- }
594
+ switch (event.key) {
595
+ case "Escape":
596
+ onEscape(event);
597
+ break;
598
+ case "Tab":
599
+ onTab(event);
600
+ break;
601
+ default: return;
602
+ }
612
603
  }
613
604
  function onPointerdown(event) {
614
- const lastFocusTrap = findAncestor(lastTarget, ATTRIBUTE_SELECTOR);
615
- const nextFocusTrap = findAncestor(event.target, ATTRIBUTE_SELECTOR);
616
- if (lastFocusTrap != null && nextFocusTrap !== lastFocusTrap) {
617
- if (FOCUSTRAPS_ALL.get(lastFocusTrap)?.contain ?? false) {
618
- event.preventDefault();
619
- lastTarget?.focus();
620
- }
621
- }
622
- if (FOCUSTRAPS_DISABLED.size === 0) {
623
- return;
624
- }
625
- for (const focusTrap of FOCUSTRAPS_DISABLED) {
626
- if (focusTrap.element !== nextFocusTrap) {
627
- focusTrap.enable();
628
- }
629
- }
605
+ const lastFocusTrap = findAncestor(lastTarget, ATTRIBUTE_SELECTOR);
606
+ const nextFocusTrap = findAncestor(event.target, ATTRIBUTE_SELECTOR);
607
+ if (lastFocusTrap != null && nextFocusTrap !== lastFocusTrap) {
608
+ if (FOCUSTRAPS_ALL.get(lastFocusTrap)?.contain ?? false) {
609
+ event.preventDefault();
610
+ lastTarget?.focus();
611
+ }
612
+ }
613
+ if (FOCUSTRAPS_DISABLED.size === 0) return;
614
+ for (const focusTrap of FOCUSTRAPS_DISABLED) if (focusTrap.element !== nextFocusTrap) focusTrap.enable();
630
615
  }
631
616
  function onTab(event) {
632
- const element = findAncestor(event.target, ATTRIBUTE_SELECTOR);
633
- const focusTrap = FOCUSTRAPS_ALL.get(element);
634
- if (focusTrap == null) {
635
- return;
636
- }
637
- if (!focusTrap.disabled) {
638
- event.preventDefault();
639
- }
640
- const elements = getFocusable(element);
641
- const index = elements.indexOf(event.target);
642
- if (index === -1 || elements.length === 0) {
643
- tabToTrap(focusTrap, elements, element);
644
- }
645
- else {
646
- tabToElement(focusTrap, elements, index, event.shiftKey ? -1 : 1);
647
- }
617
+ const element = findAncestor(event.target, ATTRIBUTE_SELECTOR);
618
+ const focusTrap = FOCUSTRAPS_ALL.get(element);
619
+ if (focusTrap == null) return;
620
+ if (!focusTrap.disabled) event.preventDefault();
621
+ const elements = getFocusable(element);
622
+ const index$1 = elements.indexOf(event.target);
623
+ if (index$1 === -1 || elements.length === 0) tabToTrap(focusTrap, elements, element);
624
+ else tabToElement(focusTrap, elements, index$1, event.shiftKey ? -1 : 1);
648
625
  }
649
626
  function setConnected(focusTrap, value) {
650
- if (!focusTrap.embedded || focusTrap.connected === value) {
651
- return;
652
- }
653
- focusTrap.connected = value;
627
+ if (!focusTrap.embedded || focusTrap.connected === value) return;
628
+ focusTrap.connected = value;
654
629
  }
655
630
  function setDisabled(focusTrap, value) {
656
- focusTrap.disabled = value;
657
- if (value) {
658
- FOCUSTRAPS_DISABLED.add(focusTrap);
659
- }
660
- else {
661
- FOCUSTRAPS_DISABLED.delete(focusTrap);
662
- }
663
- }
664
- function tabToElement(focusTrap, elements, index, modifier) {
665
- const { length } = elements;
666
- const next = clamp(index + modifier, 0, length - 1);
667
- if (focusTrap.disabled) {
668
- if ((index === length - 1 && next === 0) ||
669
- (index === 0 && next === length - 1)) {
670
- lastTarget = undefined;
671
- focusTrap.enable();
672
- }
673
- return;
674
- }
675
- const element = elements[next];
676
- const elementFocusTrap = FOCUSTRAPS_ALL.get(element);
677
- if (elementFocusTrap != null) {
678
- elementFocusTrap.focus(modifier === -1);
679
- }
680
- else {
681
- elements[next].focus();
682
- lastTarget = elements[next];
683
- }
684
- }
685
- function tabToTrap(focusTrap, elements, element, index) {
686
- if (focusTrap.disabled) {
687
- lastTarget = undefined;
688
- focusTrap.enable();
689
- }
690
- else {
691
- const next = elements.length === 0 ? element : elements.at(index ?? 0);
692
- next.focus();
693
- lastTarget = next;
694
- }
695
- }
696
- //
697
- const FOCUS_TRAP_SELECTOR = 'oui-focus-trap';
631
+ focusTrap.disabled = value;
632
+ if (value) FOCUSTRAPS_DISABLED.add(focusTrap);
633
+ else FOCUSTRAPS_DISABLED.delete(focusTrap);
634
+ }
635
+ function tabToElement(focusTrap, elements, index$1, modifier) {
636
+ const { length } = elements;
637
+ const next = clamp(index$1 + modifier, 0, length - 1, true);
638
+ if (focusTrap.disabled) {
639
+ if (index$1 === length - 1 && next === 0 || index$1 === 0 && next === length - 1) {
640
+ lastTarget = void 0;
641
+ focusTrap.enable();
642
+ }
643
+ return;
644
+ }
645
+ const element = elements[next];
646
+ const elementFocusTrap = FOCUSTRAPS_ALL.get(element);
647
+ if (elementFocusTrap != null) elementFocusTrap.focus(modifier === -1);
648
+ else {
649
+ elements[next].focus();
650
+ lastTarget = elements[next];
651
+ }
652
+ }
653
+ function tabToTrap(focusTrap, elements, element, index$1) {
654
+ if (focusTrap.disabled) {
655
+ lastTarget = void 0;
656
+ focusTrap.enable();
657
+ } else {
658
+ const next = elements.length === 0 ? element : elements.at(index$1 ?? 0);
659
+ next.focus();
660
+ lastTarget = next;
661
+ }
662
+ }
663
+ const FOCUS_TRAP_SELECTOR = "oui-focus-trap";
698
664
  const ATTRIBUTE_SELECTOR = `[${FOCUS_TRAP_SELECTOR}]`;
699
665
  const EVENT_OPTIONS = {
700
- capture: true,
701
- passive: false,
666
+ capture: true,
667
+ passive: false
702
668
  };
703
669
  const FOCUS_TRAP_CONTAIN = `${FOCUS_TRAP_SELECTOR}-contain`;
704
670
  const FOCUS_TRAP_NOESCAPE = `${FOCUS_TRAP_SELECTOR}-noescape`;
705
- const FOCUSTRAPS_ALL = new WeakMap();
706
- const FOCUSTRAPS_DISABLED = new Set();
671
+ const FOCUSTRAPS_ALL = /* @__PURE__ */ new WeakMap();
672
+ const FOCUSTRAPS_DISABLED = /* @__PURE__ */ new Set();
707
673
  let lastTarget;
708
- //
709
- on(document, 'focusin', onFocusIn, EVENT_OPTIONS);
710
- on(document, 'keydown', onKeydown, EVENT_OPTIONS);
711
- on(document, 'mousedown', onPointerdown, EVENT_OPTIONS);
712
- on(document, 'touchstart', onPointerdown, EVENT_OPTIONS);
713
-
674
+ on(document, "focusin", onFocusIn, EVENT_OPTIONS);
675
+ on(document, "keydown", onKeydown, EVENT_OPTIONS);
676
+ on(document, "mousedown", onPointerdown, EVENT_OPTIONS);
677
+ on(document, "touchstart", onPointerdown, EVENT_OPTIONS);
714
678
  let index = 0;
715
- class OuiPopoverElement extends HTMLElement {
716
- #floatable;
717
- #focusTrap;
718
- constructor() {
719
- super();
720
- const content = this.querySelector(SELECTOR_CONTENT);
721
- const toggle = this.querySelector(SELECTOR_TOGGLE);
722
- if (!(content instanceof HTMLElement)) {
723
- throw new Error('A oui-popover must have a direct child element with the [oui-popover-content]-attribute');
724
- }
725
- if (!(toggle instanceof HTMLButtonElement)) {
726
- throw new Error('A oui-popover must have a direct child element with the [oui-popover-toggle]-attribute and be a button');
727
- }
728
- content.hidden = true;
729
- content.setAttribute('role', 'dialog');
730
- content.setAttribute('aria-modal', 'true');
731
- if (isNullableOrWhitespace(content.id)) {
732
- content.setAttribute('id', `${ATTRIBUTE_ID_PREFIX}_${++index}`);
733
- }
734
- toggle.setAttribute('aria-controls', content.id);
735
- toggle.setAttribute('aria-haspopup', 'dialog');
736
- this.#floatable = new Floatable({
737
- content,
738
- anchor: toggle,
739
- defaultPosition: 'below-start',
740
- interactive: true,
741
- positionAttribute: 'position',
742
- preferAbove: false,
743
- onAfter: (active) => {
744
- if (active) {
745
- focus(content);
746
- }
747
- else if (!this.#floatable.ignoreFocus) {
748
- toggle.focus();
749
- }
750
- },
751
- });
752
- this.#focusTrap = createFocusTrap(content, {
753
- noescape: true,
754
- });
755
- POPOVERS.set(toggle, this.#floatable);
756
- POPOVERS.set(content, this.#floatable);
757
- }
758
- close() {
759
- this.hidePopover();
760
- }
761
- connectedCallback() {
762
- this.#floatable.enable();
763
- this.#focusTrap.connect();
764
- }
765
- disconnectedCallback() {
766
- this.#floatable.disable();
767
- this.#focusTrap.disconnect();
768
- }
769
- hidePopover() {
770
- if (this.#floatable.active && this.isConnected) {
771
- this.#floatable.toggle(false);
772
- }
773
- }
774
- open() {
775
- this.showPopover();
776
- }
777
- showPopover() {
778
- if (!this.#floatable.active && this.isConnected) {
779
- this.#floatable.toggle(true);
780
- }
781
- }
782
- toggle() {
783
- this.togglePopover();
784
- }
785
- togglePopover(options) {
786
- if (typeof options === 'boolean') {
787
- if (options === true) {
788
- this.showPopover();
789
- }
790
- else {
791
- this.hidePopover();
792
- }
793
- return options;
794
- }
795
- if (this.#floatable.active) {
796
- this.hidePopover();
797
- return false;
798
- }
799
- this.showPopover();
800
- return true;
801
- }
802
- }
803
- //
679
+ var OuiPopoverElement = class extends HTMLElement {
680
+ #floatable;
681
+ #focusTrap;
682
+ constructor() {
683
+ super();
684
+ const content = this.querySelector(SELECTOR_CONTENT);
685
+ const toggle$1 = this.querySelector(SELECTOR_TOGGLE);
686
+ if (!(content instanceof HTMLElement)) throw new Error("A oui-popover must have a direct child element with the [oui-popover-content]-attribute");
687
+ if (!(toggle$1 instanceof HTMLButtonElement)) throw new Error("A oui-popover must have a direct child element with the [oui-popover-toggle]-attribute and be a button");
688
+ content.hidden = true;
689
+ content.setAttribute("role", "dialog");
690
+ content.setAttribute("aria-modal", "true");
691
+ if (isNullableOrWhitespace(content.id)) content.setAttribute("id", `${ATTRIBUTE_ID_PREFIX}_${++index}`);
692
+ toggle$1.setAttribute("aria-controls", content.id);
693
+ toggle$1.setAttribute("aria-haspopup", "dialog");
694
+ this.#floatable = new Floatable({
695
+ content,
696
+ anchor: toggle$1,
697
+ defaultPosition: "below-start",
698
+ interactive: true,
699
+ positionAttribute: "position",
700
+ preferAbove: false,
701
+ onAfter: (active) => {
702
+ if (active) focus(content);
703
+ else if (!this.#floatable.ignoreFocus) toggle$1.focus();
704
+ }
705
+ });
706
+ this.#focusTrap = createFocusTrap(content, { noescape: true });
707
+ POPOVERS.set(toggle$1, this.#floatable);
708
+ POPOVERS.set(content, this.#floatable);
709
+ }
710
+ close() {
711
+ this.hidePopover();
712
+ }
713
+ connectedCallback() {
714
+ this.#floatable.enable();
715
+ this.#focusTrap.connect();
716
+ }
717
+ disconnectedCallback() {
718
+ this.#floatable.disable();
719
+ this.#focusTrap.disconnect();
720
+ }
721
+ hidePopover() {
722
+ if (this.#floatable.active && this.isConnected) this.#floatable.toggle(false);
723
+ }
724
+ open() {
725
+ this.showPopover();
726
+ }
727
+ showPopover() {
728
+ if (!this.#floatable.active && this.isConnected) this.#floatable.toggle(true);
729
+ }
730
+ toggle() {
731
+ this.togglePopover();
732
+ }
733
+ togglePopover(options) {
734
+ if (typeof options === "boolean") {
735
+ if (options === true) this.showPopover();
736
+ else this.hidePopover();
737
+ return options;
738
+ }
739
+ if (this.#floatable.active) {
740
+ this.hidePopover();
741
+ return false;
742
+ }
743
+ this.showPopover();
744
+ return true;
745
+ }
746
+ };
804
747
  function focus(content) {
805
- let target = getFocusable(content)[0];
806
- if (!(target instanceof HTMLElement)) {
807
- target = content;
808
- }
809
- requestAnimationFrame(() => {
810
- target.focus();
811
- });
812
- }
813
- //
814
- const ATTRIBUTE_ID_PREFIX = 'oui_popover_content_';
815
- const POPOVERS = new Map();
816
- const SELECTOR = 'oui-popover';
748
+ let target = getFocusable(content)[0];
749
+ if (!(target instanceof HTMLElement)) target = content;
750
+ requestAnimationFrame(() => {
751
+ target.focus();
752
+ });
753
+ }
754
+ const ATTRIBUTE_ID_PREFIX = "oui_popover_content_";
755
+ const POPOVERS = /* @__PURE__ */ new Map();
756
+ const SELECTOR = "oui-popover";
817
757
  const SELECTOR_CONTENT = `:scope > [${SELECTOR}-content]`;
818
758
  const SELECTOR_TOGGLE = `:scope > [${SELECTOR}-toggle]`;
819
- //
820
759
  customElements.define(SELECTOR, OuiPopoverElement);
821
-
822
760
  export { OuiPopoverElement };