@oscarpalmer/oui 0.17.0 → 0.18.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.
- package/dist/css/badge.css +3 -3
- package/dist/css/content.css +9 -11
- package/dist/css/form.css +36 -22
- package/dist/css/message.css +4 -0
- package/dist/css/reset.css +176 -56
- package/dist/css/tooltip.css +8 -0
- package/dist/js/attributable.full.js +48 -0
- package/dist/js/attributable.js +30 -45
- package/dist/js/floatable.full.js +413 -0
- package/dist/js/floatable.js +254 -169
- package/dist/js/focus-trap/embedded.full.js +351 -0
- package/dist/js/focus-trap/embedded.js +131 -131
- package/dist/js/focus-trap/standalone.full.js +402 -0
- package/dist/js/focus-trap/standalone.js +4 -4
- package/dist/js/index.js +4 -5
- package/dist/js/oui.full.js +1596 -0
- package/dist/js/popover.full.js +822 -0
- package/dist/js/popover.js +83 -162
- package/dist/js/splitter.full.js +605 -0
- package/dist/js/splitter.js +263 -245
- package/dist/js/tooltip.full.js +679 -0
- package/dist/js/tooltip.js +159 -150
- package/package.json +31 -59
- package/src/css/content.scss +1 -2
- package/src/css/form.scss +12 -4
- package/src/css/message.scss +3 -0
- package/src/css/mixins.scss +7 -0
- package/src/css/reset.scss +180 -54
- package/src/css/tooltip.scss +8 -0
- package/src/js/floatable.ts +380 -133
- package/src/js/focus-trap/embedded.ts +149 -64
- package/src/js/focus-trap/standalone.ts +4 -4
- package/src/js/index.ts +1 -0
- package/src/js/popover.ts +50 -120
- package/src/js/splitter.ts +250 -103
- package/src/js/tooltip.ts +155 -68
- package/types/floatable.d.ts +17 -10
- package/types/focus-trap/embedded.d.ts +18 -5
- package/types/index.d.ts +1 -0
- package/types/popover.d.ts +2 -0
- package/types/splitter.d.ts +13 -1
- package/types/tooltip.d.ts +2 -1
- package/dist/js/attributable.cjs +0 -51
- package/dist/js/floatable.cjs +0 -176
- package/dist/js/focus-trap/embedded.cjs +0 -150
- package/dist/js/focus-trap/standalone.cjs +0 -8
- package/dist/js/index.cjs +0 -6
- package/dist/js/popover.cjs +0 -166
- package/dist/js/splitter.cjs +0 -272
- package/dist/js/tooltip.cjs +0 -166
- package/types/attributable.d.cts +0 -5
- package/types/floatable.d.cts +0 -20
- package/types/focus-trap/embedded.d.cts +0 -15
- package/types/focus-trap/standalone.d.cts +0 -3
- package/types/index.d.cts +0 -14
- package/types/popover.d.cts +0 -14
- package/types/splitter.d.cts +0 -10
- package/types/tooltip.d.cts +0 -3
package/src/js/tooltip.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
|
|
2
2
|
import {on} from '@oscarpalmer/toretto/event';
|
|
3
|
+
import {findAncestor} from '@oscarpalmer/toretto/find';
|
|
3
4
|
import {attributable} from './attributable';
|
|
4
|
-
import {
|
|
5
|
+
import {Floatable} from './floatable';
|
|
5
6
|
|
|
6
7
|
type Attributes = {
|
|
7
8
|
ariaDescribedby: string | null;
|
|
@@ -14,47 +15,80 @@ type Content = {
|
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
class Tooltip {
|
|
17
|
-
abortController = new AbortController();
|
|
18
18
|
attributes: Attributes;
|
|
19
|
+
|
|
19
20
|
floatable: Floatable;
|
|
20
21
|
|
|
22
|
+
timer: number | undefined;
|
|
23
|
+
|
|
21
24
|
constructor(anchor: HTMLElement, content: Content) {
|
|
22
25
|
this.attributes = content.attributes;
|
|
23
26
|
|
|
24
|
-
this.floatable = new Floatable(
|
|
27
|
+
this.floatable = new Floatable({
|
|
25
28
|
anchor,
|
|
26
|
-
content.element,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
true,
|
|
30
|
-
|
|
29
|
+
content: content.element,
|
|
30
|
+
defaultPosition: 'vertical',
|
|
31
|
+
interactive: false,
|
|
32
|
+
preferAbove: true,
|
|
33
|
+
positionAttribute: ATTRIBUTE_POSITION,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
anchor.insertAdjacentElement('afterend', content.element);
|
|
31
37
|
|
|
32
|
-
|
|
38
|
+
TOOLTIPS_ALL.set(content.element, this);
|
|
33
39
|
}
|
|
34
40
|
|
|
35
41
|
destroy(): void {
|
|
36
|
-
|
|
37
|
-
reset(this.floatable.anchor, this.attributes);
|
|
42
|
+
const {attributes, floatable} = this;
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
TOOLTIPS_ACTIVE.delete(this);
|
|
45
|
+
TOOLTIPS_ALL.delete(floatable.options.anchor);
|
|
46
|
+
TOOLTIPS_ALL.delete(floatable.options.content);
|
|
47
|
+
|
|
48
|
+
reset(floatable.options.anchor, attributes);
|
|
49
|
+
|
|
50
|
+
floatable.options.content.remove();
|
|
51
|
+
floatable.destroy();
|
|
42
52
|
|
|
43
|
-
this.abortController = undefined as never;
|
|
44
53
|
this.attributes = undefined as never;
|
|
45
54
|
this.floatable = undefined as never;
|
|
46
55
|
}
|
|
47
56
|
}
|
|
48
57
|
|
|
49
58
|
function addTooltip(anchor: HTMLElement): void {
|
|
50
|
-
if (
|
|
59
|
+
if (TOOLTIPS_ALL.has(anchor)) {
|
|
51
60
|
return;
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
const content = getContent(anchor);
|
|
55
64
|
|
|
56
65
|
if (content != null) {
|
|
57
|
-
|
|
66
|
+
TOOLTIPS_ALL.set(anchor, new Tooltip(anchor, content));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function closeTooltips(next: Tooltip | undefined): void {
|
|
71
|
+
const tooltips = [...TOOLTIPS_ACTIVE];
|
|
72
|
+
|
|
73
|
+
for (const active of tooltips) {
|
|
74
|
+
if (active === next) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (active.timer != null) {
|
|
79
|
+
clearTimeout(active.timer);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
active.floatable.options.content.removeAttribute(
|
|
83
|
+
'oui-tooltip-content-active',
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
requestAnimationFrame(() => {
|
|
87
|
+
active.timer = setTimeout(() => {
|
|
88
|
+
TOOLTIPS_ACTIVE.delete(active);
|
|
89
|
+
active.floatable.toggle(false);
|
|
90
|
+
}, delay) as never;
|
|
91
|
+
});
|
|
58
92
|
}
|
|
59
93
|
}
|
|
60
94
|
|
|
@@ -119,7 +153,7 @@ function getContent(anchor: HTMLElement): Content | undefined {
|
|
|
119
153
|
}
|
|
120
154
|
|
|
121
155
|
function getElements(attribute: string | null): HTMLElement[] {
|
|
122
|
-
const ids = attribute?.split(
|
|
156
|
+
const ids = attribute?.split(EXPRESSION_WHITESPACE) ?? [];
|
|
123
157
|
const elements: HTMLElement[] = [];
|
|
124
158
|
|
|
125
159
|
for (const id of ids) {
|
|
@@ -144,57 +178,92 @@ function getElements(attribute: string | null): HTMLElement[] {
|
|
|
144
178
|
function getWrapper(anchor: HTMLElement): HTMLElement {
|
|
145
179
|
const wrapper = document.createElement('div');
|
|
146
180
|
|
|
147
|
-
wrapper.setAttribute(
|
|
181
|
+
wrapper.setAttribute(ATTRIBUTE_CONTENT, '');
|
|
148
182
|
|
|
149
|
-
wrapper.className = anchor.getAttribute(
|
|
183
|
+
wrapper.className = anchor.getAttribute(ATTRIBUTE_CLASS) ?? '';
|
|
150
184
|
wrapper.hidden = true;
|
|
151
|
-
wrapper.id = `${
|
|
185
|
+
wrapper.id = `${SELECTOR}-${++index}`;
|
|
152
186
|
wrapper.role = 'tooltip';
|
|
153
187
|
wrapper.tabIndex = -1;
|
|
154
188
|
|
|
155
189
|
return wrapper;
|
|
156
190
|
}
|
|
157
191
|
|
|
158
|
-
function
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
192
|
+
function onActivate(event: Event): void {
|
|
193
|
+
onToggle(event, true);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function onClick(event: Event): void {
|
|
197
|
+
if (findAncestor(event.target as HTMLElement, SELECTOR_CONTENT) != null) {
|
|
198
|
+
event.stopPropagation();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function onDeactivate(event: Event): void {
|
|
203
|
+
onToggle(event, false);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function onToggle(event: Event, activate: boolean): void {
|
|
207
|
+
if (toggle != null) {
|
|
208
|
+
cancelAnimationFrame(toggle);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
toggle = requestAnimationFrame(() => {
|
|
212
|
+
toggle = undefined;
|
|
213
|
+
|
|
214
|
+
const element = findAncestor(
|
|
215
|
+
event.target as HTMLElement,
|
|
216
|
+
SELECTOR_FULL,
|
|
217
|
+
) as HTMLElement;
|
|
218
|
+
|
|
219
|
+
const tooltip = TOOLTIPS_ALL.get(element);
|
|
220
|
+
|
|
221
|
+
if (TOOLTIPS_ACTIVE.size > 0) {
|
|
222
|
+
closeTooltips(tooltip);
|
|
178
223
|
}
|
|
179
224
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
{
|
|
188
|
-
signal: abortController.signal,
|
|
189
|
-
},
|
|
190
|
-
);
|
|
225
|
+
if (
|
|
226
|
+
tooltip == null ||
|
|
227
|
+
tooltip.floatable.options.content.hasAttribute(
|
|
228
|
+
'oui-tooltip-content-active',
|
|
229
|
+
) === activate
|
|
230
|
+
) {
|
|
231
|
+
return;
|
|
191
232
|
}
|
|
192
|
-
|
|
233
|
+
|
|
234
|
+
if (activate) {
|
|
235
|
+
if (tooltip.timer != null) {
|
|
236
|
+
clearTimeout(tooltip.timer);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
TOOLTIPS_ACTIVE.add(tooltip);
|
|
240
|
+
tooltip.floatable.toggle(true);
|
|
241
|
+
|
|
242
|
+
requestAnimationFrame(() => {
|
|
243
|
+
tooltip.floatable.options.content.setAttribute(
|
|
244
|
+
'oui-tooltip-content-active',
|
|
245
|
+
'',
|
|
246
|
+
);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
tooltip.floatable.options.content.removeAttribute(
|
|
253
|
+
'oui-tooltip-content-active',
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
tooltip.timer ??= setTimeout(() => {
|
|
257
|
+
TOOLTIPS_ACTIVE.delete(tooltip);
|
|
258
|
+
tooltip.floatable.toggle(false);
|
|
259
|
+
}, delay) as never;
|
|
260
|
+
});
|
|
193
261
|
}
|
|
194
262
|
|
|
195
263
|
function removeTooltip(element: HTMLElement): void {
|
|
196
|
-
|
|
197
|
-
|
|
264
|
+
if (!element.hasAttribute(ATTRIBUTE_CONTENT)) {
|
|
265
|
+
TOOLTIPS_ALL.get(element)?.destroy();
|
|
266
|
+
}
|
|
198
267
|
}
|
|
199
268
|
|
|
200
269
|
function reset(anchor: HTMLElement, attributes: Attributes): void {
|
|
@@ -205,28 +274,46 @@ function reset(anchor: HTMLElement, attributes: Attributes): void {
|
|
|
205
274
|
}
|
|
206
275
|
}
|
|
207
276
|
|
|
277
|
+
function setDelay(value: number): void {
|
|
278
|
+
delay = typeof value === 'number' && value >= 0 ? value : delay;
|
|
279
|
+
}
|
|
280
|
+
|
|
208
281
|
//
|
|
209
282
|
|
|
210
|
-
const
|
|
283
|
+
const SELECTOR = 'oui-tooltip';
|
|
284
|
+
|
|
285
|
+
const ATTRIBUTE_CLASS = `${SELECTOR}-class`;
|
|
286
|
+
|
|
287
|
+
const ATTRIBUTE_CONTENT = `${SELECTOR}-content`;
|
|
288
|
+
|
|
289
|
+
const ATTRIBUTE_POSITION = `${SELECTOR}-position`;
|
|
290
|
+
|
|
291
|
+
const SELECTOR_CONTENT = `[${ATTRIBUTE_CONTENT}]`;
|
|
292
|
+
|
|
293
|
+
const SELECTOR_FULL = `[${SELECTOR}], [${ATTRIBUTE_CONTENT}]`;
|
|
211
294
|
|
|
212
|
-
const
|
|
295
|
+
const EXPRESSION_WHITESPACE = /\s+/;
|
|
213
296
|
|
|
214
|
-
const
|
|
297
|
+
const TOOLTIPS_ACTIVE: Set<Tooltip> = new Set();
|
|
215
298
|
|
|
216
|
-
const
|
|
299
|
+
const TOOLTIPS_ALL: WeakMap<HTMLElement, Tooltip> = new WeakMap();
|
|
217
300
|
|
|
218
|
-
|
|
301
|
+
let delay = 250;
|
|
219
302
|
|
|
220
303
|
let index = 0;
|
|
221
304
|
|
|
305
|
+
let toggle: DOMHighResTimeStamp | undefined;
|
|
306
|
+
|
|
222
307
|
//
|
|
223
308
|
|
|
224
|
-
attributable(
|
|
309
|
+
attributable(SELECTOR, addTooltip, removeTooltip);
|
|
225
310
|
|
|
226
|
-
on(document, '
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
311
|
+
on(document, 'click', onClick, {capture: true});
|
|
312
|
+
on(document, 'focusin', onActivate);
|
|
313
|
+
on(document, 'focusout', onDeactivate);
|
|
314
|
+
on(document, 'mousemove', onActivate);
|
|
315
|
+
on(document, 'touchstart', onActivate);
|
|
316
|
+
|
|
317
|
+
//
|
|
318
|
+
|
|
319
|
+
export {setDelay};
|
package/types/floatable.d.ts
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
export declare class Floatable {
|
|
2
|
-
|
|
3
|
-
content: HTMLElement;
|
|
4
|
-
readonly attribute: string;
|
|
5
|
-
readonly position: Position;
|
|
6
|
-
readonly preferAbove: boolean;
|
|
7
|
-
activate: number | undefined;
|
|
2
|
+
readonly options: Options;
|
|
8
3
|
active: boolean;
|
|
9
|
-
|
|
4
|
+
disabled: boolean;
|
|
10
5
|
frame: DOMHighResTimeStamp | undefined;
|
|
11
|
-
|
|
6
|
+
ignoreFocus: boolean;
|
|
7
|
+
constructor(options: Options);
|
|
12
8
|
destroy(): void;
|
|
9
|
+
disable(): void;
|
|
10
|
+
enable(): void;
|
|
11
|
+
toggle(active: boolean, ignoreFocus?: boolean): void;
|
|
13
12
|
}
|
|
13
|
+
type Options = {
|
|
14
|
+
anchor: HTMLElement;
|
|
15
|
+
content: HTMLElement;
|
|
16
|
+
defaultPosition: Position;
|
|
17
|
+
interactive: boolean;
|
|
18
|
+
positionAttribute: string;
|
|
19
|
+
preferAbove: boolean;
|
|
20
|
+
onAfter?: (active: boolean) => void;
|
|
21
|
+
};
|
|
14
22
|
type Position = 'above' | 'above-end' | 'above-start' | 'below' | 'below-end' | 'below-start' | 'end' | 'end-bottom' | 'end-top' | 'horizontal' | 'horizontal-bottom' | 'horizontal-top' | 'start' | 'start-bottom' | 'start-top' | 'vertical' | 'vertical-end' | 'vertical-start';
|
|
15
|
-
export declare function
|
|
16
|
-
export declare function deactivate(floatable: Floatable, active: Set<Floatable>, order?: Floatable[], time?: number): void;
|
|
23
|
+
export declare function deactivate(floatable: Floatable): void;
|
|
17
24
|
export {};
|
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
export declare class FocusTrap {
|
|
2
|
+
disabled: boolean;
|
|
3
|
+
connected: boolean;
|
|
2
4
|
element: HTMLElement;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
embedded: boolean;
|
|
6
|
+
get contain(): boolean;
|
|
7
|
+
get noescape(): boolean;
|
|
8
|
+
constructor(element: HTMLElement, options?: Options);
|
|
9
|
+
connect(): void;
|
|
5
10
|
destroy(): void;
|
|
6
11
|
disable(): void;
|
|
12
|
+
disconnect(): void;
|
|
7
13
|
enable(): void;
|
|
14
|
+
focus(last: boolean): void;
|
|
8
15
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
16
|
+
type Options = {
|
|
17
|
+
noescape: boolean;
|
|
18
|
+
};
|
|
19
|
+
export declare function createFocusTrap(element: HTMLElement, options?: Options): FocusTrap;
|
|
20
|
+
export declare const FOCUS_TRAP_SELECTOR = "oui-focus-trap";
|
|
21
|
+
export declare const FOCUS_TRAP_CONTAIN = "oui-focus-trap-contain";
|
|
22
|
+
export declare const FOCUS_TRAP_NOESCAPE = "oui-focus-trap-noescape";
|
|
23
|
+
export declare const FOCUSTRAPS_ALL: WeakMap<HTMLElement, FocusTrap>;
|
|
24
|
+
export {};
|
package/types/index.d.ts
CHANGED
package/types/popover.d.ts
CHANGED
package/types/splitter.d.ts
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
declare global {
|
|
2
2
|
interface HTMLElementTagNameMap {
|
|
3
|
-
|
|
3
|
+
[SELECTOR]: OuiSplitterElement;
|
|
4
4
|
}
|
|
5
5
|
}
|
|
6
6
|
export declare class OuiSplitterElement extends HTMLElement {
|
|
7
7
|
#private;
|
|
8
|
+
static readonly observedAttributes: string[];
|
|
9
|
+
get max(): number;
|
|
10
|
+
set max(value: number);
|
|
11
|
+
get min(): number;
|
|
12
|
+
set min(value: number);
|
|
13
|
+
get size(): number;
|
|
14
|
+
set size(value: number);
|
|
15
|
+
get type(): string;
|
|
16
|
+
set type(value: string);
|
|
8
17
|
constructor();
|
|
9
18
|
connectedCallback(): void;
|
|
10
19
|
disconnectedCallback(): void;
|
|
20
|
+
attributeChangedCallback(name: string): void;
|
|
11
21
|
}
|
|
22
|
+
declare const SELECTOR = "oui-splitter";
|
|
23
|
+
export {};
|
package/types/tooltip.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
declare function setDelay(value: number): void;
|
|
2
|
+
export { setDelay };
|
package/dist/js/attributable.cjs
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
function attributable(attribute, add, remove) {
|
|
4
|
-
const observer = new MutationObserver((entries) => {
|
|
5
|
-
const { length } = entries;
|
|
6
|
-
for (let index = 0; index < length; index += 1) {
|
|
7
|
-
const entry = entries[index];
|
|
8
|
-
if (entry.type === "attributes" && entry.target instanceof HTMLElement) {
|
|
9
|
-
if (entry.target.hasAttribute(attribute)) {
|
|
10
|
-
handleAdded(attribute, [entry.target], add);
|
|
11
|
-
} else {
|
|
12
|
-
handleRemoved([entry.target], remove);
|
|
13
|
-
}
|
|
14
|
-
} else if (entry.type === "childList") {
|
|
15
|
-
handleAdded(attribute, entry.addedNodes, add);
|
|
16
|
-
handleRemoved(entry.removedNodes, remove);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
observer.observe(document, {
|
|
21
|
-
attributeFilter: [attribute],
|
|
22
|
-
attributes: true,
|
|
23
|
-
childList: true,
|
|
24
|
-
subtree: true
|
|
25
|
-
});
|
|
26
|
-
requestAnimationFrame(() => {
|
|
27
|
-
handleAdded(attribute, document.querySelectorAll(`[${attribute}]`), add);
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
function handleAdded(attribute, nodes, add) {
|
|
31
|
-
const elements = [...nodes].filter(
|
|
32
|
-
(node) => node instanceof HTMLElement
|
|
33
|
-
);
|
|
34
|
-
const { length } = elements;
|
|
35
|
-
for (let index = 0; index < length; index += 1) {
|
|
36
|
-
const element = elements[index];
|
|
37
|
-
if (element.hasAttribute(attribute)) {
|
|
38
|
-
add(element);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
function handleRemoved(nodes, remove) {
|
|
43
|
-
const elements = [...nodes].filter(
|
|
44
|
-
(node) => node instanceof HTMLElement
|
|
45
|
-
);
|
|
46
|
-
const { length } = elements;
|
|
47
|
-
for (let index = 0; index < length; index += 1) {
|
|
48
|
-
remove(elements[index]);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
exports.attributable = attributable;
|
package/dist/js/floatable.cjs
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
class Floatable {
|
|
4
|
-
constructor(anchor, content, attribute, position, preferAbove) {
|
|
5
|
-
this.anchor = anchor;
|
|
6
|
-
this.content = content;
|
|
7
|
-
this.attribute = attribute;
|
|
8
|
-
this.position = position;
|
|
9
|
-
this.preferAbove = preferAbove;
|
|
10
|
-
setStyles(content);
|
|
11
|
-
}
|
|
12
|
-
activate;
|
|
13
|
-
active = false;
|
|
14
|
-
deactivate;
|
|
15
|
-
frame;
|
|
16
|
-
destroy() {
|
|
17
|
-
this.activate = void 0;
|
|
18
|
-
this.deactivate = void 0;
|
|
19
|
-
this.frame = void 0;
|
|
20
|
-
this.anchor = void 0;
|
|
21
|
-
this.content = void 0;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
function activate(floatable, active, order, time) {
|
|
25
|
-
stop(floatable);
|
|
26
|
-
if (floatable.active) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
if (time == null || time === 0) {
|
|
30
|
-
onActivate(floatable, active, order);
|
|
31
|
-
} else {
|
|
32
|
-
floatable.activate = +setTimeout(() => {
|
|
33
|
-
onActivate(floatable, active, order);
|
|
34
|
-
}, time);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
function deactivate(floatable, active, order, time) {
|
|
38
|
-
stop(floatable);
|
|
39
|
-
if (!floatable.active) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
if (time == null || time === 0) {
|
|
43
|
-
onDeactivate(floatable, active, order);
|
|
44
|
-
} else {
|
|
45
|
-
floatable.deactivate = +setTimeout(() => {
|
|
46
|
-
onDeactivate(floatable, active, order);
|
|
47
|
-
}, time);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
function getX(anchor, content, position) {
|
|
51
|
-
if (position.endsWith("-end")) {
|
|
52
|
-
const end = anchor.right - content.width;
|
|
53
|
-
return end - margin < 0 ? margin : end;
|
|
54
|
-
}
|
|
55
|
-
if (position.endsWith("-start")) {
|
|
56
|
-
const start = anchor.left;
|
|
57
|
-
return start + content.width + margin > window.innerWidth ? window.innerWidth - content.width - margin : start;
|
|
58
|
-
}
|
|
59
|
-
if (position.startsWith("end")) {
|
|
60
|
-
return anchor.right + margin;
|
|
61
|
-
}
|
|
62
|
-
if (position.startsWith("start")) {
|
|
63
|
-
return anchor.left - content.width - margin;
|
|
64
|
-
}
|
|
65
|
-
if (position.startsWith("horizontal")) {
|
|
66
|
-
if (anchor.right + content.width + margin <= window.innerWidth) {
|
|
67
|
-
return anchor.right + margin;
|
|
68
|
-
}
|
|
69
|
-
return anchor.left - content.width - margin;
|
|
70
|
-
}
|
|
71
|
-
return anchor.left + (anchor.width - content.width) / 2;
|
|
72
|
-
}
|
|
73
|
-
function getY(anchor, content, position, preferAbove) {
|
|
74
|
-
if (position.startsWith("above")) {
|
|
75
|
-
return anchor.top - content.height - margin;
|
|
76
|
-
}
|
|
77
|
-
if (position.startsWith("below")) {
|
|
78
|
-
return anchor.bottom + margin;
|
|
79
|
-
}
|
|
80
|
-
if (position.endsWith("bottom")) {
|
|
81
|
-
const bottom = anchor.bottom - content.height;
|
|
82
|
-
return bottom + margin < 0 ? margin : bottom;
|
|
83
|
-
}
|
|
84
|
-
if (position.endsWith("top")) {
|
|
85
|
-
const top = anchor.top;
|
|
86
|
-
return top + content.height + margin > window.innerHeight ? window.innerHeight - content.height - margin : top;
|
|
87
|
-
}
|
|
88
|
-
if (position.startsWith("vertical")) {
|
|
89
|
-
if (preferAbove && anchor.top - content.height - margin >= 0) {
|
|
90
|
-
return anchor.top - content.height - margin;
|
|
91
|
-
}
|
|
92
|
-
if (anchor.bottom + content.height + margin <= document.body.clientHeight) {
|
|
93
|
-
return anchor.bottom + margin;
|
|
94
|
-
}
|
|
95
|
-
return anchor.top - content.height - margin;
|
|
96
|
-
}
|
|
97
|
-
return anchor.top + (anchor.height - content.height) / 2;
|
|
98
|
-
}
|
|
99
|
-
function onActivate(floatable, active, order) {
|
|
100
|
-
floatable.active = true;
|
|
101
|
-
active.add(floatable);
|
|
102
|
-
if (order != null) {
|
|
103
|
-
order.push(floatable);
|
|
104
|
-
}
|
|
105
|
-
document.body.append(floatable.content);
|
|
106
|
-
floatable.content.hidden = false;
|
|
107
|
-
update(floatable);
|
|
108
|
-
}
|
|
109
|
-
function onDeactivate(floatable, active, order) {
|
|
110
|
-
floatable.active = false;
|
|
111
|
-
active.delete(floatable);
|
|
112
|
-
const index = order?.indexOf(floatable) ?? -1;
|
|
113
|
-
if (index > -1) {
|
|
114
|
-
order?.splice(index, 1);
|
|
115
|
-
}
|
|
116
|
-
floatable.content.hidden = true;
|
|
117
|
-
floatable.anchor.insertAdjacentElement("afterend", floatable.content);
|
|
118
|
-
}
|
|
119
|
-
function update(floatable) {
|
|
120
|
-
let position = floatable.anchor.getAttribute(floatable.attribute)?.trim() ?? floatable.position;
|
|
121
|
-
if (!positions.has(position)) {
|
|
122
|
-
position = floatable.position;
|
|
123
|
-
}
|
|
124
|
-
function run() {
|
|
125
|
-
const anchor = floatable.anchor.getBoundingClientRect();
|
|
126
|
-
const content = floatable.content.getBoundingClientRect();
|
|
127
|
-
const left = getX(anchor, content, position);
|
|
128
|
-
const top = getY(anchor, content, position, floatable.preferAbove);
|
|
129
|
-
floatable.content.style.inset = `${top}px auto auto ${left}px`;
|
|
130
|
-
floatable.frame = requestAnimationFrame(run);
|
|
131
|
-
}
|
|
132
|
-
floatable.frame = requestAnimationFrame(run);
|
|
133
|
-
}
|
|
134
|
-
function setStyles(content) {
|
|
135
|
-
content.style.position = "fixed";
|
|
136
|
-
content.style.inset = "0 auto auto 0";
|
|
137
|
-
content.style.zIndex = "10";
|
|
138
|
-
}
|
|
139
|
-
function stop(floatable) {
|
|
140
|
-
if (floatable.frame != null) {
|
|
141
|
-
cancelAnimationFrame(floatable.frame);
|
|
142
|
-
}
|
|
143
|
-
if (floatable.activate != null) {
|
|
144
|
-
clearTimeout(floatable.activate);
|
|
145
|
-
}
|
|
146
|
-
if (floatable.deactivate != null) {
|
|
147
|
-
clearTimeout(floatable.deactivate);
|
|
148
|
-
}
|
|
149
|
-
floatable.activate = void 0;
|
|
150
|
-
floatable.deactivate = void 0;
|
|
151
|
-
floatable.frame = void 0;
|
|
152
|
-
}
|
|
153
|
-
const margin = Number.parseInt(getComputedStyle(document.documentElement).fontSize, 10) / 2;
|
|
154
|
-
const positions = /* @__PURE__ */ new Set([
|
|
155
|
-
"above",
|
|
156
|
-
"above-end",
|
|
157
|
-
"above-start",
|
|
158
|
-
"below",
|
|
159
|
-
"below-end",
|
|
160
|
-
"below-start",
|
|
161
|
-
"end",
|
|
162
|
-
"end-bottom",
|
|
163
|
-
"end-top",
|
|
164
|
-
"horizontal",
|
|
165
|
-
"horizontal-bottom",
|
|
166
|
-
"horizontal-top",
|
|
167
|
-
"start",
|
|
168
|
-
"start-bottom",
|
|
169
|
-
"start-top",
|
|
170
|
-
"vertical",
|
|
171
|
-
"vertical-end",
|
|
172
|
-
"vertical-start"
|
|
173
|
-
]);
|
|
174
|
-
exports.Floatable = Floatable;
|
|
175
|
-
exports.activate = activate;
|
|
176
|
-
exports.deactivate = deactivate;
|