@schukai/monster 4.129.4 → 4.129.6
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/package.json +1 -1
- package/source/components/content/copy.mjs +2 -2
- package/source/components/datatable/columnbar.mjs +12 -9
- package/source/components/form/button-bar.mjs +1 -1
- package/source/components/form/util/floating-ui.mjs +12 -611
- package/source/components/form/util/popper.mjs +322 -14
- package/source/components/layout/popper.mjs +2 -2
- package/source/components/layout/tabs.mjs +7 -6
- package/source/components/layout/vertical-tabs.mjs +7 -6
- package/test/cases/components/form/login.mjs +6 -11
- package/test/util/jsdom.mjs +1 -0
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.6"
|
|
1
|
+
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.6"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.129.6"}
|
|
@@ -163,7 +163,7 @@ class Copy extends CustomElement {
|
|
|
163
163
|
* @property {boolean} features.preventOpenEventSent=false Prevent open event from being sent
|
|
164
164
|
* @property {Object} popper Popper configuration
|
|
165
165
|
* @property {string} popper.placement="top" Popper placement
|
|
166
|
-
* @property {string[]} popper.middleware=["
|
|
166
|
+
* @property {string[]} popper.middleware=["flip", "shift", "offset:-1", "arrow"] Popper middleware
|
|
167
167
|
* @property {boolean} disabled=false Disabled state
|
|
168
168
|
*/
|
|
169
169
|
get defaults() {
|
|
@@ -178,7 +178,7 @@ class Copy extends CustomElement {
|
|
|
178
178
|
},
|
|
179
179
|
popper: {
|
|
180
180
|
placement: "top",
|
|
181
|
-
middleware: ["
|
|
181
|
+
middleware: ["flip", "shift", "offset:-1", "arrow"],
|
|
182
182
|
},
|
|
183
183
|
});
|
|
184
184
|
}
|
|
@@ -21,11 +21,14 @@ import {
|
|
|
21
21
|
import { findTargetElementFromEvent } from "../../dom/events.mjs";
|
|
22
22
|
import { clone } from "../../util/clone.mjs";
|
|
23
23
|
import { ColumnBarStyleSheet } from "./stylesheet/column-bar.mjs";
|
|
24
|
-
import { createPopper } from "@popperjs/core";
|
|
25
24
|
import { getLocaleOfDocument } from "../../dom/locale.mjs";
|
|
26
25
|
import { hasObjectLink } from "../../dom/attributes.mjs";
|
|
27
26
|
import { customElementUpdaterLinkSymbol } from "../../dom/constants.mjs";
|
|
28
27
|
import { getGlobalObject } from "../../types/global.mjs";
|
|
28
|
+
import {
|
|
29
|
+
createFloatingPopper,
|
|
30
|
+
popperInstanceSymbol,
|
|
31
|
+
} from "../form/util/popper.mjs";
|
|
29
32
|
|
|
30
33
|
export { ColumnBar };
|
|
31
34
|
|
|
@@ -53,12 +56,6 @@ const settingsLayerElementSymbol = Symbol("settingsLayerElement");
|
|
|
53
56
|
*/
|
|
54
57
|
const dotsContainerElementSymbol = Symbol("dotsContainerElement");
|
|
55
58
|
|
|
56
|
-
/**
|
|
57
|
-
* @private
|
|
58
|
-
* @type {symbol}
|
|
59
|
-
*/
|
|
60
|
-
const popperInstanceSymbol = Symbol("popperInstance");
|
|
61
|
-
|
|
62
59
|
/**
|
|
63
60
|
* @private
|
|
64
61
|
* @type {symbol}
|
|
@@ -226,7 +223,11 @@ class ColumnBar extends CustomElement {
|
|
|
226
223
|
}
|
|
227
224
|
|
|
228
225
|
if (typeof this[dotsFrameRequestSymbol] === "number") {
|
|
229
|
-
|
|
226
|
+
const cancelFrame =
|
|
227
|
+
typeof globalThis.cancelAnimationFrame === "function"
|
|
228
|
+
? globalThis.cancelAnimationFrame.bind(globalThis)
|
|
229
|
+
: globalThis.clearTimeout.bind(globalThis);
|
|
230
|
+
cancelFrame(this[dotsFrameRequestSymbol]);
|
|
230
231
|
this[dotsFrameRequestSymbol] = null;
|
|
231
232
|
}
|
|
232
233
|
|
|
@@ -241,6 +242,8 @@ class ColumnBar extends CustomElement {
|
|
|
241
242
|
);
|
|
242
243
|
this[closeEventHandlerSymbol] = null;
|
|
243
244
|
}
|
|
245
|
+
|
|
246
|
+
this[popperInstanceSymbol]?.destroy();
|
|
244
247
|
}
|
|
245
248
|
|
|
246
249
|
/**
|
|
@@ -350,7 +353,7 @@ function initControlReferences() {
|
|
|
350
353
|
function initEventHandler() {
|
|
351
354
|
const self = this;
|
|
352
355
|
|
|
353
|
-
self[popperInstanceSymbol] =
|
|
356
|
+
self[popperInstanceSymbol] = createFloatingPopper(
|
|
354
357
|
self[settingsButtonElementSymbol],
|
|
355
358
|
self[settingsLayerElementSymbol],
|
|
356
359
|
{
|
|
@@ -19,15 +19,14 @@ import {
|
|
|
19
19
|
computePosition,
|
|
20
20
|
offset,
|
|
21
21
|
flip,
|
|
22
|
+
hide,
|
|
22
23
|
size,
|
|
23
24
|
shift,
|
|
24
25
|
} from "@floating-ui/dom";
|
|
26
|
+
import { isArray, isFunction, isObject, isString } from "../../../types/is.mjs";
|
|
25
27
|
import { Processing } from "../../../util/processing.mjs";
|
|
26
|
-
import { isString, isArray, isObject, isFunction } from "../../../types/is.mjs";
|
|
27
|
-
import { hide } from "@popperjs/core";
|
|
28
28
|
|
|
29
29
|
export {
|
|
30
|
-
canUseNativePositionedPopper,
|
|
31
30
|
closePositionedPopper,
|
|
32
31
|
isPositionedPopperOpen,
|
|
33
32
|
openPositionedPopper,
|
|
@@ -35,9 +34,6 @@ export {
|
|
|
35
34
|
};
|
|
36
35
|
|
|
37
36
|
const autoUpdateCleanupMap = new WeakMap();
|
|
38
|
-
const nativeArrowSyncFrameMap = new WeakMap();
|
|
39
|
-
const anchorNameMap = new WeakMap();
|
|
40
|
-
let anchorNameCounter = 0;
|
|
41
37
|
|
|
42
38
|
/**
|
|
43
39
|
* @private
|
|
@@ -50,15 +46,6 @@ function positionPopper(controlElement, popperElement, options) {
|
|
|
50
46
|
const config = normalizePopperConfig(options);
|
|
51
47
|
|
|
52
48
|
return new Processing(() => {
|
|
53
|
-
if (canUseNativePositionedPopper(controlElement, popperElement, config)) {
|
|
54
|
-
prepareNativePopover(controlElement, popperElement, config);
|
|
55
|
-
startAutoUpdate(controlElement, popperElement, () => {
|
|
56
|
-
syncNativePopover(controlElement, popperElement, config);
|
|
57
|
-
});
|
|
58
|
-
syncNativePopover(controlElement, popperElement, config);
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
49
|
enableFloatingPositioning(controlElement, popperElement, config);
|
|
63
50
|
}).run();
|
|
64
51
|
}
|
|
@@ -66,21 +53,16 @@ function positionPopper(controlElement, popperElement, options) {
|
|
|
66
53
|
function openPositionedPopper(controlElement, popperElement, options) {
|
|
67
54
|
const config = normalizePopperConfig(options);
|
|
68
55
|
|
|
69
|
-
|
|
70
|
-
prepareNativePopover(controlElement, popperElement, config);
|
|
71
|
-
popperElement.style.removeProperty("transform");
|
|
72
|
-
if (!matchesPopoverOpen(popperElement)) {
|
|
73
|
-
popperElement.showPopover();
|
|
74
|
-
}
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
teardownNativePopover(popperElement);
|
|
56
|
+
stopAutoUpdate(popperElement);
|
|
79
57
|
popperElement.style.display = "block";
|
|
58
|
+
popperElement.style.removeProperty("transform");
|
|
59
|
+
|
|
60
|
+
// Keep the call signature stable even though only Floating UI is used now.
|
|
61
|
+
void controlElement;
|
|
62
|
+
void config;
|
|
80
63
|
}
|
|
81
64
|
|
|
82
65
|
function enableFloatingPositioning(controlElement, popperElement, config) {
|
|
83
|
-
teardownNativePopover(popperElement);
|
|
84
66
|
popperElement.style.removeProperty("visibility");
|
|
85
67
|
popperElement.style.display = "block";
|
|
86
68
|
|
|
@@ -122,63 +104,21 @@ function syncFloatingPopover(controlElement, popperElement, config) {
|
|
|
122
104
|
|
|
123
105
|
function closePositionedPopper(popperElement) {
|
|
124
106
|
stopAutoUpdate(popperElement);
|
|
125
|
-
cancelScheduledNativeArrowSync(popperElement);
|
|
126
|
-
|
|
127
|
-
if (isNativePopoverElement(popperElement)) {
|
|
128
|
-
if (matchesPopoverOpen(popperElement)) {
|
|
129
|
-
popperElement.hidePopover();
|
|
130
|
-
}
|
|
131
|
-
popperElement.style.display = "none";
|
|
132
|
-
popperElement.style.removeProperty("visibility");
|
|
133
|
-
popperElement.style.removeProperty("transform");
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
107
|
popperElement.style.display = "none";
|
|
108
|
+
popperElement.style.removeProperty("visibility");
|
|
109
|
+
popperElement.style.removeProperty("transform");
|
|
138
110
|
}
|
|
139
111
|
|
|
140
112
|
function isPositionedPopperOpen(popperElement) {
|
|
141
|
-
if (isNativePopoverElement(popperElement)) {
|
|
142
|
-
return matchesPopoverOpen(popperElement);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
113
|
return popperElement.style.display === "block";
|
|
146
114
|
}
|
|
147
115
|
|
|
148
|
-
function canUseNativePositionedPopper(controlElement, popperElement, options) {
|
|
149
|
-
if (!(controlElement instanceof HTMLElement)) {
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (!(popperElement instanceof HTMLElement)) {
|
|
154
|
-
return false;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (options?.engine !== "native") {
|
|
158
|
-
return false;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (!("showPopover" in HTMLElement.prototype)) {
|
|
162
|
-
return false;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (typeof CSS === "undefined") {
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return (
|
|
170
|
-
CSS.supports("anchor-name: --monster-popper-anchor") &&
|
|
171
|
-
CSS.supports("position-anchor: --monster-popper-anchor") &&
|
|
172
|
-
CSS.supports("top: anchor(bottom)")
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
116
|
function normalizePopperConfig(options) {
|
|
177
117
|
const config = Object.assign(
|
|
178
118
|
{},
|
|
179
119
|
{
|
|
180
120
|
placement: "top",
|
|
181
|
-
engine: "
|
|
121
|
+
engine: "floating",
|
|
182
122
|
},
|
|
183
123
|
options,
|
|
184
124
|
);
|
|
@@ -194,7 +134,7 @@ function normalizePopperConfig(options) {
|
|
|
194
134
|
}
|
|
195
135
|
|
|
196
136
|
function normalizeMiddleware(config) {
|
|
197
|
-
const middleware = config?.
|
|
137
|
+
const middleware = config?.middleware;
|
|
198
138
|
if (isArray(middleware)) {
|
|
199
139
|
return [...middleware];
|
|
200
140
|
}
|
|
@@ -299,499 +239,6 @@ function stopAutoUpdate(popperElement) {
|
|
|
299
239
|
autoUpdateCleanupMap.delete(popperElement);
|
|
300
240
|
}
|
|
301
241
|
|
|
302
|
-
function scheduleNativeArrowSync(controlElement, popperElement) {
|
|
303
|
-
cancelScheduledNativeArrowSync(popperElement);
|
|
304
|
-
|
|
305
|
-
const frameState = {
|
|
306
|
-
outer: 0,
|
|
307
|
-
inner: 0,
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
frameState.outer = requestAnimationFrame(() => {
|
|
311
|
-
frameState.inner = requestAnimationFrame(() => {
|
|
312
|
-
nativeArrowSyncFrameMap.delete(popperElement);
|
|
313
|
-
|
|
314
|
-
if (
|
|
315
|
-
!(controlElement instanceof HTMLElement) ||
|
|
316
|
-
!(popperElement instanceof HTMLElement) ||
|
|
317
|
-
!isNativePopoverElement(popperElement)
|
|
318
|
-
) {
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if (
|
|
323
|
-
!matchesPopoverOpen(popperElement) &&
|
|
324
|
-
popperElement.style.display !== "block"
|
|
325
|
-
) {
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
syncNativeArrow(controlElement, popperElement);
|
|
330
|
-
});
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
nativeArrowSyncFrameMap.set(popperElement, frameState);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
function cancelScheduledNativeArrowSync(popperElement) {
|
|
337
|
-
const frameState = nativeArrowSyncFrameMap.get(popperElement);
|
|
338
|
-
if (!frameState) {
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
if (frameState.outer) {
|
|
343
|
-
cancelAnimationFrame(frameState.outer);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
if (frameState.inner) {
|
|
347
|
-
cancelAnimationFrame(frameState.inner);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
nativeArrowSyncFrameMap.delete(popperElement);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
function prepareNativePopover(controlElement, popperElement, config) {
|
|
354
|
-
const anchorName = getAnchorName(controlElement);
|
|
355
|
-
popperElement.dataset.monsterPopperEngine = "native";
|
|
356
|
-
popperElement.setAttribute("popover", "manual");
|
|
357
|
-
controlElement.style.setProperty("anchor-name", anchorName);
|
|
358
|
-
popperElement.style.setProperty("position-anchor", anchorName);
|
|
359
|
-
popperElement.style.setProperty("inset", "auto");
|
|
360
|
-
popperElement.style.setProperty("margin", "0");
|
|
361
|
-
popperElement.style.setProperty("overflow", "visible");
|
|
362
|
-
popperElement.style.display = "block";
|
|
363
|
-
popperElement.style.removeProperty("transform");
|
|
364
|
-
applyNativeTryFallbacks(popperElement, config);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
function teardownNativePopover(popperElement) {
|
|
368
|
-
if (!isNativePopoverElement(popperElement)) {
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
if (matchesPopoverOpen(popperElement)) {
|
|
373
|
-
popperElement.hidePopover();
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
cancelScheduledNativeArrowSync(popperElement);
|
|
377
|
-
delete popperElement.dataset.monsterPopperEngine;
|
|
378
|
-
popperElement.removeAttribute("popover");
|
|
379
|
-
popperElement.style.removeProperty("position-anchor");
|
|
380
|
-
popperElement.style.removeProperty("position-area");
|
|
381
|
-
popperElement.style.removeProperty("inset-area");
|
|
382
|
-
popperElement.style.removeProperty("position-try");
|
|
383
|
-
popperElement.style.removeProperty("position-try-fallbacks");
|
|
384
|
-
popperElement.style.removeProperty("margin");
|
|
385
|
-
popperElement.style.removeProperty("margin-top");
|
|
386
|
-
popperElement.style.removeProperty("margin-right");
|
|
387
|
-
popperElement.style.removeProperty("margin-bottom");
|
|
388
|
-
popperElement.style.removeProperty("margin-left");
|
|
389
|
-
popperElement.style.removeProperty("inset");
|
|
390
|
-
popperElement.style.removeProperty("overflow");
|
|
391
|
-
popperElement.style.removeProperty("--monster-popper-control-width");
|
|
392
|
-
popperElement.style.removeProperty("--monster-popper-control-height");
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
function syncNativePopover(controlElement, popperElement, config) {
|
|
396
|
-
const controlRect = controlElement.getBoundingClientRect();
|
|
397
|
-
const placement = resolvePlacement(config.placement);
|
|
398
|
-
const offsetValue = resolveOffset(config.middlewareTokens);
|
|
399
|
-
|
|
400
|
-
popperElement.style.setProperty(
|
|
401
|
-
"--monster-popper-control-width",
|
|
402
|
-
`${Math.round(controlRect.width)}px`,
|
|
403
|
-
);
|
|
404
|
-
popperElement.style.setProperty(
|
|
405
|
-
"--monster-popper-control-height",
|
|
406
|
-
`${Math.round(controlRect.height)}px`,
|
|
407
|
-
);
|
|
408
|
-
|
|
409
|
-
applyNativePlacementStyles(popperElement, placement, offsetValue);
|
|
410
|
-
popperElement.style.removeProperty("visibility");
|
|
411
|
-
|
|
412
|
-
if (hasViewportOverflow(popperElement)) {
|
|
413
|
-
enableFloatingPositioning(controlElement, popperElement, config);
|
|
414
|
-
return;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
syncNativeArrow(controlElement, popperElement);
|
|
418
|
-
scheduleNativeArrowSync(controlElement, popperElement);
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
function resolvePlacement(value) {
|
|
422
|
-
if (!isString(value) || value.trim().length === 0) {
|
|
423
|
-
return { side: "top", align: "center" };
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
const [rawSide, rawAlign] = value.split("-");
|
|
427
|
-
const side = rawSide === "auto" ? "top" : rawSide;
|
|
428
|
-
const align =
|
|
429
|
-
rawAlign === "start" || rawAlign === "end" ? rawAlign : "center";
|
|
430
|
-
|
|
431
|
-
if (!["top", "bottom", "left", "right"].includes(side)) {
|
|
432
|
-
return { side: "top", align: "center" };
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
return { side, align };
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
function resolveOffset(middleware) {
|
|
439
|
-
if (!isArray(middleware)) {
|
|
440
|
-
return 10;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
for (const entry of middleware) {
|
|
444
|
-
if (!isString(entry) || !entry.startsWith("offset")) {
|
|
445
|
-
continue;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
const [, rawValue] = entry.split(":");
|
|
449
|
-
const parsed = parseInt(rawValue);
|
|
450
|
-
if (Number.isFinite(parsed)) {
|
|
451
|
-
return parsed;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
return 10;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
function applyNativePlacementStyles(
|
|
459
|
-
popperElement,
|
|
460
|
-
{ side, align },
|
|
461
|
-
offsetValue,
|
|
462
|
-
) {
|
|
463
|
-
if (supportsNativePositionArea()) {
|
|
464
|
-
applyNativePositionAreaStyles(popperElement, { side, align }, offsetValue);
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
popperElement.style.removeProperty("position-area");
|
|
469
|
-
popperElement.style.removeProperty("inset-area");
|
|
470
|
-
popperElement.style.removeProperty("margin-top");
|
|
471
|
-
popperElement.style.removeProperty("margin-right");
|
|
472
|
-
popperElement.style.removeProperty("margin-bottom");
|
|
473
|
-
popperElement.style.removeProperty("margin-left");
|
|
474
|
-
popperElement.style.removeProperty("top");
|
|
475
|
-
popperElement.style.removeProperty("right");
|
|
476
|
-
popperElement.style.removeProperty("bottom");
|
|
477
|
-
popperElement.style.removeProperty("left");
|
|
478
|
-
|
|
479
|
-
switch (side) {
|
|
480
|
-
case "bottom":
|
|
481
|
-
popperElement.style.setProperty(
|
|
482
|
-
"top",
|
|
483
|
-
`calc(anchor(bottom) + ${offsetValue}px)`,
|
|
484
|
-
);
|
|
485
|
-
applyHorizontalAlignment(popperElement, align);
|
|
486
|
-
break;
|
|
487
|
-
case "left":
|
|
488
|
-
popperElement.style.setProperty(
|
|
489
|
-
"left",
|
|
490
|
-
`calc(anchor(left) - 100% - ${offsetValue}px)`,
|
|
491
|
-
);
|
|
492
|
-
applyVerticalAlignment(popperElement, align);
|
|
493
|
-
break;
|
|
494
|
-
case "right":
|
|
495
|
-
popperElement.style.setProperty(
|
|
496
|
-
"left",
|
|
497
|
-
`calc(anchor(right) + ${offsetValue}px)`,
|
|
498
|
-
);
|
|
499
|
-
applyVerticalAlignment(popperElement, align);
|
|
500
|
-
break;
|
|
501
|
-
case "top":
|
|
502
|
-
default:
|
|
503
|
-
popperElement.style.setProperty(
|
|
504
|
-
"top",
|
|
505
|
-
`calc(anchor(top) - 100% - ${offsetValue}px)`,
|
|
506
|
-
);
|
|
507
|
-
applyHorizontalAlignment(popperElement, align);
|
|
508
|
-
break;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
function applyNativePositionAreaStyles(
|
|
513
|
-
popperElement,
|
|
514
|
-
{ side, align },
|
|
515
|
-
offsetValue,
|
|
516
|
-
) {
|
|
517
|
-
const positionArea = resolveNativePositionArea({ side, align });
|
|
518
|
-
|
|
519
|
-
popperElement.style.removeProperty("top");
|
|
520
|
-
popperElement.style.removeProperty("right");
|
|
521
|
-
popperElement.style.removeProperty("bottom");
|
|
522
|
-
popperElement.style.removeProperty("left");
|
|
523
|
-
popperElement.style.setProperty("position-area", positionArea);
|
|
524
|
-
popperElement.style.setProperty("inset-area", positionArea);
|
|
525
|
-
popperElement.style.setProperty("margin-top", "0px");
|
|
526
|
-
popperElement.style.setProperty("margin-right", "0px");
|
|
527
|
-
popperElement.style.setProperty("margin-bottom", "0px");
|
|
528
|
-
popperElement.style.setProperty("margin-left", "0px");
|
|
529
|
-
|
|
530
|
-
switch (side) {
|
|
531
|
-
case "bottom":
|
|
532
|
-
popperElement.style.setProperty("margin-top", `${offsetValue}px`);
|
|
533
|
-
break;
|
|
534
|
-
case "left":
|
|
535
|
-
popperElement.style.setProperty("margin-right", `${offsetValue}px`);
|
|
536
|
-
break;
|
|
537
|
-
case "right":
|
|
538
|
-
popperElement.style.setProperty("margin-left", `${offsetValue}px`);
|
|
539
|
-
break;
|
|
540
|
-
case "top":
|
|
541
|
-
default:
|
|
542
|
-
popperElement.style.setProperty("margin-bottom", `${offsetValue}px`);
|
|
543
|
-
break;
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
function resolveNativePositionArea({ side, align }) {
|
|
548
|
-
switch (side) {
|
|
549
|
-
case "bottom":
|
|
550
|
-
switch (align) {
|
|
551
|
-
case "end":
|
|
552
|
-
return "bottom span-left";
|
|
553
|
-
case "center":
|
|
554
|
-
return "bottom center";
|
|
555
|
-
case "start":
|
|
556
|
-
default:
|
|
557
|
-
return "bottom span-right";
|
|
558
|
-
}
|
|
559
|
-
case "left":
|
|
560
|
-
switch (align) {
|
|
561
|
-
case "end":
|
|
562
|
-
return "left span-top";
|
|
563
|
-
case "center":
|
|
564
|
-
return "left center";
|
|
565
|
-
case "start":
|
|
566
|
-
default:
|
|
567
|
-
return "left span-bottom";
|
|
568
|
-
}
|
|
569
|
-
case "right":
|
|
570
|
-
switch (align) {
|
|
571
|
-
case "end":
|
|
572
|
-
return "right span-top";
|
|
573
|
-
case "center":
|
|
574
|
-
return "right center";
|
|
575
|
-
case "start":
|
|
576
|
-
default:
|
|
577
|
-
return "right span-bottom";
|
|
578
|
-
}
|
|
579
|
-
case "top":
|
|
580
|
-
default:
|
|
581
|
-
switch (align) {
|
|
582
|
-
case "end":
|
|
583
|
-
return "top span-left";
|
|
584
|
-
case "center":
|
|
585
|
-
return "top center";
|
|
586
|
-
case "start":
|
|
587
|
-
default:
|
|
588
|
-
return "top span-right";
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
function supportsNativePositionArea() {
|
|
594
|
-
if (typeof CSS === "undefined") {
|
|
595
|
-
return false;
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
return (
|
|
599
|
-
CSS.supports("position-area: bottom center") ||
|
|
600
|
-
CSS.supports("inset-area: bottom center")
|
|
601
|
-
);
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
function applyHorizontalAlignment(popperElement, align) {
|
|
605
|
-
switch (align) {
|
|
606
|
-
case "end":
|
|
607
|
-
popperElement.style.setProperty("left", "calc(anchor(right) - 100%)");
|
|
608
|
-
break;
|
|
609
|
-
case "center":
|
|
610
|
-
popperElement.style.setProperty(
|
|
611
|
-
"left",
|
|
612
|
-
"calc(anchor(left) + (var(--monster-popper-control-width) - 100%) / 2)",
|
|
613
|
-
);
|
|
614
|
-
break;
|
|
615
|
-
case "start":
|
|
616
|
-
default:
|
|
617
|
-
popperElement.style.setProperty("left", "anchor(left)");
|
|
618
|
-
break;
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
function applyVerticalAlignment(popperElement, align) {
|
|
623
|
-
switch (align) {
|
|
624
|
-
case "end":
|
|
625
|
-
popperElement.style.setProperty("top", "calc(anchor(bottom) - 100%)");
|
|
626
|
-
break;
|
|
627
|
-
case "center":
|
|
628
|
-
popperElement.style.setProperty(
|
|
629
|
-
"top",
|
|
630
|
-
"calc(anchor(top) + (var(--monster-popper-control-height) - 100%) / 2)",
|
|
631
|
-
);
|
|
632
|
-
break;
|
|
633
|
-
case "start":
|
|
634
|
-
default:
|
|
635
|
-
popperElement.style.setProperty("top", "anchor(top)");
|
|
636
|
-
break;
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
function applyNativeTryFallbacks(popperElement, config) {
|
|
641
|
-
const middleware = config.middlewareTokens || [];
|
|
642
|
-
const placement = resolvePlacement(config.placement);
|
|
643
|
-
let fallbacks = "";
|
|
644
|
-
|
|
645
|
-
if (
|
|
646
|
-
middleware.some(
|
|
647
|
-
(entry) => isString(entry) && entry.startsWith("autoPlacement"),
|
|
648
|
-
)
|
|
649
|
-
) {
|
|
650
|
-
fallbacks =
|
|
651
|
-
placement.side === "left" || placement.side === "right"
|
|
652
|
-
? "flip-inline, flip-block"
|
|
653
|
-
: "flip-block, flip-inline";
|
|
654
|
-
} else if (middleware.includes("flip")) {
|
|
655
|
-
fallbacks =
|
|
656
|
-
placement.side === "left" || placement.side === "right"
|
|
657
|
-
? "flip-inline"
|
|
658
|
-
: "flip-block";
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
if (fallbacks.length === 0) {
|
|
662
|
-
popperElement.style.removeProperty("position-try");
|
|
663
|
-
popperElement.style.removeProperty("position-try-fallbacks");
|
|
664
|
-
return;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
popperElement.style.setProperty("position-try", fallbacks);
|
|
668
|
-
popperElement.style.setProperty("position-try-fallbacks", fallbacks);
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
function syncNativeArrow(controlElement, popperElement) {
|
|
672
|
-
const arrowElement = popperElement.querySelector("[data-monster-role=arrow]");
|
|
673
|
-
|
|
674
|
-
if (!(arrowElement instanceof HTMLElement)) {
|
|
675
|
-
return;
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
const controlRect = controlElement.getBoundingClientRect();
|
|
679
|
-
const popperRect = popperElement.getBoundingClientRect();
|
|
680
|
-
const arrowHalf = arrowElement.offsetWidth / 2;
|
|
681
|
-
|
|
682
|
-
if (arrowHalf === 0) {
|
|
683
|
-
return;
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
const side = resolveArrowSide(controlRect, popperRect);
|
|
687
|
-
const staticSide = side;
|
|
688
|
-
const defaultBorder =
|
|
689
|
-
"var(--monster-border-width) var(--monster-border-style) var(--monster-bg-color-primary-4)";
|
|
690
|
-
const borderStyle = {
|
|
691
|
-
borderLeft: "transparent",
|
|
692
|
-
borderRight: "transparent",
|
|
693
|
-
borderBottom: "transparent",
|
|
694
|
-
borderTop: "transparent",
|
|
695
|
-
};
|
|
696
|
-
|
|
697
|
-
switch (side) {
|
|
698
|
-
case "top":
|
|
699
|
-
borderStyle.borderTop = defaultBorder;
|
|
700
|
-
borderStyle.borderLeft = defaultBorder;
|
|
701
|
-
break;
|
|
702
|
-
case "bottom":
|
|
703
|
-
borderStyle.borderRight = defaultBorder;
|
|
704
|
-
borderStyle.borderBottom = defaultBorder;
|
|
705
|
-
break;
|
|
706
|
-
case "left":
|
|
707
|
-
borderStyle.borderLeft = defaultBorder;
|
|
708
|
-
borderStyle.borderBottom = defaultBorder;
|
|
709
|
-
break;
|
|
710
|
-
case "right":
|
|
711
|
-
borderStyle.borderTop = defaultBorder;
|
|
712
|
-
borderStyle.borderRight = defaultBorder;
|
|
713
|
-
break;
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
const arrowOffset = resolveArrowOffset(
|
|
717
|
-
side,
|
|
718
|
-
controlRect,
|
|
719
|
-
popperRect,
|
|
720
|
-
arrowHalf,
|
|
721
|
-
);
|
|
722
|
-
const arrowLen = arrowElement.offsetWidth + 4;
|
|
723
|
-
|
|
724
|
-
Object.assign(
|
|
725
|
-
arrowElement.style,
|
|
726
|
-
{
|
|
727
|
-
left: side === "top" || side === "bottom" ? `${arrowOffset}px` : "",
|
|
728
|
-
top: side === "left" || side === "right" ? `${arrowOffset}px` : "",
|
|
729
|
-
right: "",
|
|
730
|
-
bottom: "",
|
|
731
|
-
[staticSide]: `${-arrowLen / 2}px`,
|
|
732
|
-
transform: "rotate(45deg)",
|
|
733
|
-
},
|
|
734
|
-
borderStyle,
|
|
735
|
-
);
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
function resolveArrowSide(controlRect, popperRect) {
|
|
739
|
-
const triggerCenterX = controlRect.left + controlRect.width / 2;
|
|
740
|
-
const triggerCenterY = controlRect.top + controlRect.height / 2;
|
|
741
|
-
const candidates = [];
|
|
742
|
-
|
|
743
|
-
if (triggerCenterY <= popperRect.top) {
|
|
744
|
-
candidates.push({
|
|
745
|
-
side: "top",
|
|
746
|
-
distance: popperRect.top - triggerCenterY,
|
|
747
|
-
});
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
if (triggerCenterY >= popperRect.bottom) {
|
|
751
|
-
candidates.push({
|
|
752
|
-
side: "bottom",
|
|
753
|
-
distance: triggerCenterY - popperRect.bottom,
|
|
754
|
-
});
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
if (triggerCenterX <= popperRect.left) {
|
|
758
|
-
candidates.push({
|
|
759
|
-
side: "left",
|
|
760
|
-
distance: popperRect.left - triggerCenterX,
|
|
761
|
-
});
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
if (triggerCenterX >= popperRect.right) {
|
|
765
|
-
candidates.push({
|
|
766
|
-
side: "right",
|
|
767
|
-
distance: triggerCenterX - popperRect.right,
|
|
768
|
-
});
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
if (candidates.length === 0) {
|
|
772
|
-
return "top";
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
candidates.sort((a, b) => a.distance - b.distance);
|
|
776
|
-
return candidates[0].side;
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
function resolveArrowOffset(side, controlRect, popperRect, arrowHalf) {
|
|
780
|
-
if (side === "top" || side === "bottom") {
|
|
781
|
-
return clamp(
|
|
782
|
-
controlRect.left + controlRect.width / 2 - popperRect.left - arrowHalf,
|
|
783
|
-
0,
|
|
784
|
-
Math.max(0, popperRect.width - arrowHalf * 2),
|
|
785
|
-
);
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
return clamp(
|
|
789
|
-
controlRect.top + controlRect.height / 2 - popperRect.top - arrowHalf,
|
|
790
|
-
0,
|
|
791
|
-
Math.max(0, popperRect.height - arrowHalf * 2),
|
|
792
|
-
);
|
|
793
|
-
}
|
|
794
|
-
|
|
795
242
|
function applyFloatingArrowStyles(arrowElement, placement, arrowData) {
|
|
796
243
|
if (!(arrowElement instanceof HTMLElement)) {
|
|
797
244
|
return;
|
|
@@ -847,52 +294,6 @@ function applyFloatingArrowStyles(arrowElement, placement, arrowData) {
|
|
|
847
294
|
);
|
|
848
295
|
}
|
|
849
296
|
|
|
850
|
-
function getAnchorName(controlElement) {
|
|
851
|
-
if (!anchorNameMap.has(controlElement)) {
|
|
852
|
-
anchorNameCounter += 1;
|
|
853
|
-
anchorNameMap.set(
|
|
854
|
-
controlElement,
|
|
855
|
-
`--monster-popper-anchor-${anchorNameCounter}`,
|
|
856
|
-
);
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
return anchorNameMap.get(controlElement);
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
function isNativePopoverElement(popperElement) {
|
|
863
|
-
return popperElement?.dataset?.monsterPopperEngine === "native";
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
function matchesPopoverOpen(popperElement) {
|
|
867
|
-
try {
|
|
868
|
-
return popperElement.matches(":popover-open");
|
|
869
|
-
} catch (e) {
|
|
870
|
-
return false;
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
function hasViewportOverflow(popperElement) {
|
|
875
|
-
if (!(popperElement instanceof HTMLElement)) {
|
|
876
|
-
return false;
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
const rect = popperElement.getBoundingClientRect();
|
|
880
|
-
const tolerance = 1;
|
|
881
|
-
const viewportWidth = window.innerWidth;
|
|
882
|
-
const viewportHeight = window.innerHeight;
|
|
883
|
-
|
|
884
|
-
return (
|
|
885
|
-
rect.left < -tolerance ||
|
|
886
|
-
rect.top < -tolerance ||
|
|
887
|
-
rect.right > viewportWidth + tolerance ||
|
|
888
|
-
rect.bottom > viewportHeight + tolerance
|
|
889
|
-
);
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
function clamp(value, min, max) {
|
|
893
|
-
return Math.min(Math.max(value, min), max);
|
|
894
|
-
}
|
|
895
|
-
|
|
896
297
|
function roundByDPR(value) {
|
|
897
298
|
const dpr = window.devicePixelRatio || 1;
|
|
898
299
|
return Math.round(value * dpr) / dpr;
|
|
@@ -12,11 +12,33 @@
|
|
|
12
12
|
* SPDX-License-Identifier: AGPL-3.0
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
+
import {
|
|
16
|
+
arrow,
|
|
17
|
+
autoPlacement,
|
|
18
|
+
autoUpdate,
|
|
19
|
+
computePosition,
|
|
20
|
+
flip,
|
|
21
|
+
hide,
|
|
22
|
+
offset,
|
|
23
|
+
shift,
|
|
24
|
+
size,
|
|
25
|
+
} from "@floating-ui/dom";
|
|
15
26
|
import { extend } from "../../../data/extend.mjs";
|
|
16
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
isArray,
|
|
29
|
+
isElement,
|
|
30
|
+
isFunction,
|
|
31
|
+
isNumber,
|
|
32
|
+
isObject,
|
|
33
|
+
isString,
|
|
34
|
+
} from "../../../types/is.mjs";
|
|
17
35
|
import { validateBoolean } from "../../../types/validate.mjs";
|
|
18
36
|
|
|
19
|
-
export {
|
|
37
|
+
export {
|
|
38
|
+
createFloatingPopper,
|
|
39
|
+
setEventListenersModifiers,
|
|
40
|
+
popperInstanceSymbol,
|
|
41
|
+
};
|
|
20
42
|
|
|
21
43
|
/**
|
|
22
44
|
* @private
|
|
@@ -24,6 +46,65 @@ export { setEventListenersModifiers, popperInstanceSymbol };
|
|
|
24
46
|
*/
|
|
25
47
|
const popperInstanceSymbol = Symbol("popperInstance");
|
|
26
48
|
|
|
49
|
+
/**
|
|
50
|
+
* @private
|
|
51
|
+
* @type {symbol}
|
|
52
|
+
*/
|
|
53
|
+
const optionsSymbol = Symbol("options");
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @private
|
|
57
|
+
* @type {symbol}
|
|
58
|
+
*/
|
|
59
|
+
const referenceElementSymbol = Symbol("referenceElement");
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @private
|
|
63
|
+
* @type {symbol}
|
|
64
|
+
*/
|
|
65
|
+
const popperElementSymbol = Symbol("popperElement");
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @private
|
|
69
|
+
* @type {symbol}
|
|
70
|
+
*/
|
|
71
|
+
const autoUpdateCleanupSymbol = Symbol("autoUpdateCleanup");
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @private
|
|
75
|
+
* @param {HTMLElement} referenceElement
|
|
76
|
+
* @param {HTMLElement} popperElement
|
|
77
|
+
* @param {object} options
|
|
78
|
+
* @return {{destroy: Function, setOptions: Function, update: Function}}
|
|
79
|
+
*/
|
|
80
|
+
function createFloatingPopper(referenceElement, popperElement, options = {}) {
|
|
81
|
+
const instance = {
|
|
82
|
+
[referenceElementSymbol]: referenceElement,
|
|
83
|
+
[popperElementSymbol]: popperElement,
|
|
84
|
+
[optionsSymbol]: normalizeOptions(options),
|
|
85
|
+
[autoUpdateCleanupSymbol]: null,
|
|
86
|
+
destroy() {
|
|
87
|
+
stopAutoUpdate(instance);
|
|
88
|
+
},
|
|
89
|
+
setOptions(nextOptions) {
|
|
90
|
+
const normalizedOptions = isFunction(nextOptions)
|
|
91
|
+
? nextOptions(instance[optionsSymbol])
|
|
92
|
+
: nextOptions;
|
|
93
|
+
|
|
94
|
+
instance[optionsSymbol] = normalizeOptions(normalizedOptions);
|
|
95
|
+
syncAutoUpdate(instance);
|
|
96
|
+
return instance.update();
|
|
97
|
+
},
|
|
98
|
+
update() {
|
|
99
|
+
return updatePosition(instance);
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
syncAutoUpdate(instance);
|
|
104
|
+
|
|
105
|
+
return instance;
|
|
106
|
+
}
|
|
107
|
+
|
|
27
108
|
/**
|
|
28
109
|
* @private
|
|
29
110
|
* @this {CustomElement}
|
|
@@ -31,25 +112,252 @@ const popperInstanceSymbol = Symbol("popperInstance");
|
|
|
31
112
|
*/
|
|
32
113
|
function setEventListenersModifiers(mode) {
|
|
33
114
|
const options = extend({}, this.getOption("popper"));
|
|
34
|
-
const modifiers = options?.
|
|
115
|
+
const modifiers = options?.modifiers;
|
|
35
116
|
|
|
36
117
|
if (!isArray(modifiers)) {
|
|
37
|
-
options
|
|
118
|
+
options.modifiers = [];
|
|
38
119
|
}
|
|
39
120
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
options["modifiers"].push({
|
|
121
|
+
const existingModifier = options.modifiers.find((entry) => {
|
|
122
|
+
return entry?.name === "eventListeners";
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
if (existingModifier) {
|
|
126
|
+
existingModifier.enabled = validateBoolean(mode);
|
|
127
|
+
} else {
|
|
128
|
+
options.modifiers.push({
|
|
49
129
|
name: "eventListeners",
|
|
50
130
|
enabled: validateBoolean(mode),
|
|
51
131
|
});
|
|
52
132
|
}
|
|
53
133
|
|
|
54
|
-
this[popperInstanceSymbol].setOptions(options);
|
|
134
|
+
return this[popperInstanceSymbol].setOptions(options);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @private
|
|
139
|
+
* @param {object} instance
|
|
140
|
+
* @return {Promise<void>}
|
|
141
|
+
*/
|
|
142
|
+
function updatePosition(instance) {
|
|
143
|
+
const referenceElement = instance[referenceElementSymbol];
|
|
144
|
+
const popperElement = instance[popperElementSymbol];
|
|
145
|
+
const options = instance[optionsSymbol];
|
|
146
|
+
|
|
147
|
+
if (!isElement(referenceElement) || !isElement(popperElement)) {
|
|
148
|
+
return Promise.resolve();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return computePosition(referenceElement, popperElement, {
|
|
152
|
+
placement: options.placement,
|
|
153
|
+
strategy: options.strategy,
|
|
154
|
+
middleware: options.middleware,
|
|
155
|
+
}).then(({ x, y, strategy }) => {
|
|
156
|
+
Object.assign(popperElement.style, {
|
|
157
|
+
position: strategy,
|
|
158
|
+
left: `${roundByDPR(x)}px`,
|
|
159
|
+
top: `${roundByDPR(y)}px`,
|
|
160
|
+
transform: "",
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @private
|
|
167
|
+
* @param {object} instance
|
|
168
|
+
* @return {void}
|
|
169
|
+
*/
|
|
170
|
+
function syncAutoUpdate(instance) {
|
|
171
|
+
stopAutoUpdate(instance);
|
|
172
|
+
|
|
173
|
+
if (instance[optionsSymbol].eventListeners !== true) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
instance[autoUpdateCleanupSymbol] = autoUpdate(
|
|
178
|
+
instance[referenceElementSymbol],
|
|
179
|
+
instance[popperElementSymbol],
|
|
180
|
+
() => {
|
|
181
|
+
void instance.update();
|
|
182
|
+
},
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* @private
|
|
188
|
+
* @param {object} instance
|
|
189
|
+
* @return {void}
|
|
190
|
+
*/
|
|
191
|
+
function stopAutoUpdate(instance) {
|
|
192
|
+
const cleanup = instance[autoUpdateCleanupSymbol];
|
|
193
|
+
if (typeof cleanup === "function") {
|
|
194
|
+
cleanup();
|
|
195
|
+
}
|
|
196
|
+
instance[autoUpdateCleanupSymbol] = null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* @private
|
|
201
|
+
* @param {object} options
|
|
202
|
+
* @return {object}
|
|
203
|
+
*/
|
|
204
|
+
function normalizeOptions(options) {
|
|
205
|
+
const config = extend(
|
|
206
|
+
{
|
|
207
|
+
placement: "bottom",
|
|
208
|
+
strategy: "absolute",
|
|
209
|
+
modifiers: [],
|
|
210
|
+
},
|
|
211
|
+
options || {},
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
config.eventListeners = normalizeEventListeners(config.modifiers);
|
|
215
|
+
config.middleware = normalizeMiddleware(config);
|
|
216
|
+
|
|
217
|
+
if (config.placement === "auto") {
|
|
218
|
+
config.placement = "bottom";
|
|
219
|
+
config.middleware.unshift(
|
|
220
|
+
autoPlacement({
|
|
221
|
+
crossAxis: true,
|
|
222
|
+
autoAlignment: true,
|
|
223
|
+
}),
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return config;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @private
|
|
232
|
+
* @param {object[]} modifiers
|
|
233
|
+
* @return {boolean}
|
|
234
|
+
*/
|
|
235
|
+
function normalizeEventListeners(modifiers) {
|
|
236
|
+
if (!isArray(modifiers)) {
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
let result = true;
|
|
241
|
+
|
|
242
|
+
for (const entry of modifiers) {
|
|
243
|
+
if (entry?.name === "eventListeners") {
|
|
244
|
+
result = validateBoolean(entry.enabled);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return result;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* @private
|
|
253
|
+
* @param {object} config
|
|
254
|
+
* @return {Array}
|
|
255
|
+
*/
|
|
256
|
+
function normalizeMiddleware(config) {
|
|
257
|
+
const result = [];
|
|
258
|
+
const middleware = [];
|
|
259
|
+
|
|
260
|
+
if (isArray(config?.middleware)) {
|
|
261
|
+
middleware.push(...config.middleware);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (isArray(config?.modifiers)) {
|
|
265
|
+
middleware.push(...config.modifiers);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
for (const entry of middleware) {
|
|
269
|
+
if (isFunction(entry)) {
|
|
270
|
+
result.push(entry);
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (isObject(entry) && isFunction(entry?.fn)) {
|
|
275
|
+
result.push(entry);
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (isObject(entry) && !isString(entry?.name)) {
|
|
280
|
+
result.push(entry);
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (!isObject(entry) || !isString(entry?.name)) {
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const normalizedEntry = normalizeModifier(entry);
|
|
289
|
+
if (normalizedEntry) {
|
|
290
|
+
result.push(normalizedEntry);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return result;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* @private
|
|
299
|
+
* @param {{name: string, options?: object, enabled?: boolean}} modifier
|
|
300
|
+
* @return {object|null}
|
|
301
|
+
*/
|
|
302
|
+
function normalizeModifier(modifier) {
|
|
303
|
+
if (modifier.enabled === false) {
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
switch (modifier.name) {
|
|
308
|
+
case "arrow":
|
|
309
|
+
if (!isElement(modifier?.options?.element)) {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
return arrow(modifier.options);
|
|
313
|
+
case "autoPlacement":
|
|
314
|
+
return autoPlacement(modifier.options);
|
|
315
|
+
case "eventListeners":
|
|
316
|
+
return null;
|
|
317
|
+
case "flip":
|
|
318
|
+
return flip(modifier.options);
|
|
319
|
+
case "hide":
|
|
320
|
+
return hide(modifier.options);
|
|
321
|
+
case "offset":
|
|
322
|
+
return offset(normalizeOffset(modifier.options?.offset));
|
|
323
|
+
case "preventOverflow":
|
|
324
|
+
return shift(modifier.options);
|
|
325
|
+
case "shift":
|
|
326
|
+
return shift(modifier.options);
|
|
327
|
+
case "size":
|
|
328
|
+
return size(modifier.options);
|
|
329
|
+
default:
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* @private
|
|
336
|
+
* @param {number|Array<number>} rawOffset
|
|
337
|
+
* @return {number|object}
|
|
338
|
+
*/
|
|
339
|
+
function normalizeOffset(rawOffset) {
|
|
340
|
+
if (isArray(rawOffset)) {
|
|
341
|
+
const [skidding = 0, distance = 0] = rawOffset;
|
|
342
|
+
return {
|
|
343
|
+
mainAxis: distance,
|
|
344
|
+
crossAxis: skidding,
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (isNumber(rawOffset)) {
|
|
349
|
+
return rawOffset;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return 0;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* @private
|
|
357
|
+
* @param {number} value
|
|
358
|
+
* @return {number}
|
|
359
|
+
*/
|
|
360
|
+
function roundByDPR(value) {
|
|
361
|
+
const dpr = window.devicePixelRatio || 1;
|
|
362
|
+
return Math.round(value * dpr) / dpr;
|
|
55
363
|
}
|
|
@@ -169,8 +169,8 @@ class Popper extends CustomElement {
|
|
|
169
169
|
content: "<slot></slot>",
|
|
170
170
|
popper: {
|
|
171
171
|
placement: "top",
|
|
172
|
-
engine: "
|
|
173
|
-
middleware: ["
|
|
172
|
+
engine: "floating",
|
|
173
|
+
middleware: ["flip", "shift", "offset:15", "arrow"],
|
|
174
174
|
contentOverflow: "both",
|
|
175
175
|
},
|
|
176
176
|
features: {
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { instanceSymbol } from "../../constants.mjs";
|
|
16
|
-
import { createPopper } from "@popperjs/core";
|
|
17
16
|
import { extend } from "../../data/extend.mjs";
|
|
18
17
|
import { Pathfinder } from "../../data/pathfinder.mjs";
|
|
19
18
|
import {
|
|
@@ -56,6 +55,7 @@ import { TabsStyleSheet } from "./stylesheet/tabs.mjs";
|
|
|
56
55
|
import { loadAndAssignContent } from "../form/util/fetch.mjs";
|
|
57
56
|
import { ThemeStyleSheet } from "../stylesheet/theme.mjs";
|
|
58
57
|
import {
|
|
58
|
+
createFloatingPopper,
|
|
59
59
|
popperInstanceSymbol,
|
|
60
60
|
setEventListenersModifiers,
|
|
61
61
|
} from "../form/util/popper.mjs";
|
|
@@ -189,9 +189,9 @@ class Tabs extends CustomElement {
|
|
|
189
189
|
* @property {String} fetch.mode=same-origin
|
|
190
190
|
* @property {String} fetch.credentials=same-origin
|
|
191
191
|
* @property {Object} fetch.headers={"accept":"text/html"}}
|
|
192
|
-
* @property {Object} popper
|
|
193
|
-
* @property {string} popper.placement=bottom
|
|
194
|
-
* @property {Object[]} modifiers={name:offset}
|
|
192
|
+
* @property {Object} popper Popper configuration
|
|
193
|
+
* @property {string} popper.placement=bottom Popper placement
|
|
194
|
+
* @property {Object[]} popper.modifiers={name:offset} Placement middleware configuration
|
|
195
195
|
*/
|
|
196
196
|
get defaults() {
|
|
197
197
|
return Object.assign({}, super.defaults, {
|
|
@@ -473,6 +473,8 @@ class Tabs extends CustomElement {
|
|
|
473
473
|
for (const [, type] of Object.entries(["click", "touch"])) {
|
|
474
474
|
document.removeEventListener(type, this[closeEventHandler]);
|
|
475
475
|
}
|
|
476
|
+
|
|
477
|
+
this[popperInstanceSymbol]?.destroy();
|
|
476
478
|
}
|
|
477
479
|
}
|
|
478
480
|
|
|
@@ -668,14 +670,13 @@ function attachTabChangeObserver() {
|
|
|
668
670
|
/**
|
|
669
671
|
* @private
|
|
670
672
|
* @return {Select}
|
|
671
|
-
* @external "external:createPopper"
|
|
672
673
|
*/
|
|
673
674
|
function initPopper() {
|
|
674
675
|
const self = this;
|
|
675
676
|
|
|
676
677
|
const options = extend({}, self.getOption("popper"));
|
|
677
678
|
|
|
678
|
-
self[popperInstanceSymbol] =
|
|
679
|
+
self[popperInstanceSymbol] = createFloatingPopper(
|
|
679
680
|
self[switchElementSymbol],
|
|
680
681
|
self[popperElementSymbol],
|
|
681
682
|
options,
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { instanceSymbol } from "../../constants.mjs";
|
|
16
|
-
import { createPopper } from "@popperjs/core";
|
|
17
16
|
import { extend } from "../../data/extend.mjs";
|
|
18
17
|
import { Pathfinder } from "../../data/pathfinder.mjs";
|
|
19
18
|
import {
|
|
@@ -57,6 +56,7 @@ import { VerticalTabsStyleSheet } from "./stylesheet/vertical-tabs.mjs";
|
|
|
57
56
|
import { loadAndAssignContent } from "../form/util/fetch.mjs";
|
|
58
57
|
import { ThemeStyleSheet } from "../stylesheet/theme.mjs";
|
|
59
58
|
import {
|
|
59
|
+
createFloatingPopper,
|
|
60
60
|
popperInstanceSymbol,
|
|
61
61
|
setEventListenersModifiers,
|
|
62
62
|
} from "../form/util/popper.mjs";
|
|
@@ -190,9 +190,9 @@ class VerticalTabs extends CustomElement {
|
|
|
190
190
|
* @property {String} fetch.mode=same-origin
|
|
191
191
|
* @property {String} fetch.credentials=same-origin
|
|
192
192
|
* @property {Object} fetch.headers={"accept":"text/html"}}
|
|
193
|
-
* @property {Object} popper
|
|
194
|
-
* @property {string} popper.placement=
|
|
195
|
-
* @property {Object[]} modifiers={name:offset}
|
|
193
|
+
* @property {Object} popper Popper configuration
|
|
194
|
+
* @property {string} popper.placement=right-start Popper placement
|
|
195
|
+
* @property {Object[]} popper.modifiers={name:offset} Placement middleware configuration
|
|
196
196
|
*/
|
|
197
197
|
get defaults() {
|
|
198
198
|
return Object.assign({}, super.defaults, {
|
|
@@ -474,6 +474,8 @@ class VerticalTabs extends CustomElement {
|
|
|
474
474
|
for (const [, type] of Object.entries(["click", "touch"])) {
|
|
475
475
|
document.removeEventListener(type, this[closeEventHandler]);
|
|
476
476
|
}
|
|
477
|
+
|
|
478
|
+
this[popperInstanceSymbol]?.destroy();
|
|
477
479
|
}
|
|
478
480
|
}
|
|
479
481
|
|
|
@@ -669,14 +671,13 @@ function attachTabChangeObserver() {
|
|
|
669
671
|
/**
|
|
670
672
|
* @private
|
|
671
673
|
* @return {Select}
|
|
672
|
-
* @external "external:createPopper"
|
|
673
674
|
*/
|
|
674
675
|
function initPopper() {
|
|
675
676
|
const self = this;
|
|
676
677
|
|
|
677
678
|
const options = extend({}, self.getOption("popper"));
|
|
678
679
|
|
|
679
|
-
self[popperInstanceSymbol] =
|
|
680
|
+
self[popperInstanceSymbol] = createFloatingPopper(
|
|
680
681
|
self[switchElementSymbol],
|
|
681
682
|
self[popperElementSymbol],
|
|
682
683
|
options,
|
|
@@ -8,6 +8,8 @@ chai.use(chaiDom);
|
|
|
8
8
|
let Login;
|
|
9
9
|
|
|
10
10
|
describe("Login", function () {
|
|
11
|
+
this.timeout(10000);
|
|
12
|
+
|
|
11
13
|
before(function (done) {
|
|
12
14
|
initJSDOM().then(() => {
|
|
13
15
|
import("element-internals-polyfill")
|
|
@@ -32,21 +34,14 @@ describe("Login", function () {
|
|
|
32
34
|
expect(document.createElement("monster-login")).is.instanceof(Login);
|
|
33
35
|
});
|
|
34
36
|
|
|
35
|
-
it("should respect the native hidden attribute on the host", function (
|
|
37
|
+
it("should respect the native hidden attribute on the host", function () {
|
|
36
38
|
const login = document.createElement("monster-login");
|
|
37
39
|
login.setAttribute("hidden", "");
|
|
38
40
|
document.getElementById("mocks").appendChild(login);
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
expect(login.visible).to.be.false;
|
|
44
|
-
expect(login.isVisible).to.be.false;
|
|
45
|
-
done();
|
|
46
|
-
} catch (error) {
|
|
47
|
-
done(error);
|
|
48
|
-
}
|
|
49
|
-
}, 100);
|
|
42
|
+
expect(login.hidden).to.be.true;
|
|
43
|
+
expect(login.visible).to.be.false;
|
|
44
|
+
expect(login.isVisible).to.be.false;
|
|
50
45
|
});
|
|
51
46
|
|
|
52
47
|
it("should hide and show the host with the public visibility API", function (done) {
|