@oscarpalmer/oui 0.24.0 → 0.26.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/{tooltip.css → floatable.css} +59 -24
- package/dist/css/reset.css +17 -0
- package/dist/js/dialog.d.mts +38 -0
- package/dist/js/dialog.mjs +92 -0
- package/dist/js/embedded-CHK82Uh5.d.mts +76 -0
- package/dist/js/embedded-ai6cqURc.d.mts +68 -0
- package/dist/js/floatable/embedded.d.mts +2 -0
- package/dist/js/floatable/embedded.mjs +157 -0
- package/dist/js/floatable/standalone.d.mts +2 -0
- package/dist/js/floatable/standalone.mjs +2 -0
- package/dist/js/focus-trap/embedded.d.mts +2 -26
- package/dist/js/focus-trap/embedded.mjs +158 -80
- package/dist/js/focus-trap/standalone.d.mts +2 -1
- package/dist/js/focus-trap/standalone.mjs +3 -3
- package/dist/js/index.d.mts +6 -3
- package/dist/js/index.mjs +9 -5
- package/dist/js/internal/draggable.d.mts +2 -2
- package/dist/js/internal/draggable.mjs +3 -3
- package/dist/js/{movable-BKFgoaOl.d.mts → movable-dNqBctx3.d.mts} +16 -16
- package/dist/js/movable.d.mts +2 -2
- package/dist/js/movable.mjs +4 -4
- package/dist/js/popover.d.mts +38 -1
- package/dist/js/popover.mjs +83 -44
- package/dist/js/sortable.d.mts +2 -2
- package/dist/js/sortable.mjs +5 -5
- package/dist/js/splitter.mjs +49 -48
- package/dist/js/toolbar.d.mts +1 -0
- package/dist/js/toolbar.mjs +107 -0
- package/dist/js/tooltip.d.mts +27 -1
- package/dist/js/tooltip.mjs +85 -49
- package/package.json +14 -2
- package/src/css/{tooltip.scss → floatable.scss} +47 -5
- package/src/css/mixins.scss +0 -2
- package/src/css/reset.scss +17 -0
- package/src/js/dialog.ts +188 -0
- package/src/js/floatable/embedded.ts +323 -0
- package/src/js/floatable/standalone.ts +1 -0
- package/src/js/focus-trap/embedded.ts +219 -93
- package/src/js/focus-trap/standalone.ts +4 -2
- package/src/js/index.ts +6 -4
- package/src/js/internal/draggable.ts +20 -20
- package/src/js/movable.ts +17 -17
- package/src/js/popover.ts +143 -61
- package/src/js/sortable.ts +26 -26
- package/src/js/splitter.ts +98 -96
- package/src/js/toolbar.ts +214 -0
- package/src/js/tooltip.ts +138 -54
- package/dist/css/popover.css +0 -30
- package/dist/js/floatable.d.mts +0 -59
- package/dist/js/floatable.mjs +0 -130
- package/src/css/popover.scss +0 -10
- package/src/js/floatable.ts +0 -237
package/src/js/tooltip.ts
CHANGED
|
@@ -3,97 +3,145 @@ import {createElement} from '@oscarpalmer/toretto/create';
|
|
|
3
3
|
import {on} from '@oscarpalmer/toretto/event';
|
|
4
4
|
import {findAncestor} from '@oscarpalmer/toretto/find';
|
|
5
5
|
import {isHTMLOrSVGElement} from '@oscarpalmer/toretto/is';
|
|
6
|
+
import {
|
|
7
|
+
createEmbeddedFloatable,
|
|
8
|
+
type OuiFloatable,
|
|
9
|
+
type OuiFloatableOptions,
|
|
10
|
+
} from './floatable/embedded';
|
|
6
11
|
import {attributable} from './internal/attributable';
|
|
7
|
-
import {Floatable, type FloatableOptions} from './floatable';
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
floatable: Floatable;
|
|
13
|
+
// #region Types
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
class OuiTooltip {
|
|
16
|
+
readonly #state: OuiTooltipState;
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
anchor.insertAdjacentElement('afterend', content);
|
|
18
|
+
/**
|
|
19
|
+
* Is the tooltip open?
|
|
20
|
+
*/
|
|
21
|
+
get open(): boolean {
|
|
22
|
+
return this.#state.content.checkVisibility();
|
|
23
|
+
}
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
constructor(state: OuiTooltipState) {
|
|
26
|
+
this.#state = state;
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
state.floatable.update();
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Closes the tooltip
|
|
33
|
+
*/
|
|
34
|
+
hide(): void {
|
|
35
|
+
this.#state.floatable.hide();
|
|
36
|
+
}
|
|
29
37
|
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Opens the tooltip
|
|
40
|
+
*/
|
|
41
|
+
show(): void {
|
|
42
|
+
this.#state.floatable.show();
|
|
32
43
|
}
|
|
33
44
|
}
|
|
34
45
|
|
|
46
|
+
type OuiTooltipState = {
|
|
47
|
+
anchor: HTMLElement;
|
|
48
|
+
content: HTMLElement;
|
|
49
|
+
floatable: OuiFloatable;
|
|
50
|
+
timer?: number;
|
|
51
|
+
tooltip: OuiTooltip;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// #endregion
|
|
55
|
+
|
|
56
|
+
// #region Functions
|
|
57
|
+
|
|
35
58
|
function activate(event: Event, focus: boolean): void {
|
|
36
59
|
const anchor = findAncestor(event, SELECTOR) as HTMLElement | null;
|
|
37
60
|
const content = findAncestor(event, SELECTOR_CONTENT) as HTMLElement | null;
|
|
38
61
|
|
|
39
62
|
if (anchor == null && content == null) {
|
|
40
63
|
if (!focused) {
|
|
41
|
-
closeTooltip(
|
|
64
|
+
closeTooltip(activeState);
|
|
42
65
|
|
|
43
|
-
|
|
66
|
+
activeState = undefined;
|
|
67
|
+
activeTooltip = undefined;
|
|
44
68
|
}
|
|
45
69
|
|
|
46
70
|
return;
|
|
47
71
|
}
|
|
48
72
|
|
|
49
|
-
const
|
|
73
|
+
const state = states.get((anchor ?? content)!);
|
|
50
74
|
|
|
51
|
-
if (
|
|
75
|
+
if (state == null || state.tooltip === activeTooltip) {
|
|
52
76
|
return;
|
|
53
77
|
}
|
|
54
78
|
|
|
55
|
-
const shouldDelay =
|
|
79
|
+
const shouldDelay = activeTooltip == null;
|
|
80
|
+
|
|
81
|
+
closeTooltip(activeState);
|
|
56
82
|
|
|
57
|
-
|
|
83
|
+
activeState = state;
|
|
84
|
+
activeTooltip = state.tooltip;
|
|
58
85
|
|
|
59
|
-
active = instance;
|
|
60
86
|
focused = focus;
|
|
61
87
|
|
|
62
|
-
|
|
88
|
+
state.timer = setTimeout(
|
|
63
89
|
() => {
|
|
64
|
-
|
|
65
|
-
source:
|
|
90
|
+
state.content.showPopover({
|
|
91
|
+
source: state.anchor as HTMLElement,
|
|
66
92
|
});
|
|
67
93
|
|
|
68
94
|
setTimeout(() => {
|
|
69
|
-
|
|
95
|
+
state.floatable.update();
|
|
70
96
|
|
|
71
|
-
|
|
97
|
+
state.content.setAttribute(ATTRIBUTE_CONTENT_OPEN, '');
|
|
72
98
|
});
|
|
73
99
|
},
|
|
74
100
|
shouldDelay ? delay : 0,
|
|
75
101
|
);
|
|
76
102
|
}
|
|
77
103
|
|
|
78
|
-
function
|
|
79
|
-
if (
|
|
104
|
+
function addTooltip(element: HTMLElement): void {
|
|
105
|
+
if (!states.has(element)) {
|
|
106
|
+
createTooltip(element);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function closeTooltip(state?: OuiTooltipState): void {
|
|
111
|
+
if (state == null) {
|
|
80
112
|
return;
|
|
81
113
|
}
|
|
82
114
|
|
|
83
|
-
if (
|
|
84
|
-
clearTimeout(
|
|
115
|
+
if (state.timer != null) {
|
|
116
|
+
clearTimeout(state.timer);
|
|
85
117
|
}
|
|
86
118
|
|
|
87
|
-
|
|
88
|
-
|
|
119
|
+
state.content?.hidePopover();
|
|
120
|
+
state.content?.removeAttribute(ATTRIBUTE_CONTENT_OPEN);
|
|
89
121
|
}
|
|
90
122
|
|
|
91
123
|
function createTooltip(anchor: HTMLElement): void {
|
|
92
124
|
const content = getContent(anchor);
|
|
93
125
|
|
|
94
|
-
if (content
|
|
95
|
-
|
|
126
|
+
if (content == null) {
|
|
127
|
+
return;
|
|
96
128
|
}
|
|
129
|
+
|
|
130
|
+
anchor.insertAdjacentElement('afterend', content);
|
|
131
|
+
|
|
132
|
+
states.set(anchor, getState(anchor, content));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function destroyTooltip(state: OuiTooltipState): void {
|
|
136
|
+
clearTimeout(state.timer);
|
|
137
|
+
|
|
138
|
+
state.content.remove();
|
|
139
|
+
state.floatable.destroy();
|
|
140
|
+
|
|
141
|
+
state.anchor = undefined as never;
|
|
142
|
+
state.content = undefined as never;
|
|
143
|
+
state.floatable = undefined as never;
|
|
144
|
+
state.tooltip = undefined as never;
|
|
97
145
|
}
|
|
98
146
|
|
|
99
147
|
function findElements(attribute: string | null): HTMLElement[] {
|
|
@@ -169,10 +217,21 @@ function getElements(anchor: HTMLElement): HTMLElement[] | undefined {
|
|
|
169
217
|
return [paragraph];
|
|
170
218
|
}
|
|
171
219
|
|
|
172
|
-
function
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
220
|
+
function getState(anchor: HTMLElement, content: HTMLElement): OuiTooltipState {
|
|
221
|
+
const state: OuiTooltipState = {
|
|
222
|
+
anchor,
|
|
223
|
+
content,
|
|
224
|
+
floatable: createEmbeddedFloatable(anchor, content, options),
|
|
225
|
+
tooltip: null as never,
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
state.tooltip = new OuiTooltip(state);
|
|
229
|
+
|
|
230
|
+
return state;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function getTooltip(element: HTMLElement): OuiTooltip | undefined {
|
|
234
|
+
return states.get(element)?.tooltip;
|
|
176
235
|
}
|
|
177
236
|
|
|
178
237
|
function onFocusin(event: Event): void {
|
|
@@ -180,7 +239,7 @@ function onFocusin(event: Event): void {
|
|
|
180
239
|
}
|
|
181
240
|
|
|
182
241
|
function onFocusout(): void {
|
|
183
|
-
if (
|
|
242
|
+
if (activeTooltip == null) {
|
|
184
243
|
return;
|
|
185
244
|
}
|
|
186
245
|
|
|
@@ -190,16 +249,17 @@ function onFocusout(): void {
|
|
|
190
249
|
|
|
191
250
|
focusTimer = setTimeout(() => {
|
|
192
251
|
if (
|
|
193
|
-
|
|
252
|
+
activeTooltip == null ||
|
|
194
253
|
document.activeElement == null ||
|
|
195
254
|
findAncestor(document.activeElement, SELECTOR) != null
|
|
196
255
|
) {
|
|
197
256
|
return;
|
|
198
257
|
}
|
|
199
258
|
|
|
200
|
-
closeTooltip(
|
|
259
|
+
closeTooltip(activeState);
|
|
201
260
|
|
|
202
|
-
|
|
261
|
+
activeState = undefined;
|
|
262
|
+
activeTooltip = undefined;
|
|
203
263
|
});
|
|
204
264
|
}
|
|
205
265
|
|
|
@@ -207,10 +267,16 @@ function onPointermove(event: Event): void {
|
|
|
207
267
|
activate(event, false);
|
|
208
268
|
}
|
|
209
269
|
|
|
210
|
-
function
|
|
211
|
-
|
|
270
|
+
function removeTooltip(element: HTMLElement): void {
|
|
271
|
+
const state = states.get(element);
|
|
272
|
+
|
|
273
|
+
if (state == null) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
destroyTooltip(state);
|
|
212
278
|
|
|
213
|
-
|
|
279
|
+
states.delete(element);
|
|
214
280
|
}
|
|
215
281
|
|
|
216
282
|
/**
|
|
@@ -219,12 +285,16 @@ function onRemove(element: HTMLElement): void {
|
|
|
219
285
|
* _(Default delay is half a second, or 500 milliseconds)_
|
|
220
286
|
* @param value Delay in milliseconds
|
|
221
287
|
*/
|
|
222
|
-
|
|
288
|
+
function setTooltipDelay(value: number): void {
|
|
223
289
|
if (typeof value === 'number' && !Number.isNaN(value) && value >= 0) {
|
|
224
290
|
delay = value;
|
|
225
291
|
}
|
|
226
292
|
}
|
|
227
293
|
|
|
294
|
+
// #endregion
|
|
295
|
+
|
|
296
|
+
// #region Variables
|
|
297
|
+
|
|
228
298
|
const ARIA_DESCRIBEDBY = 'aria-describedby';
|
|
229
299
|
|
|
230
300
|
const ARIA_DESCRIPTION = 'aria-description';
|
|
@@ -241,15 +311,15 @@ const ATTRIBUTE = 'oui-tooltip';
|
|
|
241
311
|
|
|
242
312
|
const ATTRIBUTE_CONTENT = `${ATTRIBUTE}-content`;
|
|
243
313
|
|
|
244
|
-
const
|
|
314
|
+
const ATTRIBUTE_CONTENT_OPEN = `${ATTRIBUTE_CONTENT}-open`;
|
|
245
315
|
|
|
246
316
|
const SELECTOR = `[${ATTRIBUTE}]`;
|
|
247
317
|
|
|
248
318
|
const SELECTOR_CONTENT = `[${ATTRIBUTE_CONTENT}]`;
|
|
249
319
|
|
|
250
|
-
const
|
|
320
|
+
const states = new WeakMap<HTMLElement, OuiTooltipState>();
|
|
251
321
|
|
|
252
|
-
const options:
|
|
322
|
+
const options: OuiFloatableOptions = {
|
|
253
323
|
attribute: `${ATTRIBUTE}-position`,
|
|
254
324
|
position: 'above',
|
|
255
325
|
};
|
|
@@ -258,12 +328,26 @@ let delay = 500;
|
|
|
258
328
|
|
|
259
329
|
let focused = false;
|
|
260
330
|
|
|
261
|
-
let
|
|
331
|
+
let activeState: OuiTooltipState | undefined;
|
|
332
|
+
|
|
333
|
+
let activeTooltip: OuiTooltip | undefined;
|
|
262
334
|
|
|
263
335
|
let focusTimer: number | undefined;
|
|
264
336
|
|
|
337
|
+
// #endregion
|
|
338
|
+
|
|
339
|
+
// #region Initialization
|
|
340
|
+
|
|
265
341
|
on(document, 'focusin', onFocusin);
|
|
266
342
|
on(document, 'focusout', onFocusout);
|
|
267
343
|
on(document, 'pointermove', onPointermove);
|
|
268
344
|
|
|
269
|
-
attributable(ATTRIBUTE,
|
|
345
|
+
attributable(ATTRIBUTE, addTooltip, removeTooltip);
|
|
346
|
+
|
|
347
|
+
// #endregion
|
|
348
|
+
|
|
349
|
+
// #region Exports
|
|
350
|
+
|
|
351
|
+
export {getTooltip, setTooltipDelay, type OuiTooltip};
|
|
352
|
+
|
|
353
|
+
// #endregion
|
package/dist/css/popover.css
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
:where([oui-popover-content]) {
|
|
3
|
-
box-shadow: inset 0 1px 0 0 transparent, 0 0 0 1px rgba(0, 0, 0, 0.05), 0 1px 2px -0.5px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.05), 0 4px 8px -2px rgba(0, 0, 0, 0.05), 0 8px 16px -4px rgba(0, 0, 0, 0.05), 0 16px 32px -8px rgba(0, 0, 0, 0.05), 0 32px 64px -16px rgba(0, 0, 0, 0.05), 0 64px 128px -32px rgba(0, 0, 0, 0.05);
|
|
4
|
-
--margin-bottom: 0.5em;
|
|
5
|
-
--margin-left: 0.5em;
|
|
6
|
-
--margin-right: 0.5em;
|
|
7
|
-
--margin-top: 0.5em;
|
|
8
|
-
inset-block: var(--margin-top) var(--margin-bottom);
|
|
9
|
-
inset-inline: var(--margin-left) var(--margin-right);
|
|
10
|
-
}
|
|
11
|
-
:where([oui-popover-content])[oui-position$=bottom] {
|
|
12
|
-
--margin-bottom: 0;
|
|
13
|
-
}
|
|
14
|
-
:where([oui-popover-content])[oui-position$=end] {
|
|
15
|
-
--margin-right: 0;
|
|
16
|
-
}
|
|
17
|
-
:where([oui-popover-content])[oui-position$=start] {
|
|
18
|
-
--margin-left: 0;
|
|
19
|
-
}
|
|
20
|
-
:where([oui-popover-content])[oui-position$=top] {
|
|
21
|
-
--margin-top: 0;
|
|
22
|
-
}
|
|
23
|
-
:where([oui-popover-content]) {
|
|
24
|
-
padding: 1rem;
|
|
25
|
-
background-color: var(--oui-absolute);
|
|
26
|
-
border: none;
|
|
27
|
-
border-radius: 0.25rem;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
package/dist/js/floatable.d.mts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
//#region src/js/floatable.d.ts
|
|
2
|
-
declare class Floatable {
|
|
3
|
-
#private;
|
|
4
|
-
anchor: HTMLElement;
|
|
5
|
-
content: HTMLElement;
|
|
6
|
-
options: FloatableOptions;
|
|
7
|
-
/**
|
|
8
|
-
* Is the _Floatable_ open?
|
|
9
|
-
*/
|
|
10
|
-
get open(): boolean;
|
|
11
|
-
constructor(anchor: HTMLElement, content: HTMLElement, options: FloatableOptions, standalone: boolean);
|
|
12
|
-
/**
|
|
13
|
-
* Destroy the floatable, removing it from the DOM and cleaning up references
|
|
14
|
-
*/
|
|
15
|
-
destroy(): void;
|
|
16
|
-
/**
|
|
17
|
-
* Hide the floatable
|
|
18
|
-
*/
|
|
19
|
-
hide(): void;
|
|
20
|
-
/**
|
|
21
|
-
* Show the floatable
|
|
22
|
-
*/
|
|
23
|
-
show(): void;
|
|
24
|
-
/**
|
|
25
|
-
* Update the position of the floatable, with an optional new position
|
|
26
|
-
*
|
|
27
|
-
* @param position Optional new position
|
|
28
|
-
*/
|
|
29
|
-
update(position?: FloatablePosition): void;
|
|
30
|
-
}
|
|
31
|
-
type FloatableOptions = {
|
|
32
|
-
attribute?: string;
|
|
33
|
-
position: FloatablePosition;
|
|
34
|
-
};
|
|
35
|
-
type FloatablePosition = 'above' | 'above-end' | 'above-start' | 'below' | 'below-end' | 'below-start' | 'end' | 'end-bottom' | 'end-top' | 'start' | 'start-bottom' | 'start-top';
|
|
36
|
-
type GetFloatableOptions = {
|
|
37
|
-
/**
|
|
38
|
-
* Open the _Floatable_ when created? _(defaults to `true`)_
|
|
39
|
-
*/
|
|
40
|
-
open?: boolean;
|
|
41
|
-
/**
|
|
42
|
-
* Position of the _Floatable_ _(defaults to `below`)_
|
|
43
|
-
*/
|
|
44
|
-
position?: FloatablePosition;
|
|
45
|
-
};
|
|
46
|
-
declare function createFloatable(anchor: HTMLElement, content: HTMLElement, options: FloatableOptions, standalone: boolean): Floatable;
|
|
47
|
-
/**
|
|
48
|
-
* Create a _Floatable_ for an anchor and content element
|
|
49
|
-
*
|
|
50
|
-
* @param anchor Anchor element
|
|
51
|
-
* @param content Content element
|
|
52
|
-
* @param options _Floatable_ options
|
|
53
|
-
* @returns _Floatable_ instance
|
|
54
|
-
*/
|
|
55
|
-
declare function getFloatable(anchor: HTMLElement | SVGElement, content: HTMLElement | SVGElement, options?: GetFloatableOptions): Floatable;
|
|
56
|
-
declare function removeFloatable(content: HTMLElement): void;
|
|
57
|
-
declare const ATTRIBUTE_FLOATABLE = "oui-floatable";
|
|
58
|
-
//#endregion
|
|
59
|
-
export { ATTRIBUTE_FLOATABLE, Floatable, FloatableOptions, FloatablePosition, createFloatable, getFloatable, removeFloatable };
|
package/dist/js/floatable.mjs
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
2
|
-
import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
|
|
3
|
-
//#region src/js/floatable.ts
|
|
4
|
-
var Floatable = class {
|
|
5
|
-
anchor;
|
|
6
|
-
content;
|
|
7
|
-
options;
|
|
8
|
-
#destroyed = false;
|
|
9
|
-
/**
|
|
10
|
-
* Is the _Floatable_ open?
|
|
11
|
-
*/
|
|
12
|
-
get open() {
|
|
13
|
-
return this.content.checkVisibility();
|
|
14
|
-
}
|
|
15
|
-
constructor(anchor, content, options, standalone) {
|
|
16
|
-
this.anchor = anchor;
|
|
17
|
-
this.content = content;
|
|
18
|
-
this.options = options;
|
|
19
|
-
if (standalone) {
|
|
20
|
-
content.setAttribute(ATTRIBUTE_FLOATABLE, "");
|
|
21
|
-
content.popover = "manual";
|
|
22
|
-
}
|
|
23
|
-
const anchorName = getAnchorName(anchor);
|
|
24
|
-
anchor.style.anchorName = anchorName;
|
|
25
|
-
content.style.positionAnchor = anchorName;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Destroy the floatable, removing it from the DOM and cleaning up references
|
|
29
|
-
*/
|
|
30
|
-
destroy() {
|
|
31
|
-
if (this.#destroyed) return;
|
|
32
|
-
this.#destroyed = true;
|
|
33
|
-
removeFloatable(this.content);
|
|
34
|
-
this.anchor = null;
|
|
35
|
-
this.content = null;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Hide the floatable
|
|
39
|
-
*/
|
|
40
|
-
hide() {
|
|
41
|
-
if (!this.#destroyed) this.content.hidePopover();
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Show the floatable
|
|
45
|
-
*/
|
|
46
|
-
show() {
|
|
47
|
-
if (!this.#destroyed) this.content.showPopover();
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Update the position of the floatable, with an optional new position
|
|
51
|
-
*
|
|
52
|
-
* @param position Optional new position
|
|
53
|
-
*/
|
|
54
|
-
update(position) {
|
|
55
|
-
if (!this.#destroyed) setPosition(this, position);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
function createFloatable(anchor, content, options, standalone) {
|
|
59
|
-
if (!isHTMLOrSVGElement(anchor) || !isHTMLOrSVGElement(content)) throw new TypeError("Anchor and content must be an HTMLElement or SVGElement.");
|
|
60
|
-
let floatable = instances.get(content);
|
|
61
|
-
if (floatable == null) {
|
|
62
|
-
floatable = new Floatable(anchor, content, options, standalone);
|
|
63
|
-
instances.set(content, floatable);
|
|
64
|
-
}
|
|
65
|
-
return floatable;
|
|
66
|
-
}
|
|
67
|
-
function getAnchorName(anchor) {
|
|
68
|
-
let { anchorName } = anchor.style;
|
|
69
|
-
if (anchorName.length > 0) return anchorName;
|
|
70
|
-
index += 1;
|
|
71
|
-
return `--oui-floatable-anchor-${index}`;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Create a _Floatable_ for an anchor and content element
|
|
75
|
-
*
|
|
76
|
-
* @param anchor Anchor element
|
|
77
|
-
* @param content Content element
|
|
78
|
-
* @param options _Floatable_ options
|
|
79
|
-
* @returns _Floatable_ instance
|
|
80
|
-
*/
|
|
81
|
-
function getFloatable(anchor, content, options) {
|
|
82
|
-
const { open, position } = getOptions(options);
|
|
83
|
-
const floatable = createFloatable(anchor, content, { position }, true);
|
|
84
|
-
floatable?.update(position);
|
|
85
|
-
if (open) floatable?.show();
|
|
86
|
-
return floatable;
|
|
87
|
-
}
|
|
88
|
-
function getOptions(input) {
|
|
89
|
-
const object = isPlainObject(input) ? input : {};
|
|
90
|
-
return {
|
|
91
|
-
open: typeof object.open === "boolean" ? object.open : true,
|
|
92
|
-
position: object.position != null && object.position in AREAS ? object.position : "below"
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
function getPosition(floatable, override) {
|
|
96
|
-
if (override != null && override in AREAS) return override;
|
|
97
|
-
if (floatable.options.attribute == null) return floatable.options.position;
|
|
98
|
-
const attribute = floatable.anchor.getAttribute(floatable.options.attribute) ?? "";
|
|
99
|
-
return attribute in AREAS ? attribute : floatable.options.position;
|
|
100
|
-
}
|
|
101
|
-
function removeFloatable(content) {
|
|
102
|
-
instances.get(content)?.destroy();
|
|
103
|
-
instances.delete(content);
|
|
104
|
-
}
|
|
105
|
-
function setPosition(floatable, override) {
|
|
106
|
-
const area = AREAS[getPosition(floatable, override)];
|
|
107
|
-
floatable.content.style.positionArea = area;
|
|
108
|
-
floatable.content.setAttribute(ATTRIBUTE_POSITION, POSITIONS[area]);
|
|
109
|
-
}
|
|
110
|
-
const AREAS = {
|
|
111
|
-
above: "block-start",
|
|
112
|
-
"above-end": "start span-start",
|
|
113
|
-
"above-start": "start span-end",
|
|
114
|
-
below: "block-end",
|
|
115
|
-
"below-end": "end span-start",
|
|
116
|
-
"below-start": "end span-end",
|
|
117
|
-
end: "center end",
|
|
118
|
-
"end-bottom": "span-start end",
|
|
119
|
-
"end-top": "span-end end",
|
|
120
|
-
start: "center start",
|
|
121
|
-
"start-bottom": "span-start start",
|
|
122
|
-
"start-top": "span-end start"
|
|
123
|
-
};
|
|
124
|
-
const ATTRIBUTE_FLOATABLE = "oui-floatable";
|
|
125
|
-
const ATTRIBUTE_POSITION = "oui-position";
|
|
126
|
-
const POSITIONS = Object.fromEntries(Object.entries(AREAS).map(([position, area]) => [area, position]));
|
|
127
|
-
const instances = /* @__PURE__ */ new WeakMap();
|
|
128
|
-
let index = 0;
|
|
129
|
-
//#endregion
|
|
130
|
-
export { ATTRIBUTE_FLOATABLE, Floatable, createFloatable, getFloatable, removeFloatable };
|