@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,24 +1,16 @@
1
1
  function getString(value) {
2
2
  if (typeof value === "string") return value;
3
3
  if (value == null) return "";
4
+ if (typeof value === "function") return getString(value());
4
5
  if (typeof value !== "object") return String(value);
5
6
  const asString = String(value.valueOf?.() ?? value);
6
7
  return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
7
8
  }
8
-
9
9
  function isNullableOrWhitespace(value) {
10
10
  return value == null || EXPRESSION_WHITESPACE$1.test(getString(value));
11
11
  }
12
12
  var EXPRESSION_WHITESPACE$1 = /^\s*$/;
13
-
14
- function isEventTarget(value) {
15
- return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
16
- }
17
-
18
- function getBoolean(value, defaultValue) {
19
- return typeof value === "boolean" ? value : defaultValue ?? false;
20
- }
21
-
13
+ function noop() {}
22
14
  function calculate() {
23
15
  return new Promise((resolve) => {
24
16
  const values = [];
@@ -26,37 +18,122 @@ function calculate() {
26
18
  function step(now) {
27
19
  if (last != null) values.push(now - last);
28
20
  last = now;
29
- if (values.length >= CALCULATION_TOTAL) {
30
- const median = values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - CALCULATION_TRIM);
31
- resolve(median);
32
- } else requestAnimationFrame(step);
21
+ if (values.length >= TOTAL) resolve(values.sort().slice(TRIM_PART, -TRIM_PART).reduce((first, second) => first + second, 0) / (values.length - TRIM_TOTAL));
22
+ else requestAnimationFrame(step);
33
23
  }
34
24
  requestAnimationFrame(step);
35
25
  });
36
26
  }
37
- function noop() {}
38
- var CALCULATION_TOTAL = 10;
39
- var CALCULATION_TRIM = 4;
40
- calculate().then((value) => {
41
- });
42
-
27
+ var TOTAL = 10;
28
+ var TRIM_PART = 2;
29
+ var TRIM_TOTAL = 4;
30
+ await calculate();
31
+ function getBoolean(value, defaultValue) {
32
+ return typeof value === "boolean" ? value : defaultValue ?? false;
33
+ }
34
+ function isEventTarget(value) {
35
+ return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
36
+ }
37
+ function addDelegatedHandler(doc, type, name, passive) {
38
+ if (DELEGATED.has(name)) return;
39
+ DELEGATED.add(name);
40
+ doc.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
41
+ }
42
+ function addDelegatedListener(target, type, name, listener, passive) {
43
+ target[name] ??= /* @__PURE__ */ new Set();
44
+ target[name].add(listener);
45
+ addDelegatedHandler(document, type, name, passive);
46
+ return () => {
47
+ removeDelegatedListener(target, name, listener);
48
+ };
49
+ }
50
+ function delegatedEventHandler(event) {
51
+ const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
52
+ const items = event.composedPath();
53
+ const { length } = items;
54
+ let target = items[0];
55
+ Object.defineProperties(event, {
56
+ currentTarget: {
57
+ configurable: true,
58
+ get() {
59
+ return target;
60
+ }
61
+ },
62
+ target: {
63
+ configurable: true,
64
+ value: target
65
+ }
66
+ });
67
+ for (let index$1 = 0; index$1 < length; index$1 += 1) {
68
+ const item = items[index$1];
69
+ const listeners = item[key];
70
+ if (item.disabled || listeners == null) continue;
71
+ target = item;
72
+ for (const listener of listeners) {
73
+ listener.call(item, event);
74
+ if (event.cancelBubble) return;
75
+ }
76
+ }
77
+ }
78
+ function getDelegatedName(target, type, options) {
79
+ 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}`;
80
+ }
81
+ function removeDelegatedListener(target, name, listener) {
82
+ const handlers = target[name];
83
+ if (handlers == null || !handlers.has(listener)) return false;
84
+ handlers.delete(listener);
85
+ if (handlers.size === 0) target[name] = void 0;
86
+ return true;
87
+ }
88
+ var DELEGATED = /* @__PURE__ */ new Set();
89
+ var EVENT_PREFIX = "@";
90
+ var EVENT_SUFFIX_ACTIVE = ":active";
91
+ var EVENT_SUFFIX_PASSIVE = ":passive";
92
+ var EVENT_TYPES = new Set([
93
+ "beforeinput",
94
+ "click",
95
+ "dblclick",
96
+ "contextmenu",
97
+ "focusin",
98
+ "focusout",
99
+ "input",
100
+ "keydown",
101
+ "keyup",
102
+ "mousedown",
103
+ "mousemove",
104
+ "mouseout",
105
+ "mouseover",
106
+ "mouseup",
107
+ "pointerdown",
108
+ "pointermove",
109
+ "pointerout",
110
+ "pointerover",
111
+ "pointerup",
112
+ "touchend",
113
+ "touchmove",
114
+ "touchstart"
115
+ ]);
116
+ var HANDLER_ACTIVE = delegatedEventHandler.bind(false);
117
+ var HANDLER_PASSIVE = delegatedEventHandler.bind(true);
43
118
  function createEventOptions(options) {
44
119
  return {
45
120
  capture: getBoolean(options?.capture),
46
121
  once: getBoolean(options?.once),
47
122
  passive: getBoolean(options?.passive, true),
48
- signal: options?.signal
123
+ signal: options?.signal instanceof AbortSignal ? options.signal : void 0
49
124
  };
50
125
  }
51
126
  function on(target, type, listener, options) {
52
127
  if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return noop;
53
128
  const extended = createEventOptions(options);
129
+ const delegated = getDelegatedName(target, type, extended);
130
+ if (delegated != null) return addDelegatedListener(target, type, delegated, listener, extended.passive);
54
131
  target.addEventListener(type, listener, extended);
132
+ if (extended.once) return noop;
55
133
  return () => {
56
134
  target.removeEventListener(type, listener, extended);
57
135
  };
58
136
  }
59
-
60
137
  function findAncestor(origin, selector) {
61
138
  if (!(origin instanceof Element) || selector == null) return null;
62
139
  if (typeof selector === "string") {
@@ -72,608 +149,465 @@ function findAncestor(origin, selector) {
72
149
  }
73
150
  return parent;
74
151
  }
75
-
76
152
  function attributable(attribute, add, remove) {
77
- const observer = new MutationObserver(entries => {
78
- const { length } = entries;
79
- for (let index = 0; index < length; index += 1) {
80
- const entry = entries[index];
81
- if (entry.type === 'attributes' && entry.target instanceof HTMLElement) {
82
- if (entry.target.hasAttribute(attribute)) {
83
- handleAdded(attribute, [entry.target], add);
84
- }
85
- else {
86
- handleRemoved([entry.target], remove);
87
- }
88
- }
89
- else if (entry.type === 'childList') {
90
- handleAdded(attribute, entry.addedNodes, add);
91
- handleRemoved(entry.removedNodes, remove);
92
- }
93
- }
94
- });
95
- observer.observe(document, {
96
- attributeFilter: [attribute],
97
- attributes: true,
98
- childList: true,
99
- subtree: true,
100
- });
101
- requestAnimationFrame(() => {
102
- handleAdded(attribute, document.querySelectorAll(`[${attribute}]`), add);
103
- });
153
+ new MutationObserver((entries) => {
154
+ const { length } = entries;
155
+ for (let index$1 = 0; index$1 < length; index$1 += 1) {
156
+ const entry = entries[index$1];
157
+ if (entry.type === "attributes" && entry.target instanceof HTMLElement) if (entry.target.hasAttribute(attribute)) handleAdded(attribute, [entry.target], add);
158
+ else handleRemoved([entry.target], remove);
159
+ else if (entry.type === "childList") {
160
+ handleAdded(attribute, entry.addedNodes, add);
161
+ handleRemoved(entry.removedNodes, remove);
162
+ }
163
+ }
164
+ }).observe(document, {
165
+ attributeFilter: [attribute],
166
+ attributes: true,
167
+ childList: true,
168
+ subtree: true
169
+ });
170
+ requestAnimationFrame(() => {
171
+ handleAdded(attribute, document.querySelectorAll(`[${attribute}]`), add);
172
+ });
104
173
  }
105
174
  function handleAdded(attribute, nodes, add) {
106
- const elements = [...nodes].filter(node => node instanceof HTMLElement);
107
- const { length } = elements;
108
- for (let index = 0; index < length; index += 1) {
109
- const element = elements[index];
110
- if (element.hasAttribute(attribute)) {
111
- add(element);
112
- }
113
- }
175
+ const elements = [...nodes].filter((node) => node instanceof HTMLElement);
176
+ const { length } = elements;
177
+ for (let index$1 = 0; index$1 < length; index$1 += 1) {
178
+ const element = elements[index$1];
179
+ if (element.hasAttribute(attribute)) add(element);
180
+ }
114
181
  }
115
182
  function handleRemoved(nodes, remove) {
116
- const elements = [...nodes].filter(node => node instanceof HTMLElement);
117
- const { length } = elements;
118
- for (let index = 0; index < length; index += 1) {
119
- remove(elements[index]);
120
- }
121
- }
122
-
123
- class Floatable {
124
- options;
125
- active = false;
126
- disabled = false;
127
- frame;
128
- ignoreFocus = false;
129
- constructor(options) {
130
- this.options = options;
131
- initialize(this);
132
- }
133
- destroy() {
134
- stop(this);
135
- const state = getState();
136
- state?.active.delete(this);
137
- state?.mapped.delete(this.options.anchor);
138
- state?.mapped.delete(this.options.content);
139
- this.options.anchor = undefined;
140
- this.options.content = undefined;
141
- }
142
- disable() {
143
- if (this.disabled) {
144
- return;
145
- }
146
- this.disabled = true;
147
- stop(this);
148
- getState()?.active.delete(this);
149
- }
150
- enable() {
151
- if (!this.disabled) {
152
- return;
153
- }
154
- this.disabled = false;
155
- initialize(this);
156
- }
157
- toggle(active, ignoreFocus) {
158
- if (this.disabled || this.active === active) {
159
- return;
160
- }
161
- const state = getState();
162
- if (state == null) {
163
- return;
164
- }
165
- this.ignoreFocus = !active && (ignoreFocus ?? false);
166
- stop(this);
167
- if (active) {
168
- state.active.add(this);
169
- }
170
- else {
171
- state.active.delete(this);
172
- }
173
- if (this.options.interactive) {
174
- if (active) {
175
- state.order.push(this);
176
- }
177
- else {
178
- const index = state.order.indexOf(this);
179
- if (index > -1) {
180
- state.order.splice(index, 1);
181
- }
182
- }
183
- }
184
- if (active) {
185
- activate(this);
186
- }
187
- else {
188
- deactivate(this);
189
- }
190
- }
191
- }
192
- //
183
+ const elements = [...nodes].filter((node) => node instanceof HTMLElement);
184
+ const { length } = elements;
185
+ for (let index$1 = 0; index$1 < length; index$1 += 1) remove(elements[index$1]);
186
+ }
187
+ var Floatable = class {
188
+ active = false;
189
+ disabled = false;
190
+ frame;
191
+ ignoreFocus = false;
192
+ constructor(options) {
193
+ this.options = options;
194
+ initialize(this);
195
+ }
196
+ destroy() {
197
+ stop(this);
198
+ const state = getState();
199
+ state?.active.delete(this);
200
+ state?.mapped.delete(this.options.anchor);
201
+ state?.mapped.delete(this.options.content);
202
+ this.options.anchor = void 0;
203
+ this.options.content = void 0;
204
+ }
205
+ disable() {
206
+ if (this.disabled) return;
207
+ this.disabled = true;
208
+ stop(this);
209
+ getState()?.active.delete(this);
210
+ }
211
+ enable() {
212
+ if (!this.disabled) return;
213
+ this.disabled = false;
214
+ initialize(this);
215
+ }
216
+ toggle(active, ignoreFocus) {
217
+ if (this.disabled || this.active === active) return;
218
+ const state = getState();
219
+ if (state == null) return;
220
+ this.ignoreFocus = !active && (ignoreFocus ?? false);
221
+ stop(this);
222
+ if (active) state.active.add(this);
223
+ else state.active.delete(this);
224
+ if (this.options.interactive) if (active) state.order.push(this);
225
+ else {
226
+ const index$1 = state.order.indexOf(this);
227
+ if (index$1 > -1) state.order.splice(index$1, 1);
228
+ }
229
+ if (active) activate(this);
230
+ else deactivate(this);
231
+ }
232
+ };
193
233
  function activate(floatable) {
194
- floatable.active = true;
195
- document.body.append(floatable.options.content);
196
- floatable.options.content.hidden = false;
197
- updatePosition(floatable);
234
+ floatable.active = true;
235
+ document.body.append(floatable.options.content);
236
+ floatable.options.content.hidden = false;
237
+ updatePosition(floatable);
198
238
  }
199
239
  function closeAbove(element) {
200
- const state = getState();
201
- if (state == null) {
202
- return;
203
- }
204
- const index = state.order.findIndex(floatable => floatable.options.anchor === element ||
205
- floatable.options.content === element);
206
- if (index === -1 || index === state.order.length - 1) {
207
- return;
208
- }
209
- while (index < state.order.length - 1) {
210
- void state.order.pop()?.toggle(false, true);
211
- }
240
+ const state = getState();
241
+ if (state == null) return;
242
+ const index$1 = state.order.findIndex((floatable) => floatable.options.anchor === element || floatable.options.content === element);
243
+ if (index$1 === -1 || index$1 === state.order.length - 1) return;
244
+ while (index$1 < state.order.length - 1) state.order.pop()?.toggle(false, true);
212
245
  }
213
246
  function closeAll() {
214
- const state = getState();
215
- const floatables = [...(state?.active ?? [])];
216
- state?.active.clear();
217
- for (const floatable of floatables) {
218
- void floatable.toggle(false, true);
219
- }
247
+ const state = getState();
248
+ const floatables = [...state?.active ?? []];
249
+ state?.active.clear();
250
+ for (const floatable of floatables) floatable.toggle(false, true);
220
251
  }
221
252
  function closeNonInteractive(state) {
222
- for (const floatable of state.active) {
223
- if (!floatable.options.interactive) {
224
- void floatable.toggle(false);
225
- }
226
- }
253
+ for (const floatable of state.active) if (!floatable.options.interactive) floatable.toggle(false);
227
254
  }
228
255
  function deactivate(floatable) {
229
- floatable.active = false;
230
- floatable.options.content.hidden = true;
231
- floatable.options.anchor.insertAdjacentElement(INSERT_AFTEREND, floatable.options.content);
232
- floatable.options.onAfter?.(false);
256
+ floatable.active = false;
257
+ floatable.options.content.hidden = true;
258
+ floatable.options.anchor.insertAdjacentElement(INSERT_AFTEREND, floatable.options.content);
259
+ floatable.options.onAfter?.(false);
233
260
  }
234
261
  function getState() {
235
- return window._oscarpalmer_oui_floatable;
262
+ return window._oscarpalmer_oui_floatable;
236
263
  }
237
264
  function getX(anchor, content, position) {
238
- if (position.endsWith(POSITION_SUFFIX_END)) {
239
- const end = anchor.right - content.width;
240
- return end < 0 ? 0 : end;
241
- }
242
- if (position.endsWith(POSITION_SUFFIX_START)) {
243
- const start = anchor.left;
244
- return start + content.width > window.innerWidth
245
- ? window.innerWidth - content.width
246
- : start;
247
- }
248
- if (position.startsWith(POSITION_END)) {
249
- return anchor.right;
250
- }
251
- if (position.startsWith(POSITION_START)) {
252
- return anchor.left - content.width;
253
- }
254
- if (position.startsWith(POSITION_HORIZONTAL)) {
255
- if (anchor.right + content.width <= window.innerWidth) {
256
- return anchor.right;
257
- }
258
- return anchor.left - content.width;
259
- }
260
- const left = anchor.left + (anchor.width - content.width) / 2;
261
- return left < 0 ? 0 : left;
265
+ if (position.endsWith(POSITION_SUFFIX_END)) {
266
+ const end = anchor.right - content.width;
267
+ return end < 0 ? 0 : end;
268
+ }
269
+ if (position.endsWith(POSITION_SUFFIX_START)) {
270
+ const start = anchor.left;
271
+ return start + content.width > window.innerWidth ? window.innerWidth - content.width : start;
272
+ }
273
+ if (position.startsWith(POSITION_END)) return anchor.right;
274
+ if (position.startsWith(POSITION_START)) return anchor.left - content.width;
275
+ if (position.startsWith(POSITION_HORIZONTAL)) {
276
+ if (anchor.right + content.width <= window.innerWidth) return anchor.right;
277
+ return anchor.left - content.width;
278
+ }
279
+ const left = anchor.left + (anchor.width - content.width) / 2;
280
+ return left < 0 ? 0 : left;
262
281
  }
263
282
  function getY(anchor, content, position, preferAbove) {
264
- if (position.startsWith(POSITION_ABOVE)) {
265
- return anchor.top - content.height;
266
- }
267
- if (position.startsWith(POSITION_BELOW)) {
268
- return anchor.bottom;
269
- }
270
- if (position.endsWith(POSITION_BOTTOM)) {
271
- const bottom = anchor.bottom - content.height;
272
- return bottom < 0 ? 0 : bottom;
273
- }
274
- if (position.endsWith(POSITION_TOP)) {
275
- const top = anchor.top;
276
- return top + content.height > window.innerHeight
277
- ? window.innerHeight - content.height
278
- : top;
279
- }
280
- if (position.startsWith(POSITION_VERTICAL)) {
281
- if (preferAbove && anchor.top - content.height >= 0) {
282
- return anchor.top - content.height;
283
- }
284
- if (anchor.bottom + content.height <= document.body.clientHeight) {
285
- return anchor.bottom;
286
- }
287
- return anchor.top - content.height;
288
- }
289
- return anchor.top + (anchor.height - content.height) / 2;
283
+ if (position.startsWith(POSITION_ABOVE)) return anchor.top - content.height;
284
+ if (position.startsWith(POSITION_BELOW)) return anchor.bottom;
285
+ if (position.endsWith(POSITION_BOTTOM)) {
286
+ const bottom = anchor.bottom - content.height;
287
+ return bottom < 0 ? 0 : bottom;
288
+ }
289
+ if (position.endsWith(POSITION_TOP)) {
290
+ const top = anchor.top;
291
+ return top + content.height > window.innerHeight ? window.innerHeight - content.height : top;
292
+ }
293
+ if (position.startsWith(POSITION_VERTICAL)) {
294
+ if (preferAbove && anchor.top - content.height >= 0) return anchor.top - content.height;
295
+ if (anchor.bottom + content.height <= document.body.clientHeight) return anchor.bottom;
296
+ return anchor.top - content.height;
297
+ }
298
+ return anchor.top + (anchor.height - content.height) / 2;
290
299
  }
291
300
  function initialize(floatable) {
292
- const { anchor, content, interactive } = floatable.options;
293
- if (interactive) {
294
- anchor.setAttribute(ATTRIBUTE_ANCHOR, '');
295
- content.setAttribute(ATTRIBUTE_CONTENT$1, '');
296
- }
297
- content.style.position = 'fixed';
298
- content.style.inset = '0 auto auto 0';
299
- content.style.zIndex = '10';
300
- const state = getState();
301
- state?.mapped.set(anchor, floatable);
302
- state?.mapped.set(content, floatable);
301
+ const { anchor, content, interactive } = floatable.options;
302
+ if (interactive) {
303
+ anchor.setAttribute(ATTRIBUTE_ANCHOR, "");
304
+ content.setAttribute(ATTRIBUTE_CONTENT$1, "");
305
+ }
306
+ content.style.position = "fixed";
307
+ content.style.inset = "0 auto auto 0";
308
+ content.style.zIndex = "10";
309
+ const state = getState();
310
+ state?.mapped.set(anchor, floatable);
311
+ state?.mapped.set(content, floatable);
303
312
  }
304
313
  function isDisabled(element) {
305
- return (element.disabled ||
306
- element.readOnly ||
307
- element.getAttribute('aria-disabled') === 'true');
314
+ return element.disabled || element.readOnly || element.getAttribute("aria-disabled") === "true";
308
315
  }
309
316
  function onClick$1(event) {
310
- const related = findAncestor(event.target, SELECTOR_ALL);
311
- if (!(related instanceof HTMLElement)) {
312
- closeAll();
313
- }
314
- else if (related.hasAttribute(ATTRIBUTE_CONTENT$1)) {
315
- closeAbove(related);
316
- }
317
- else if (!isDisabled(related)) {
318
- toggle$1(related);
319
- }
317
+ const related = findAncestor(event.target, SELECTOR_ALL);
318
+ if (!(related instanceof HTMLElement)) closeAll();
319
+ else if (related.hasAttribute(ATTRIBUTE_CONTENT$1)) closeAbove(related);
320
+ else if (!isDisabled(related)) toggle$1(related);
320
321
  }
321
322
  function onKeyDown(event) {
322
- if (event.key !== 'Escape') {
323
- return;
324
- }
325
- const state = getState();
326
- if (state == null || state.active.size === 0) {
327
- return;
328
- }
329
- closeNonInteractive(state);
330
- const related = findAncestor(event.target, SELECTOR_CONTENT$1);
331
- if (!(related instanceof HTMLElement)) {
332
- return;
333
- }
334
- closeAbove(related);
335
- const floatable = state.mapped.get(related);
336
- if (floatable != null) {
337
- void floatable.toggle(false);
338
- }
323
+ if (event.key !== "Escape") return;
324
+ const state = getState();
325
+ if (state == null || state.active.size === 0) return;
326
+ closeNonInteractive(state);
327
+ const related = findAncestor(event.target, SELECTOR_CONTENT$1);
328
+ if (!(related instanceof HTMLElement)) return;
329
+ closeAbove(related);
330
+ const floatable = state.mapped.get(related);
331
+ if (floatable != null) floatable.toggle(false);
339
332
  }
340
333
  function stop(floatable) {
341
- if (floatable.frame != null) {
342
- cancelAnimationFrame(floatable.frame);
343
- }
344
- floatable.frame = undefined;
334
+ if (floatable.frame != null) cancelAnimationFrame(floatable.frame);
335
+ floatable.frame = void 0;
345
336
  }
346
337
  function toggle$1(anchor) {
347
- const floatable = getState()?.mapped.get(anchor);
348
- if (floatable == null) {
349
- closeAll();
350
- return;
351
- }
352
- const active = Boolean(floatable.active);
353
- const content = findAncestor(floatable.options.anchor, SELECTOR_CONTENT$1);
354
- if (content == null) {
355
- closeAll();
356
- }
357
- else {
358
- closeAbove(content);
359
- }
360
- void floatable.toggle(!active);
338
+ const floatable = getState()?.mapped.get(anchor);
339
+ if (floatable == null) {
340
+ closeAll();
341
+ return;
342
+ }
343
+ const active = Boolean(floatable.active);
344
+ const content = findAncestor(floatable.options.anchor, SELECTOR_CONTENT$1);
345
+ if (content == null) closeAll();
346
+ else closeAbove(content);
347
+ floatable.toggle(!active);
361
348
  }
362
349
  function updatePosition(floatable) {
363
- let position = floatable.options.anchor
364
- .getAttribute(floatable.options.positionAttribute)
365
- ?.trim() ?? floatable.options.defaultPosition;
366
- if (!POSITIONS.has(position)) {
367
- position = floatable.options.defaultPosition;
368
- }
369
- let previousAnchor;
370
- let previousContent;
371
- let calculated = false;
372
- let runOnAfter = false;
373
- function run() {
374
- const anchor = floatable.options.anchor.getBoundingClientRect();
375
- const content = floatable.options.content.getBoundingClientRect();
376
- if (calculated) {
377
- if (previousAnchor != null && previousContent != null) {
378
- if (PROPERTIES.every(property => anchor[property] === previousAnchor[property]) &&
379
- PROPERTIES.every(property => content[property] === previousContent[property])) {
380
- floatable.frame = requestAnimationFrame(run);
381
- return;
382
- }
383
- }
384
- }
385
- else {
386
- calculated = true;
387
- }
388
- update(anchor, content);
389
- }
390
- function update(anchor, content) {
391
- previousAnchor = anchor;
392
- previousContent = content;
393
- const left = getX(anchor, content, position);
394
- const top = getY(anchor, content, position, floatable.options.preferAbove);
395
- if (top + content.height > window.innerHeight) {
396
- floatable.options.content.style.height = `${window.innerHeight - top}px`;
397
- }
398
- else {
399
- floatable.options.content.style.height = '';
400
- }
401
- if (left + content.width > window.innerWidth) {
402
- floatable.options.content.style.width = `${window.innerWidth - left}px`;
403
- }
404
- else {
405
- floatable.options.content.style.width = '';
406
- }
407
- // floatable.options.content.style.inset = `${top}px auto auto ${left}px`;
408
- floatable.options.content.style.transform = `translate3d(${left}px, ${top}px, 0)`;
409
- floatable.frame = requestAnimationFrame(run);
410
- if (!runOnAfter) {
411
- runOnAfter = true;
412
- floatable.options.onAfter?.(true);
413
- }
414
- }
415
- floatable.frame = requestAnimationFrame(run);
416
- }
417
- //
418
- const ATTRIBUTE_ANCHOR = 'oui-floatable-anchor';
419
- const ATTRIBUTE_CONTENT$1 = 'oui-floatable-content';
420
- const INSERT_AFTEREND = 'afterend';
421
- const POSITION_ABOVE = 'above';
422
- const POSITION_BELOW = 'below';
423
- const POSITION_BOTTOM = 'bottom';
424
- const POSITION_END = 'end';
425
- const POSITION_HORIZONTAL = 'horizontal';
426
- const POSITION_START = 'start';
427
- const POSITION_SUFFIX_END = '-end';
428
- const POSITION_SUFFIX_START = '-start';
429
- const POSITION_TOP = 'top';
430
- const POSITION_VERTICAL = 'vertical';
350
+ let position = floatable.options.anchor.getAttribute(floatable.options.positionAttribute)?.trim() ?? floatable.options.defaultPosition;
351
+ if (!POSITIONS.has(position)) position = floatable.options.defaultPosition;
352
+ let previousAnchor;
353
+ let previousContent;
354
+ let calculated = false;
355
+ let runOnAfter = false;
356
+ function run() {
357
+ const anchor = floatable.options.anchor.getBoundingClientRect();
358
+ const content = floatable.options.content.getBoundingClientRect();
359
+ if (calculated) {
360
+ if (previousAnchor != null && previousContent != null) {
361
+ if (PROPERTIES.every((property) => anchor[property] === previousAnchor[property]) && PROPERTIES.every((property) => content[property] === previousContent[property])) {
362
+ floatable.frame = requestAnimationFrame(run);
363
+ return;
364
+ }
365
+ }
366
+ } else calculated = true;
367
+ update(anchor, content);
368
+ }
369
+ function update(anchor, content) {
370
+ previousAnchor = anchor;
371
+ previousContent = content;
372
+ const left = getX(anchor, content, position);
373
+ const top = getY(anchor, content, position, floatable.options.preferAbove);
374
+ if (top + content.height > window.innerHeight) floatable.options.content.style.height = `${window.innerHeight - top}px`;
375
+ else floatable.options.content.style.height = "";
376
+ if (left + content.width > window.innerWidth) floatable.options.content.style.width = `${window.innerWidth - left}px`;
377
+ else floatable.options.content.style.width = "";
378
+ floatable.options.content.style.transform = `translate3d(${left}px, ${top}px, 0)`;
379
+ floatable.frame = requestAnimationFrame(run);
380
+ if (!runOnAfter) {
381
+ runOnAfter = true;
382
+ floatable.options.onAfter?.(true);
383
+ }
384
+ }
385
+ floatable.frame = requestAnimationFrame(run);
386
+ }
387
+ const ATTRIBUTE_ANCHOR = "oui-floatable-anchor";
388
+ const ATTRIBUTE_CONTENT$1 = "oui-floatable-content";
389
+ const INSERT_AFTEREND = "afterend";
390
+ const POSITION_ABOVE = "above";
391
+ const POSITION_BELOW = "below";
392
+ const POSITION_BOTTOM = "bottom";
393
+ const POSITION_END = "end";
394
+ const POSITION_HORIZONTAL = "horizontal";
395
+ const POSITION_START = "start";
396
+ const POSITION_SUFFIX_END = "-end";
397
+ const POSITION_SUFFIX_START = "-start";
398
+ const POSITION_TOP = "top";
399
+ const POSITION_VERTICAL = "vertical";
431
400
  const POSITIONS = new Set([
432
- 'above',
433
- 'above-end',
434
- 'above-start',
435
- 'below',
436
- 'below-end',
437
- 'below-start',
438
- 'end',
439
- 'end-bottom',
440
- 'end-top',
441
- 'horizontal',
442
- 'horizontal-bottom',
443
- 'horizontal-top',
444
- 'start',
445
- 'start-bottom',
446
- 'start-top',
447
- 'vertical',
448
- 'vertical-end',
449
- 'vertical-start',
401
+ "above",
402
+ "above-end",
403
+ "above-start",
404
+ "below",
405
+ "below-end",
406
+ "below-start",
407
+ "end",
408
+ "end-bottom",
409
+ "end-top",
410
+ "horizontal",
411
+ "horizontal-bottom",
412
+ "horizontal-top",
413
+ "start",
414
+ "start-bottom",
415
+ "start-top",
416
+ "vertical",
417
+ "vertical-end",
418
+ "vertical-start"
450
419
  ]);
451
- const PROPERTIES = ['bottom', 'left', 'right', 'top'];
420
+ const PROPERTIES = [
421
+ "bottom",
422
+ "left",
423
+ "right",
424
+ "top"
425
+ ];
452
426
  const SELECTOR_ALL = `[${ATTRIBUTE_ANCHOR}], [${ATTRIBUTE_CONTENT$1}]`;
453
427
  const SELECTOR_CONTENT$1 = `[${ATTRIBUTE_CONTENT$1}]`;
454
- //
455
428
  if (window._oscarpalmer_oui_floatable == null) {
456
- Object.defineProperty(window, '_oscarpalmer_oui_floatable', {
457
- enumerable: false,
458
- value: {
459
- active: new Set(),
460
- mapped: new Map(),
461
- order: [],
462
- },
463
- writable: false,
464
- });
465
- on(document, 'keydown', event => {
466
- onKeyDown(event);
467
- });
468
- on(document, 'click', event => {
469
- onClick$1(event);
470
- });
471
- }
472
-
473
- class Tooltip {
474
- attributes;
475
- floatable;
476
- timer;
477
- constructor(anchor, content) {
478
- this.attributes = content.attributes;
479
- this.floatable = new Floatable({
480
- anchor,
481
- content: content.element,
482
- defaultPosition: 'vertical',
483
- interactive: false,
484
- preferAbove: true,
485
- positionAttribute: ATTRIBUTE_POSITION,
486
- });
487
- anchor.insertAdjacentElement('afterend', content.element);
488
- TOOLTIPS_ALL.set(content.element, this);
489
- }
490
- destroy() {
491
- const { attributes, floatable } = this;
492
- TOOLTIPS_ACTIVE.delete(this);
493
- TOOLTIPS_ALL.delete(floatable.options.anchor);
494
- TOOLTIPS_ALL.delete(floatable.options.content);
495
- reset(floatable.options.anchor, attributes);
496
- floatable.options.content.remove();
497
- floatable.destroy();
498
- this.attributes = undefined;
499
- this.floatable = undefined;
500
- }
429
+ Object.defineProperty(window, "_oscarpalmer_oui_floatable", {
430
+ enumerable: false,
431
+ value: {
432
+ active: /* @__PURE__ */ new Set(),
433
+ mapped: /* @__PURE__ */ new Map(),
434
+ order: []
435
+ },
436
+ writable: false
437
+ });
438
+ on(document, "keydown", (event) => {
439
+ onKeyDown(event);
440
+ });
441
+ on(document, "click", (event) => {
442
+ onClick$1(event);
443
+ });
501
444
  }
445
+ var Tooltip = class {
446
+ attributes;
447
+ floatable;
448
+ timer;
449
+ constructor(anchor, content) {
450
+ this.attributes = content.attributes;
451
+ this.floatable = new Floatable({
452
+ anchor,
453
+ content: content.element,
454
+ defaultPosition: "vertical",
455
+ interactive: false,
456
+ preferAbove: true,
457
+ positionAttribute: ATTRIBUTE_POSITION
458
+ });
459
+ anchor.insertAdjacentElement("afterend", content.element);
460
+ TOOLTIPS_ALL.set(content.element, this);
461
+ }
462
+ destroy() {
463
+ const { attributes, floatable } = this;
464
+ TOOLTIPS_ACTIVE.delete(this);
465
+ TOOLTIPS_ALL.delete(floatable.options.anchor);
466
+ TOOLTIPS_ALL.delete(floatable.options.content);
467
+ reset(floatable.options.anchor, attributes);
468
+ floatable.options.content.remove();
469
+ floatable.destroy();
470
+ this.attributes = void 0;
471
+ this.floatable = void 0;
472
+ }
473
+ };
502
474
  function addTooltip(anchor) {
503
- if (TOOLTIPS_ALL.has(anchor)) {
504
- return;
505
- }
506
- const content = getContent(anchor);
507
- if (content != null) {
508
- TOOLTIPS_ALL.set(anchor, new Tooltip(anchor, content));
509
- }
475
+ if (TOOLTIPS_ALL.has(anchor)) return;
476
+ const content = getContent(anchor);
477
+ if (content != null) TOOLTIPS_ALL.set(anchor, new Tooltip(anchor, content));
510
478
  }
511
479
  function closeTooltips(next) {
512
- const tooltips = [...TOOLTIPS_ACTIVE];
513
- for (const active of tooltips) {
514
- if (active === next) {
515
- continue;
516
- }
517
- if (active.timer != null) {
518
- clearTimeout(active.timer);
519
- }
520
- active.floatable.options.content.removeAttribute('oui-tooltip-content-active');
521
- requestAnimationFrame(() => {
522
- active.timer = setTimeout(() => {
523
- TOOLTIPS_ACTIVE.delete(active);
524
- active.floatable.toggle(false);
525
- }, delay);
526
- });
527
- }
480
+ const tooltips = [...TOOLTIPS_ACTIVE];
481
+ for (const active of tooltips) {
482
+ if (active === next) continue;
483
+ if (active.timer != null) clearTimeout(active.timer);
484
+ active.floatable.options.content.removeAttribute("oui-tooltip-content-active");
485
+ requestAnimationFrame(() => {
486
+ active.timer = setTimeout(() => {
487
+ TOOLTIPS_ACTIVE.delete(active);
488
+ active.floatable.toggle(false);
489
+ }, delay);
490
+ });
491
+ }
528
492
  }
529
493
  function getContent(anchor) {
530
- const attributes = {
531
- ariaDescribedby: anchor.getAttribute('aria-describedby'),
532
- ariaLabelledBy: anchor.getAttribute('aria-labelledby'),
533
- };
534
- const wrapper = getWrapper(anchor);
535
- const labelledElements = getElements(attributes.ariaLabelledBy);
536
- if (labelledElements.length > 0) {
537
- anchor.setAttribute('aria-labelledby', wrapper.id);
538
- for (const element of labelledElements) {
539
- wrapper.append(element);
540
- }
541
- return {
542
- attributes,
543
- element: wrapper,
544
- };
545
- }
546
- const describedElements = getElements(attributes.ariaDescribedby);
547
- if (describedElements.length > 0) {
548
- anchor.setAttribute('aria-describedby', wrapper.id);
549
- for (const element of describedElements) {
550
- wrapper.append(element);
551
- }
552
- return {
553
- attributes,
554
- element: wrapper,
555
- };
556
- }
557
- let content = anchor.getAttribute('aria-label');
558
- if (isNullableOrWhitespace(content)) {
559
- content = anchor.getAttribute('aria-description');
560
- }
561
- if (isNullableOrWhitespace(content)) {
562
- return;
563
- }
564
- const paragraph = document.createElement('p');
565
- paragraph.textContent = content;
566
- wrapper.append(paragraph);
567
- return {
568
- attributes,
569
- element: wrapper,
570
- };
494
+ const attributes = {
495
+ ariaDescribedby: anchor.getAttribute("aria-describedby"),
496
+ ariaLabelledBy: anchor.getAttribute("aria-labelledby")
497
+ };
498
+ const wrapper = getWrapper(anchor);
499
+ const labelledElements = getElements(attributes.ariaLabelledBy);
500
+ if (labelledElements.length > 0) {
501
+ anchor.setAttribute("aria-labelledby", wrapper.id);
502
+ for (const element of labelledElements) wrapper.append(element);
503
+ return {
504
+ attributes,
505
+ element: wrapper
506
+ };
507
+ }
508
+ const describedElements = getElements(attributes.ariaDescribedby);
509
+ if (describedElements.length > 0) {
510
+ anchor.setAttribute("aria-describedby", wrapper.id);
511
+ for (const element of describedElements) wrapper.append(element);
512
+ return {
513
+ attributes,
514
+ element: wrapper
515
+ };
516
+ }
517
+ let content = anchor.getAttribute("aria-label");
518
+ if (isNullableOrWhitespace(content)) content = anchor.getAttribute("aria-description");
519
+ if (isNullableOrWhitespace(content)) return;
520
+ const paragraph = document.createElement("p");
521
+ paragraph.textContent = content;
522
+ wrapper.append(paragraph);
523
+ return {
524
+ attributes,
525
+ element: wrapper
526
+ };
571
527
  }
572
528
  function getElements(attribute) {
573
- const ids = attribute?.split(EXPRESSION_WHITESPACE) ?? [];
574
- const elements = [];
575
- for (const id of ids) {
576
- if (isNullableOrWhitespace(id)) {
577
- continue;
578
- }
579
- const element = document.querySelector(`#${id}`);
580
- if (element instanceof HTMLElement) {
581
- const cloned = element.cloneNode(true);
582
- cloned.hidden = false;
583
- elements.push(cloned);
584
- }
585
- }
586
- return elements;
529
+ const ids = attribute?.split(EXPRESSION_WHITESPACE) ?? [];
530
+ const elements = [];
531
+ for (const id of ids) {
532
+ if (isNullableOrWhitespace(id)) continue;
533
+ const element = document.querySelector(`#${id}`);
534
+ if (element instanceof HTMLElement) {
535
+ const cloned = element.cloneNode(true);
536
+ cloned.hidden = false;
537
+ elements.push(cloned);
538
+ }
539
+ }
540
+ return elements;
587
541
  }
588
542
  function getWrapper(anchor) {
589
- const wrapper = document.createElement('div');
590
- wrapper.setAttribute(ATTRIBUTE_CONTENT, '');
591
- wrapper.className = anchor.getAttribute(ATTRIBUTE_CLASS) ?? '';
592
- wrapper.hidden = true;
593
- wrapper.id = `${SELECTOR}-${++index}`;
594
- wrapper.role = 'tooltip';
595
- wrapper.tabIndex = -1;
596
- return wrapper;
543
+ const wrapper = document.createElement("div");
544
+ wrapper.setAttribute(ATTRIBUTE_CONTENT, "");
545
+ wrapper.className = anchor.getAttribute(ATTRIBUTE_CLASS) ?? "";
546
+ wrapper.hidden = true;
547
+ wrapper.id = `${SELECTOR}-${++index}`;
548
+ wrapper.role = "tooltip";
549
+ wrapper.tabIndex = -1;
550
+ return wrapper;
597
551
  }
598
552
  function onActivate(event) {
599
- onToggle(event, true);
553
+ onToggle(event, true);
600
554
  }
601
555
  function onClick(event) {
602
- if (findAncestor(event.target, SELECTOR_CONTENT) != null) {
603
- event.stopPropagation();
604
- }
556
+ if (findAncestor(event.target, SELECTOR_CONTENT) != null) event.stopPropagation();
605
557
  }
606
558
  function onDeactivate(event) {
607
- onToggle(event, false);
608
- }
609
- function onToggle(event, activate) {
610
- if (toggle != null) {
611
- cancelAnimationFrame(toggle);
612
- }
613
- toggle = requestAnimationFrame(() => {
614
- toggle = undefined;
615
- const element = findAncestor(event.target, SELECTOR_FULL);
616
- const tooltip = TOOLTIPS_ALL.get(element);
617
- if (TOOLTIPS_ACTIVE.size > 0) {
618
- closeTooltips(tooltip);
619
- }
620
- if (tooltip == null ||
621
- tooltip.floatable.options.content.hasAttribute('oui-tooltip-content-active') === activate) {
622
- return;
623
- }
624
- if (activate) {
625
- if (tooltip.timer != null) {
626
- clearTimeout(tooltip.timer);
627
- }
628
- TOOLTIPS_ACTIVE.add(tooltip);
629
- tooltip.floatable.toggle(true);
630
- requestAnimationFrame(() => {
631
- tooltip.floatable.options.content.setAttribute('oui-tooltip-content-active', '');
632
- });
633
- return;
634
- }
635
- tooltip.floatable.options.content.removeAttribute('oui-tooltip-content-active');
636
- tooltip.timer ??= setTimeout(() => {
637
- TOOLTIPS_ACTIVE.delete(tooltip);
638
- tooltip.floatable.toggle(false);
639
- }, delay);
640
- });
559
+ onToggle(event, false);
560
+ }
561
+ function onToggle(event, activate$1) {
562
+ if (toggle != null) cancelAnimationFrame(toggle);
563
+ toggle = requestAnimationFrame(() => {
564
+ toggle = void 0;
565
+ const element = findAncestor(event.target, SELECTOR_FULL);
566
+ const tooltip = TOOLTIPS_ALL.get(element);
567
+ if (TOOLTIPS_ACTIVE.size > 0) closeTooltips(tooltip);
568
+ if (tooltip == null || tooltip.floatable.options.content.hasAttribute("oui-tooltip-content-active") === activate$1) return;
569
+ if (activate$1) {
570
+ if (tooltip.timer != null) clearTimeout(tooltip.timer);
571
+ TOOLTIPS_ACTIVE.add(tooltip);
572
+ tooltip.floatable.toggle(true);
573
+ requestAnimationFrame(() => {
574
+ tooltip.floatable.options.content.setAttribute("oui-tooltip-content-active", "");
575
+ });
576
+ return;
577
+ }
578
+ tooltip.floatable.options.content.removeAttribute("oui-tooltip-content-active");
579
+ tooltip.timer ??= setTimeout(() => {
580
+ TOOLTIPS_ACTIVE.delete(tooltip);
581
+ tooltip.floatable.toggle(false);
582
+ }, delay);
583
+ });
641
584
  }
642
585
  function removeTooltip(element) {
643
- if (!element.hasAttribute(ATTRIBUTE_CONTENT)) {
644
- TOOLTIPS_ALL.get(element)?.destroy();
645
- }
586
+ if (!element.hasAttribute(ATTRIBUTE_CONTENT)) TOOLTIPS_ALL.get(element)?.destroy();
646
587
  }
647
588
  function reset(anchor, attributes) {
648
- if (attributes.ariaDescribedby == null) {
649
- anchor.removeAttribute('aria-describedby');
650
- }
651
- else {
652
- anchor.setAttribute('aria-describedby', attributes.ariaDescribedby);
653
- }
589
+ if (attributes.ariaDescribedby == null) anchor.removeAttribute("aria-describedby");
590
+ else anchor.setAttribute("aria-describedby", attributes.ariaDescribedby);
654
591
  }
655
592
  function setDelay(value) {
656
- delay = typeof value === 'number' && value >= 0 ? value : delay;
593
+ delay = typeof value === "number" && value >= 0 ? value : delay;
657
594
  }
658
- //
659
- const SELECTOR = 'oui-tooltip';
595
+ const SELECTOR = "oui-tooltip";
660
596
  const ATTRIBUTE_CLASS = `${SELECTOR}-class`;
661
597
  const ATTRIBUTE_CONTENT = `${SELECTOR}-content`;
662
598
  const ATTRIBUTE_POSITION = `${SELECTOR}-position`;
663
599
  const SELECTOR_CONTENT = `[${ATTRIBUTE_CONTENT}]`;
664
600
  const SELECTOR_FULL = `[${SELECTOR}], [${ATTRIBUTE_CONTENT}]`;
665
601
  const EXPRESSION_WHITESPACE = /\s+/;
666
- const TOOLTIPS_ACTIVE = new Set();
667
- const TOOLTIPS_ALL = new WeakMap();
602
+ const TOOLTIPS_ACTIVE = /* @__PURE__ */ new Set();
603
+ const TOOLTIPS_ALL = /* @__PURE__ */ new WeakMap();
668
604
  let delay = 250;
669
605
  let index = 0;
670
606
  let toggle;
671
- //
672
607
  attributable(SELECTOR, addTooltip, removeTooltip);
673
- on(document, 'click', onClick, { capture: true });
674
- on(document, 'focusin', onActivate);
675
- on(document, 'focusout', onDeactivate);
676
- on(document, 'mousemove', onActivate);
677
- on(document, 'touchstart', onActivate);
678
-
608
+ on(document, "click", onClick, { capture: true });
609
+ on(document, "focusin", onActivate);
610
+ on(document, "focusout", onDeactivate);
611
+ on(document, "mousemove", onActivate);
612
+ on(document, "touchstart", onActivate);
679
613
  export { setDelay };