@oscarpalmer/oui 0.19.0 → 0.20.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 (50) hide show
  1. package/dist/css/a11y.css +0 -1
  2. package/dist/css/form.css +0 -1
  3. package/dist/css/popover.css +22 -0
  4. package/dist/css/reset.css +8 -8
  5. package/dist/css/table.css +1 -1
  6. package/dist/css/tooltip.css +43 -0
  7. package/dist/js/attributable.d.mts +4 -0
  8. package/dist/js/{attributable.full.js → attributable.mjs} +8 -1
  9. package/dist/js/floatable.d.mts +26 -0
  10. package/dist/js/{floatable.js → floatable.mjs} +73 -50
  11. package/dist/js/focus-trap/embedded.d.mts +26 -0
  12. package/dist/js/focus-trap/{embedded.js → embedded.mjs} +10 -8
  13. package/dist/js/focus-trap/standalone.d.mts +1 -0
  14. package/dist/js/focus-trap/{standalone.js → standalone.mjs} +5 -2
  15. package/dist/js/index.d.mts +4 -0
  16. package/dist/js/index.mjs +5 -0
  17. package/dist/js/popover.d.mts +20 -0
  18. package/dist/js/{popover.js → popover.mjs} +10 -8
  19. package/dist/js/splitter.d.mts +25 -0
  20. package/dist/js/{splitter.js → splitter.mjs} +58 -56
  21. package/dist/js/tooltip.d.mts +4 -0
  22. package/dist/js/{tooltip.js → tooltip.mjs} +20 -18
  23. package/package.json +64 -69
  24. package/src/css/mixins.scss +30 -1
  25. package/src/css/popover.scss +6 -1
  26. package/src/css/reset.scss +4 -4
  27. package/src/css/table.scss +1 -1
  28. package/src/css/tooltip.scss +55 -1
  29. package/src/js/attributable.ts +11 -1
  30. package/src/js/floatable.ts +136 -58
  31. package/src/js/focus-trap/embedded.ts +4 -10
  32. package/src/js/splitter.ts +2 -5
  33. package/src/js/tooltip.ts +5 -5
  34. package/dist/js/attributable.js +0 -36
  35. package/dist/js/floatable.full.js +0 -398
  36. package/dist/js/focus-trap/embedded.full.js +0 -408
  37. package/dist/js/focus-trap/standalone.full.js +0 -447
  38. package/dist/js/index.js +0 -5
  39. package/dist/js/oui.full.js +0 -1573
  40. package/dist/js/popover.full.js +0 -760
  41. package/dist/js/splitter.full.js +0 -769
  42. package/dist/js/tooltip.full.js +0 -613
  43. package/types/attributable.d.ts +0 -1
  44. package/types/floatable.d.ts +0 -24
  45. package/types/focus-trap/embedded.d.ts +0 -24
  46. package/types/focus-trap/standalone.d.ts +0 -1
  47. package/types/index.d.ts +0 -4
  48. package/types/popover.d.ts +0 -17
  49. package/types/splitter.d.ts +0 -23
  50. package/types/tooltip.d.ts +0 -2
@@ -1,398 +0,0 @@
1
- function noop() {}
2
- function calculate() {
3
- return new Promise((resolve) => {
4
- const values = [];
5
- let last;
6
- function step(now) {
7
- if (last != null) values.push(now - last);
8
- last = now;
9
- if (values.length >= TOTAL) resolve(values.sort().slice(TRIM_PART, -TRIM_PART).reduce((first, second) => first + second, 0) / (values.length - TRIM_TOTAL));
10
- else requestAnimationFrame(step);
11
- }
12
- requestAnimationFrame(step);
13
- });
14
- }
15
- var TOTAL = 10;
16
- var TRIM_PART = 2;
17
- var TRIM_TOTAL = 4;
18
- await calculate();
19
- function getBoolean(value, defaultValue) {
20
- return typeof value === "boolean" ? value : defaultValue ?? false;
21
- }
22
- function isEventTarget(value) {
23
- return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
24
- }
25
- function addDelegatedHandler(doc, type, name, passive) {
26
- if (DELEGATED.has(name)) return;
27
- DELEGATED.add(name);
28
- doc.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
29
- }
30
- function addDelegatedListener(target, type, name, listener, passive) {
31
- target[name] ??= /* @__PURE__ */ new Set();
32
- target[name].add(listener);
33
- addDelegatedHandler(document, type, name, passive);
34
- return () => {
35
- removeDelegatedListener(target, name, listener);
36
- };
37
- }
38
- function delegatedEventHandler(event) {
39
- const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
40
- const items = event.composedPath();
41
- const { length } = items;
42
- let target = items[0];
43
- Object.defineProperties(event, {
44
- currentTarget: {
45
- configurable: true,
46
- get() {
47
- return target;
48
- }
49
- },
50
- target: {
51
- configurable: true,
52
- value: target
53
- }
54
- });
55
- for (let index = 0; index < length; index += 1) {
56
- const item = items[index];
57
- const listeners = item[key];
58
- if (item.disabled || listeners == null) continue;
59
- target = item;
60
- for (const listener of listeners) {
61
- listener.call(item, event);
62
- if (event.cancelBubble) return;
63
- }
64
- }
65
- }
66
- function getDelegatedName(target, type, options) {
67
- 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}`;
68
- }
69
- function removeDelegatedListener(target, name, listener) {
70
- const handlers = target[name];
71
- if (handlers == null || !handlers.has(listener)) return false;
72
- handlers.delete(listener);
73
- if (handlers.size === 0) target[name] = void 0;
74
- return true;
75
- }
76
- var DELEGATED = /* @__PURE__ */ new Set();
77
- var EVENT_PREFIX = "@";
78
- var EVENT_SUFFIX_ACTIVE = ":active";
79
- var EVENT_SUFFIX_PASSIVE = ":passive";
80
- var EVENT_TYPES = new Set([
81
- "beforeinput",
82
- "click",
83
- "dblclick",
84
- "contextmenu",
85
- "focusin",
86
- "focusout",
87
- "input",
88
- "keydown",
89
- "keyup",
90
- "mousedown",
91
- "mousemove",
92
- "mouseout",
93
- "mouseover",
94
- "mouseup",
95
- "pointerdown",
96
- "pointermove",
97
- "pointerout",
98
- "pointerover",
99
- "pointerup",
100
- "touchend",
101
- "touchmove",
102
- "touchstart"
103
- ]);
104
- var HANDLER_ACTIVE = delegatedEventHandler.bind(false);
105
- var HANDLER_PASSIVE = delegatedEventHandler.bind(true);
106
- function createEventOptions(options) {
107
- return {
108
- capture: getBoolean(options?.capture),
109
- once: getBoolean(options?.once),
110
- passive: getBoolean(options?.passive, true),
111
- signal: options?.signal instanceof AbortSignal ? options.signal : void 0
112
- };
113
- }
114
- function on(target, type, listener, options) {
115
- if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return noop;
116
- const extended = createEventOptions(options);
117
- const delegated = getDelegatedName(target, type, extended);
118
- if (delegated != null) return addDelegatedListener(target, type, delegated, listener, extended.passive);
119
- target.addEventListener(type, listener, extended);
120
- if (extended.once) return noop;
121
- return () => {
122
- target.removeEventListener(type, listener, extended);
123
- };
124
- }
125
- function findAncestor(origin, selector) {
126
- if (!(origin instanceof Element) || selector == null) return null;
127
- if (typeof selector === "string") {
128
- if (origin.matches?.(selector)) return origin;
129
- return origin.closest(selector);
130
- }
131
- if (typeof selector !== "function") return null;
132
- if (selector(origin)) return origin;
133
- let parent = origin.parentElement;
134
- while (parent != null && !selector(parent)) {
135
- if (parent === document.body) return null;
136
- parent = parent.parentElement;
137
- }
138
- return parent;
139
- }
140
- var Floatable = class {
141
- active = false;
142
- disabled = false;
143
- frame;
144
- ignoreFocus = false;
145
- constructor(options) {
146
- this.options = options;
147
- initialize(this);
148
- }
149
- destroy() {
150
- stop(this);
151
- const state = getState();
152
- state?.active.delete(this);
153
- state?.mapped.delete(this.options.anchor);
154
- state?.mapped.delete(this.options.content);
155
- this.options.anchor = void 0;
156
- this.options.content = void 0;
157
- }
158
- disable() {
159
- if (this.disabled) return;
160
- this.disabled = true;
161
- stop(this);
162
- getState()?.active.delete(this);
163
- }
164
- enable() {
165
- if (!this.disabled) return;
166
- this.disabled = false;
167
- initialize(this);
168
- }
169
- toggle(active, ignoreFocus) {
170
- if (this.disabled || this.active === active) return;
171
- const state = getState();
172
- if (state == null) return;
173
- this.ignoreFocus = !active && (ignoreFocus ?? false);
174
- stop(this);
175
- if (active) state.active.add(this);
176
- else state.active.delete(this);
177
- if (this.options.interactive) if (active) state.order.push(this);
178
- else {
179
- const index = state.order.indexOf(this);
180
- if (index > -1) state.order.splice(index, 1);
181
- }
182
- if (active) activate(this);
183
- else deactivate(this);
184
- }
185
- };
186
- function activate(floatable) {
187
- floatable.active = true;
188
- document.body.append(floatable.options.content);
189
- floatable.options.content.hidden = false;
190
- updatePosition(floatable);
191
- }
192
- function closeAbove(element) {
193
- const state = getState();
194
- if (state == null) return;
195
- const index = state.order.findIndex((floatable) => floatable.options.anchor === element || floatable.options.content === element);
196
- if (index === -1 || index === state.order.length - 1) return;
197
- while (index < state.order.length - 1) state.order.pop()?.toggle(false, true);
198
- }
199
- function closeAll() {
200
- const state = getState();
201
- const floatables = [...state?.active ?? []];
202
- state?.active.clear();
203
- for (const floatable of floatables) floatable.toggle(false, true);
204
- }
205
- function closeNonInteractive(state) {
206
- for (const floatable of state.active) if (!floatable.options.interactive) floatable.toggle(false);
207
- }
208
- function deactivate(floatable) {
209
- floatable.active = false;
210
- floatable.options.content.hidden = true;
211
- floatable.options.anchor.insertAdjacentElement(INSERT_AFTEREND, floatable.options.content);
212
- floatable.options.onAfter?.(false);
213
- }
214
- function getState() {
215
- return window._oscarpalmer_oui_floatable;
216
- }
217
- function getX(anchor, content, position) {
218
- if (position.endsWith(POSITION_SUFFIX_END)) {
219
- const end = anchor.right - content.width;
220
- return end < 0 ? 0 : end;
221
- }
222
- if (position.endsWith(POSITION_SUFFIX_START)) {
223
- const start = anchor.left;
224
- return start + content.width > window.innerWidth ? window.innerWidth - content.width : start;
225
- }
226
- if (position.startsWith(POSITION_END)) return anchor.right;
227
- if (position.startsWith(POSITION_START)) return anchor.left - content.width;
228
- if (position.startsWith(POSITION_HORIZONTAL)) {
229
- if (anchor.right + content.width <= window.innerWidth) return anchor.right;
230
- return anchor.left - content.width;
231
- }
232
- const left = anchor.left + (anchor.width - content.width) / 2;
233
- return left < 0 ? 0 : left;
234
- }
235
- function getY(anchor, content, position, preferAbove) {
236
- if (position.startsWith(POSITION_ABOVE)) return anchor.top - content.height;
237
- if (position.startsWith(POSITION_BELOW)) return anchor.bottom;
238
- if (position.endsWith(POSITION_BOTTOM)) {
239
- const bottom = anchor.bottom - content.height;
240
- return bottom < 0 ? 0 : bottom;
241
- }
242
- if (position.endsWith(POSITION_TOP)) {
243
- const top = anchor.top;
244
- return top + content.height > window.innerHeight ? window.innerHeight - content.height : top;
245
- }
246
- if (position.startsWith(POSITION_VERTICAL)) {
247
- if (preferAbove && anchor.top - content.height >= 0) return anchor.top - content.height;
248
- if (anchor.bottom + content.height <= document.body.clientHeight) return anchor.bottom;
249
- return anchor.top - content.height;
250
- }
251
- return anchor.top + (anchor.height - content.height) / 2;
252
- }
253
- function initialize(floatable) {
254
- const { anchor, content, interactive } = floatable.options;
255
- if (interactive) {
256
- anchor.setAttribute(ATTRIBUTE_ANCHOR, "");
257
- content.setAttribute(ATTRIBUTE_CONTENT, "");
258
- }
259
- content.style.position = "fixed";
260
- content.style.inset = "0 auto auto 0";
261
- content.style.zIndex = "10";
262
- const state = getState();
263
- state?.mapped.set(anchor, floatable);
264
- state?.mapped.set(content, floatable);
265
- }
266
- function isDisabled(element) {
267
- return element.disabled || element.readOnly || element.getAttribute("aria-disabled") === "true";
268
- }
269
- function onClick(event) {
270
- const related = findAncestor(event.target, SELECTOR_ALL);
271
- if (!(related instanceof HTMLElement)) closeAll();
272
- else if (related.hasAttribute(ATTRIBUTE_CONTENT)) closeAbove(related);
273
- else if (!isDisabled(related)) toggle(related);
274
- }
275
- function onKeyDown(event) {
276
- if (event.key !== "Escape") return;
277
- const state = getState();
278
- if (state == null || state.active.size === 0) return;
279
- closeNonInteractive(state);
280
- const related = findAncestor(event.target, SELECTOR_CONTENT);
281
- if (!(related instanceof HTMLElement)) return;
282
- closeAbove(related);
283
- const floatable = state.mapped.get(related);
284
- if (floatable != null) floatable.toggle(false);
285
- }
286
- function stop(floatable) {
287
- if (floatable.frame != null) cancelAnimationFrame(floatable.frame);
288
- floatable.frame = void 0;
289
- }
290
- function toggle(anchor) {
291
- const floatable = getState()?.mapped.get(anchor);
292
- if (floatable == null) {
293
- closeAll();
294
- return;
295
- }
296
- const active = Boolean(floatable.active);
297
- const content = findAncestor(floatable.options.anchor, SELECTOR_CONTENT);
298
- if (content == null) closeAll();
299
- else closeAbove(content);
300
- floatable.toggle(!active);
301
- }
302
- function updatePosition(floatable) {
303
- let position = floatable.options.anchor.getAttribute(floatable.options.positionAttribute)?.trim() ?? floatable.options.defaultPosition;
304
- if (!POSITIONS.has(position)) position = floatable.options.defaultPosition;
305
- let previousAnchor;
306
- let previousContent;
307
- let calculated = false;
308
- let runOnAfter = false;
309
- function run() {
310
- const anchor = floatable.options.anchor.getBoundingClientRect();
311
- const content = floatable.options.content.getBoundingClientRect();
312
- if (calculated) {
313
- if (previousAnchor != null && previousContent != null) {
314
- if (PROPERTIES.every((property) => anchor[property] === previousAnchor[property]) && PROPERTIES.every((property) => content[property] === previousContent[property])) {
315
- floatable.frame = requestAnimationFrame(run);
316
- return;
317
- }
318
- }
319
- } else calculated = true;
320
- update(anchor, content);
321
- }
322
- function update(anchor, content) {
323
- previousAnchor = anchor;
324
- previousContent = content;
325
- const left = getX(anchor, content, position);
326
- const top = getY(anchor, content, position, floatable.options.preferAbove);
327
- if (top + content.height > window.innerHeight) floatable.options.content.style.height = `${window.innerHeight - top}px`;
328
- else floatable.options.content.style.height = "";
329
- if (left + content.width > window.innerWidth) floatable.options.content.style.width = `${window.innerWidth - left}px`;
330
- else floatable.options.content.style.width = "";
331
- floatable.options.content.style.transform = `translate3d(${left}px, ${top}px, 0)`;
332
- floatable.frame = requestAnimationFrame(run);
333
- if (!runOnAfter) {
334
- runOnAfter = true;
335
- floatable.options.onAfter?.(true);
336
- }
337
- }
338
- floatable.frame = requestAnimationFrame(run);
339
- }
340
- const ATTRIBUTE_ANCHOR = "oui-floatable-anchor";
341
- const ATTRIBUTE_CONTENT = "oui-floatable-content";
342
- const INSERT_AFTEREND = "afterend";
343
- const POSITION_ABOVE = "above";
344
- const POSITION_BELOW = "below";
345
- const POSITION_BOTTOM = "bottom";
346
- const POSITION_END = "end";
347
- const POSITION_HORIZONTAL = "horizontal";
348
- const POSITION_START = "start";
349
- const POSITION_SUFFIX_END = "-end";
350
- const POSITION_SUFFIX_START = "-start";
351
- const POSITION_TOP = "top";
352
- const POSITION_VERTICAL = "vertical";
353
- const POSITIONS = new Set([
354
- "above",
355
- "above-end",
356
- "above-start",
357
- "below",
358
- "below-end",
359
- "below-start",
360
- "end",
361
- "end-bottom",
362
- "end-top",
363
- "horizontal",
364
- "horizontal-bottom",
365
- "horizontal-top",
366
- "start",
367
- "start-bottom",
368
- "start-top",
369
- "vertical",
370
- "vertical-end",
371
- "vertical-start"
372
- ]);
373
- const PROPERTIES = [
374
- "bottom",
375
- "left",
376
- "right",
377
- "top"
378
- ];
379
- const SELECTOR_ALL = `[${ATTRIBUTE_ANCHOR}], [${ATTRIBUTE_CONTENT}]`;
380
- const SELECTOR_CONTENT = `[${ATTRIBUTE_CONTENT}]`;
381
- if (window._oscarpalmer_oui_floatable == null) {
382
- Object.defineProperty(window, "_oscarpalmer_oui_floatable", {
383
- enumerable: false,
384
- value: {
385
- active: /* @__PURE__ */ new Set(),
386
- mapped: /* @__PURE__ */ new Map(),
387
- order: []
388
- },
389
- writable: false
390
- });
391
- on(document, "keydown", (event) => {
392
- onKeyDown(event);
393
- });
394
- on(document, "click", (event) => {
395
- onClick(event);
396
- });
397
- }
398
- export { Floatable, deactivate };