@schukai/monster 4.129.7 → 4.129.9
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/form/context-base.mjs +3 -0
- package/source/components/form/context-error.mjs +4 -0
- package/source/components/form/util/floating-ui.mjs +168 -21
- package/source/components/layout/popper.mjs +1 -1
- package/source/components/layout/stylesheet/popper.mjs +1 -1
- package/source/components/style/floating-ui.css +1 -57
- package/source/components/style/floating-ui.pcss +7 -0
- package/source/components/stylesheet/floating-ui.mjs +7 -14
- package/test/cases/components/form/context-error.mjs +48 -0
- package/test/cases/components/form/context-help.mjs +91 -0
- package/test/cases/components/form/popper-button.mjs +56 -0
- package/test/cases/components/form/select.mjs +32 -78
- package/test/cases/dom/util/init-options-from-attributes.mjs +14 -0
- package/test/web/tests.js +5800 -6811
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
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.
|
|
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.9"}
|
|
@@ -50,6 +50,9 @@ class ContextBase extends Popper {
|
|
|
50
50
|
*/
|
|
51
51
|
get defaults() {
|
|
52
52
|
return Object.assign({}, super.defaults, {
|
|
53
|
+
popper: Object.assign({}, super.defaults.popper, {
|
|
54
|
+
contentOverflow: "visible",
|
|
55
|
+
}),
|
|
53
56
|
features: Object.assign({}, super.defaults.features, {
|
|
54
57
|
showIconWithoutContent: false,
|
|
55
58
|
}),
|
|
@@ -28,6 +28,7 @@ import { Processing } from "../../../util/processing.mjs";
|
|
|
28
28
|
|
|
29
29
|
export {
|
|
30
30
|
closePositionedPopper,
|
|
31
|
+
resolveClippingBoundaryElement,
|
|
31
32
|
isPositionedPopperOpen,
|
|
32
33
|
openPositionedPopper,
|
|
33
34
|
positionPopper,
|
|
@@ -43,7 +44,7 @@ const autoUpdateCleanupMap = new WeakMap();
|
|
|
43
44
|
* @return {Promise|*}
|
|
44
45
|
*/
|
|
45
46
|
function positionPopper(controlElement, popperElement, options) {
|
|
46
|
-
const config = normalizePopperConfig(options);
|
|
47
|
+
const config = normalizePopperConfig(options, controlElement, popperElement);
|
|
47
48
|
|
|
48
49
|
return new Processing(() => {
|
|
49
50
|
enableFloatingPositioning(controlElement, popperElement, config);
|
|
@@ -51,7 +52,7 @@ function positionPopper(controlElement, popperElement, options) {
|
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
function openPositionedPopper(controlElement, popperElement, options) {
|
|
54
|
-
const config = normalizePopperConfig(options);
|
|
55
|
+
const config = normalizePopperConfig(options, controlElement, popperElement);
|
|
55
56
|
|
|
56
57
|
stopAutoUpdate(popperElement);
|
|
57
58
|
popperElement.style.display = "block";
|
|
@@ -115,7 +116,7 @@ function isPositionedPopperOpen(popperElement) {
|
|
|
115
116
|
return popperElement.style.display === "block";
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
function normalizePopperConfig(options) {
|
|
119
|
+
function normalizePopperConfig(options, controlElement, popperElement) {
|
|
119
120
|
const config = Object.assign(
|
|
120
121
|
{},
|
|
121
122
|
{
|
|
@@ -126,13 +127,28 @@ function normalizePopperConfig(options) {
|
|
|
126
127
|
options,
|
|
127
128
|
);
|
|
128
129
|
|
|
130
|
+
config.boundaryElement = resolveClippingBoundaryElement(
|
|
131
|
+
controlElement,
|
|
132
|
+
popperElement,
|
|
133
|
+
);
|
|
134
|
+
config.detectOverflowOptions = buildDetectOverflowOptions(
|
|
135
|
+
config.boundaryElement,
|
|
136
|
+
);
|
|
129
137
|
config.middleware = normalizeMiddleware(config);
|
|
130
138
|
config.middlewareTokens = config.middleware.filter((line) => isString(line));
|
|
131
139
|
config.floatingMiddleware = buildFloatingMiddleware(
|
|
132
140
|
config.middleware,
|
|
133
141
|
config.placement,
|
|
142
|
+
config.detectOverflowOptions,
|
|
143
|
+
popperElement,
|
|
134
144
|
);
|
|
135
145
|
|
|
146
|
+
if (!config.middlewareTokens.includes("size")) {
|
|
147
|
+
config.floatingMiddleware.push(
|
|
148
|
+
createAdaptiveSizeMiddleware(config.detectOverflowOptions, popperElement),
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
136
152
|
return config;
|
|
137
153
|
}
|
|
138
154
|
|
|
@@ -149,7 +165,12 @@ function normalizeMiddleware(config) {
|
|
|
149
165
|
return [];
|
|
150
166
|
}
|
|
151
167
|
|
|
152
|
-
function buildFloatingMiddleware(
|
|
168
|
+
function buildFloatingMiddleware(
|
|
169
|
+
middleware,
|
|
170
|
+
placement,
|
|
171
|
+
detectOverflowOptions,
|
|
172
|
+
popperElement,
|
|
173
|
+
) {
|
|
153
174
|
const result = [...middleware];
|
|
154
175
|
|
|
155
176
|
for (const key in result) {
|
|
@@ -169,10 +190,10 @@ function buildFloatingMiddleware(middleware, placement) {
|
|
|
169
190
|
|
|
170
191
|
switch (fn) {
|
|
171
192
|
case "flip":
|
|
172
|
-
result[key] = flip();
|
|
193
|
+
result[key] = flip(detectOverflowOptions);
|
|
173
194
|
break;
|
|
174
195
|
case "shift":
|
|
175
|
-
result[key] = shift();
|
|
196
|
+
result[key] = shift(detectOverflowOptions);
|
|
176
197
|
break;
|
|
177
198
|
case "autoPlacement":
|
|
178
199
|
let defaultAllowedPlacements = ["top", "bottom", "left", "right"];
|
|
@@ -192,31 +213,28 @@ function buildFloatingMiddleware(middleware, placement) {
|
|
|
192
213
|
}
|
|
193
214
|
defaultAllowedPlacements.unshift(placement);
|
|
194
215
|
|
|
195
|
-
result[key] = autoPlacement(
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
216
|
+
result[key] = autoPlacement(
|
|
217
|
+
Object.assign({}, detectOverflowOptions, {
|
|
218
|
+
crossAxis: true,
|
|
219
|
+
autoAlignment: true,
|
|
220
|
+
allowedPlacements: defaultAllowedPlacements,
|
|
221
|
+
}),
|
|
222
|
+
);
|
|
200
223
|
break;
|
|
201
224
|
case "arrow":
|
|
202
225
|
result[key] = null;
|
|
203
226
|
break;
|
|
204
227
|
case "size":
|
|
205
|
-
result[key] =
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
maxWidth: `${availableWidth}px`,
|
|
210
|
-
maxHeight: `${availableHeight}px`,
|
|
211
|
-
});
|
|
212
|
-
},
|
|
213
|
-
});
|
|
228
|
+
result[key] = createAdaptiveSizeMiddleware(
|
|
229
|
+
detectOverflowOptions,
|
|
230
|
+
popperElement,
|
|
231
|
+
);
|
|
214
232
|
break;
|
|
215
233
|
case "offset":
|
|
216
234
|
result[key] = offset(parseInt(kv?.shift()) || 10);
|
|
217
235
|
break;
|
|
218
236
|
case "hide":
|
|
219
|
-
result[key] = hide();
|
|
237
|
+
result[key] = hide(detectOverflowOptions);
|
|
220
238
|
break;
|
|
221
239
|
default:
|
|
222
240
|
throw new Error(`Unknown function: ${fn}`);
|
|
@@ -226,6 +244,135 @@ function buildFloatingMiddleware(middleware, placement) {
|
|
|
226
244
|
return result.filter(Boolean);
|
|
227
245
|
}
|
|
228
246
|
|
|
247
|
+
function createAdaptiveSizeMiddleware(detectOverflowOptions, popperElement) {
|
|
248
|
+
return size(
|
|
249
|
+
Object.assign({}, detectOverflowOptions, {
|
|
250
|
+
apply({ availableWidth, availableHeight, elements }) {
|
|
251
|
+
const floatingElement = elements?.floating || popperElement;
|
|
252
|
+
if (!(floatingElement instanceof HTMLElement)) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const maxWidth = clampAvailableDimension(
|
|
257
|
+
availableWidth,
|
|
258
|
+
readMaxDimension(floatingElement, "maxWidth"),
|
|
259
|
+
);
|
|
260
|
+
const maxHeight = clampAvailableDimension(
|
|
261
|
+
availableHeight,
|
|
262
|
+
readMaxDimension(floatingElement, "maxHeight"),
|
|
263
|
+
);
|
|
264
|
+
const nextStyle = {
|
|
265
|
+
boxSizing: "border-box",
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
if (Number.isFinite(maxWidth) && maxWidth > 0) {
|
|
269
|
+
nextStyle.maxWidth = `${maxWidth}px`;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (Number.isFinite(maxHeight) && maxHeight > 0) {
|
|
273
|
+
nextStyle.maxHeight = `${maxHeight}px`;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
Object.assign(floatingElement.style, nextStyle);
|
|
277
|
+
},
|
|
278
|
+
}),
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function buildDetectOverflowOptions(boundaryElement) {
|
|
283
|
+
const result = {
|
|
284
|
+
rootBoundary: "viewport",
|
|
285
|
+
padding: 0,
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
if (boundaryElement instanceof HTMLElement) {
|
|
289
|
+
result.boundary = boundaryElement;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function resolveClippingBoundaryElement(...elements) {
|
|
296
|
+
for (const element of elements) {
|
|
297
|
+
const clippingBoundary = findNearestClippingContainer(element);
|
|
298
|
+
if (clippingBoundary instanceof HTMLElement) {
|
|
299
|
+
return clippingBoundary;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function findNearestClippingContainer(element) {
|
|
307
|
+
let current = getComposedParent(element);
|
|
308
|
+
|
|
309
|
+
while (current) {
|
|
310
|
+
if (
|
|
311
|
+
current instanceof HTMLElement &&
|
|
312
|
+
isClippingContainer(getComputedStyle(current))
|
|
313
|
+
) {
|
|
314
|
+
return current;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
current = getComposedParent(current);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function getComposedParent(node) {
|
|
324
|
+
if (!node) {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (node instanceof ShadowRoot) {
|
|
329
|
+
return node.host || null;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (node.parentElement instanceof HTMLElement) {
|
|
333
|
+
return node.parentElement;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const rootNode = node.getRootNode?.();
|
|
337
|
+
if (rootNode instanceof ShadowRoot) {
|
|
338
|
+
return rootNode.host || null;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return node.parentNode || null;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function isClippingContainer(style) {
|
|
345
|
+
if (!style) {
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return [style.overflow, style.overflowX, style.overflowY].some((value) => {
|
|
350
|
+
return ["hidden", "auto", "scroll", "clip"].includes(value);
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function readMaxDimension(element, property) {
|
|
355
|
+
const rawValue = getComputedStyle(element)?.[property];
|
|
356
|
+
if (!rawValue || rawValue === "none") {
|
|
357
|
+
return Infinity;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const value = Number.parseFloat(rawValue);
|
|
361
|
+
return Number.isFinite(value) ? value : Infinity;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function clampAvailableDimension(available, configuredMax) {
|
|
365
|
+
if (!Number.isFinite(available) || available <= 0) {
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (!Number.isFinite(configuredMax)) {
|
|
370
|
+
return available;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return Math.min(available, configuredMax);
|
|
374
|
+
}
|
|
375
|
+
|
|
229
376
|
function startAutoUpdate(controlElement, popperElement, callback) {
|
|
230
377
|
stopAutoUpdate(popperElement);
|
|
231
378
|
autoUpdateCleanupMap.set(
|
|
@@ -155,7 +155,7 @@ class Popper extends CustomElement {
|
|
|
155
155
|
* @property {Object} popper - Positioning options
|
|
156
156
|
* @property {string} popper.placement - Placement: top|bottom|left|right
|
|
157
157
|
* @property {Array} popper.middleware - Positioning middleware functions
|
|
158
|
-
* @property {string} popper.contentOverflow - Content clipping mode: both|horizontal
|
|
158
|
+
* @property {string} popper.contentOverflow - Content clipping mode: both|horizontal|visible
|
|
159
159
|
* @property {Object} features - Feature flags
|
|
160
160
|
* @property {boolean} features.preventOpenEventSent - Prevent open event
|
|
161
161
|
* @returns {Object} Default options merged with parent defaults
|
|
@@ -25,7 +25,7 @@ try {
|
|
|
25
25
|
PopperStyleSheet.insertRule(
|
|
26
26
|
`
|
|
27
27
|
@layer popper {
|
|
28
|
-
[data-monster-role=control]{box-sizing:border-box;outline:none;width:100%}[data-monster-role=control].flex{align-items:center;display:flex;flex-direction:row}:host{box-sizing:border-box;display:block}div[data-monster-role=popper]{align-content:center;background:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);box-sizing:border-box;color:var(--monster-color-primary-1);display:none;justify-content:space-between;left:0;max-height:var(--monster-popper-max-height,calc(100vh - 2rem));max-width:var(--monster-popper-max-width,calc(100vw - 2rem));padding:1.1em;position:absolute;top:0;width:-moz-max-content;width:max-content;z-index:var(--monster-z-index-modal)}div[data-monster-role=popper]>[part=content]{max-height:var(--monster-popper-content-max-height,calc(100vh - 4.2rem));max-width:100%;overflow:auto}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=horizontal]{clip-path:inset(calc(var(--monster-popper-content-block-overflow, 100vh)*-1) 0 calc(var(--monster-popper-content-block-overflow, 100vh)*-1) 0);overflow:visible}div[data-monster-role=popper] div[data-monster-role=arrow]{background:var(--monster-bg-color-primary-1);height:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);pointer-events:none;position:absolute;width:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);z-index:-1}[data-monster-role=control]{display:flex;position:relative}
|
|
28
|
+
[data-monster-role=control]{box-sizing:border-box;outline:none;width:100%}[data-monster-role=control].flex{align-items:center;display:flex;flex-direction:row}:host{box-sizing:border-box;display:block}div[data-monster-role=popper]{align-content:center;background:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);box-sizing:border-box;color:var(--monster-color-primary-1);display:none;justify-content:space-between;left:0;max-height:var(--monster-popper-max-height,calc(100vh - 2rem));max-width:var(--monster-popper-max-width,calc(100vw - 2rem));padding:1.1em;position:absolute;top:0;width:-moz-max-content;width:max-content;z-index:var(--monster-z-index-modal)}div[data-monster-role=popper]>[part=content]{max-height:var(--monster-popper-content-max-height,calc(100vh - 4.2rem));max-width:100%;overflow:auto}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=horizontal]{clip-path:inset(calc(var(--monster-popper-content-block-overflow, 100vh)*-1) 0 calc(var(--monster-popper-content-block-overflow, 100vh)*-1) 0);overflow:visible}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=visible]{clip-path:none;max-height:none;max-width:none;overflow:visible}div[data-monster-role=popper] div[data-monster-role=arrow]{background:var(--monster-bg-color-primary-1);height:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);pointer-events:none;position:absolute;width:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);z-index:-1}[data-monster-role=control]{display:flex;position:relative}
|
|
29
29
|
}`,
|
|
30
30
|
0,
|
|
31
31
|
);
|
|
@@ -1,58 +1,2 @@
|
|
|
1
1
|
/** generated from floating-ui.pcss **/
|
|
2
|
-
div[data-monster-role=
|
|
3
|
-
align-content: center;
|
|
4
|
-
background: var(--monster-bg-color-primary-1);
|
|
5
|
-
border-color: var(--monster-bg-color-primary-4);
|
|
6
|
-
border-radius: var(--monster-border-radius);
|
|
7
|
-
border-style: var(--monster-border-style);
|
|
8
|
-
border-width: var(--monster-border-width);
|
|
9
|
-
box-shadow: var(--monster-box-shadow-1);
|
|
10
|
-
box-sizing: border-box;
|
|
11
|
-
color: var(--monster-color-primary-1);
|
|
12
|
-
display: none;
|
|
13
|
-
justify-content: space-between;
|
|
14
|
-
left: 0;
|
|
15
|
-
max-height: var(--monster-popper-max-height, calc(100vh - 2rem));
|
|
16
|
-
max-width: var(--monster-popper-max-width, calc(100vw - 2rem));
|
|
17
|
-
padding: 1.1em;
|
|
18
|
-
position: absolute;
|
|
19
|
-
top: 0;
|
|
20
|
-
width: -moz-max-content;
|
|
21
|
-
width: max-content;
|
|
22
|
-
z-index: var(--monster-z-index-modal);
|
|
23
|
-
}
|
|
24
|
-
div[data-monster-role="popper"] > [part="content"] {
|
|
25
|
-
max-height: var(--monster-popper-content-max-height, calc(100vh - 4.2rem));
|
|
26
|
-
max-width: 100%;
|
|
27
|
-
overflow: auto;
|
|
28
|
-
}
|
|
29
|
-
div[data-monster-role="popper"]
|
|
30
|
-
> [part="content"][data-monster-overflow-mode="horizontal"] {
|
|
31
|
-
clip-path: inset(
|
|
32
|
-
calc(var(--monster-popper-content-block-overflow, 100vh) * -1) 0
|
|
33
|
-
calc(var(--monster-popper-content-block-overflow, 100vh) * -1) 0
|
|
34
|
-
);
|
|
35
|
-
overflow: visible;
|
|
36
|
-
}
|
|
37
|
-
div[data-monster-role="popper"] div[data-monster-role="arrow"] {
|
|
38
|
-
background: var(--monster-bg-color-primary-1);
|
|
39
|
-
height: calc(
|
|
40
|
-
max(
|
|
41
|
-
var(--monster-popper-witharrrow-distance),
|
|
42
|
-
-1 *
|
|
43
|
-
var(--monster-popper-witharrrow-distance)
|
|
44
|
-
) *
|
|
45
|
-
2
|
|
46
|
-
);
|
|
47
|
-
pointer-events: none;
|
|
48
|
-
position: absolute;
|
|
49
|
-
width: calc(
|
|
50
|
-
max(
|
|
51
|
-
var(--monster-popper-witharrrow-distance),
|
|
52
|
-
-1 *
|
|
53
|
-
var(--monster-popper-witharrrow-distance)
|
|
54
|
-
) *
|
|
55
|
-
2
|
|
56
|
-
);
|
|
57
|
-
z-index: -1;
|
|
58
|
-
}
|
|
2
|
+
div[data-monster-role=popper]{align-content:center;background:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);box-sizing:border-box;color:var(--monster-color-primary-1);display:none;justify-content:space-between;left:0;max-height:var(--monster-popper-max-height,calc(100vh - 2rem));max-width:var(--monster-popper-max-width,calc(100vw - 2rem));padding:1.1em;position:absolute;top:0;width:-moz-max-content;width:max-content;z-index:var(--monster-z-index-modal)}div[data-monster-role=popper]>[part=content]{max-height:var(--monster-popper-content-max-height,calc(100vh - 4.2rem));max-width:100%;overflow:auto}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=horizontal]{clip-path:inset(calc(var(--monster-popper-content-block-overflow, 100vh)*-1) 0 calc(var(--monster-popper-content-block-overflow, 100vh)*-1) 0);overflow:visible}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=visible]{clip-path:none;max-height:none;max-width:none;overflow:visible}div[data-monster-role=popper] div[data-monster-role=arrow]{background:var(--monster-bg-color-primary-1);height:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);pointer-events:none;position:absolute;width:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);z-index:-1}
|
|
@@ -39,6 +39,13 @@ div[data-monster-role=popper] {
|
|
|
39
39
|
);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
& > [part=content][data-monster-overflow-mode=visible] {
|
|
43
|
+
overflow: visible;
|
|
44
|
+
clip-path: none;
|
|
45
|
+
max-width: none;
|
|
46
|
+
max-height: none;
|
|
47
|
+
}
|
|
48
|
+
|
|
42
49
|
& div[data-monster-role=arrow] {
|
|
43
50
|
position: absolute;
|
|
44
51
|
width: calc(2 * max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance)));
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
* For more information about purchasing a commercial license, please contact Volker Schukai.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import {addAttributeToken} from "../../dom/attributes.mjs";
|
|
14
|
+
import {ATTRIBUTE_ERRORMESSAGE} from "../../dom/constants.mjs";
|
|
15
15
|
|
|
16
|
-
export {
|
|
16
|
+
export {FloatingUiStyleSheet}
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* @private
|
|
@@ -22,17 +22,10 @@ export { FloatingUiStyleSheet };
|
|
|
22
22
|
const FloatingUiStyleSheet = new CSSStyleSheet();
|
|
23
23
|
|
|
24
24
|
try {
|
|
25
|
-
|
|
26
|
-
`
|
|
25
|
+
FloatingUiStyleSheet.insertRule(`
|
|
27
26
|
@layer floatingui {
|
|
28
|
-
div[data-monster-role=popper]{align-content:center;background:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);box-sizing:border-box;color:var(--monster-color-primary-1);display:none;justify-content:space-between;left:0;max-height:var(--monster-popper-max-height,calc(100vh - 2rem));max-width:var(--monster-popper-max-width,calc(100vw - 2rem));padding:1.1em;position:absolute;top:0;width:-moz-max-content;width:max-content;z-index:var(--monster-z-index-modal)}div[data-monster-role=popper]>[part=content]{max-height:var(--monster-popper-content-max-height,calc(100vh - 4.2rem));max-width:100%;overflow:auto}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=horizontal]{clip-path:inset(calc(var(--monster-popper-content-block-overflow, 100vh)*-1) 0 calc(var(--monster-popper-content-block-overflow, 100vh)*-1) 0);overflow:visible}div[data-monster-role=popper] div[data-monster-role=arrow]{background:var(--monster-bg-color-primary-1);height:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);pointer-events:none;position:absolute;width:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);z-index:-1}
|
|
29
|
-
}`,
|
|
30
|
-
0,
|
|
31
|
-
);
|
|
27
|
+
div[data-monster-role=popper]{align-content:center;background:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);box-sizing:border-box;color:var(--monster-color-primary-1);display:none;justify-content:space-between;left:0;max-height:var(--monster-popper-max-height,calc(100vh - 2rem));max-width:var(--monster-popper-max-width,calc(100vw - 2rem));padding:1.1em;position:absolute;top:0;width:-moz-max-content;width:max-content;z-index:var(--monster-z-index-modal)}div[data-monster-role=popper]>[part=content]{max-height:var(--monster-popper-content-max-height,calc(100vh - 4.2rem));max-width:100%;overflow:auto}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=horizontal]{clip-path:inset(calc(var(--monster-popper-content-block-overflow, 100vh)*-1) 0 calc(var(--monster-popper-content-block-overflow, 100vh)*-1) 0);overflow:visible}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=visible]{clip-path:none;max-height:none;max-width:none;overflow:visible}div[data-monster-role=popper] div[data-monster-role=arrow]{background:var(--monster-bg-color-primary-1);height:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);pointer-events:none;position:absolute;width:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);z-index:-1}
|
|
28
|
+
}`, 0);
|
|
32
29
|
} catch (e) {
|
|
33
|
-
|
|
34
|
-
document.getRootNode().querySelector("html"),
|
|
35
|
-
ATTRIBUTE_ERRORMESSAGE,
|
|
36
|
-
e + "",
|
|
37
|
-
);
|
|
30
|
+
addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + "");
|
|
38
31
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as chai from "chai";
|
|
2
|
+
import { chaiDom } from "../../../util/chai-dom.mjs";
|
|
3
|
+
import { initJSDOM } from "../../../util/jsdom.mjs";
|
|
4
|
+
|
|
5
|
+
let expect = chai.expect;
|
|
6
|
+
chai.use(chaiDom);
|
|
7
|
+
|
|
8
|
+
let ContextError;
|
|
9
|
+
|
|
10
|
+
describe("ContextError", function () {
|
|
11
|
+
before(function (done) {
|
|
12
|
+
initJSDOM()
|
|
13
|
+
.then(() => {
|
|
14
|
+
return import("../../../../source/components/form/context-error.mjs");
|
|
15
|
+
})
|
|
16
|
+
.then((m) => {
|
|
17
|
+
ContextError = m["ContextError"];
|
|
18
|
+
done();
|
|
19
|
+
})
|
|
20
|
+
.catch((e) => done(e));
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
let mocks = document.getElementById("mocks");
|
|
25
|
+
mocks.innerHTML = "";
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should default to visible content overflow", function (done) {
|
|
29
|
+
let mocks = document.getElementById("mocks");
|
|
30
|
+
const error = document.createElement("monster-context-error");
|
|
31
|
+
error.innerHTML = "<p>Error message</p>";
|
|
32
|
+
mocks.appendChild(error);
|
|
33
|
+
|
|
34
|
+
setTimeout(() => {
|
|
35
|
+
try {
|
|
36
|
+
expect(error).to.be.instanceof(ContextError);
|
|
37
|
+
const content = error.shadowRoot.querySelector('[part="content"]');
|
|
38
|
+
expect(error.getOption("popper.contentOverflow")).to.equal("visible");
|
|
39
|
+
expect(content.getAttribute("data-monster-overflow-mode")).to.equal(
|
|
40
|
+
"visible",
|
|
41
|
+
);
|
|
42
|
+
done();
|
|
43
|
+
} catch (e) {
|
|
44
|
+
done(e);
|
|
45
|
+
}
|
|
46
|
+
}, 0);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { getGlobal } from "../../../../source/types/global.mjs";
|
|
2
|
+
import * as chai from "chai";
|
|
3
|
+
import { chaiDom } from "../../../util/chai-dom.mjs";
|
|
4
|
+
import { initJSDOM } from "../../../util/jsdom.mjs";
|
|
5
|
+
import { ResizeObserverMock } from "../../../util/resize-observer.mjs";
|
|
6
|
+
|
|
7
|
+
let expect = chai.expect;
|
|
8
|
+
chai.use(chaiDom);
|
|
9
|
+
|
|
10
|
+
const global = getGlobal();
|
|
11
|
+
|
|
12
|
+
let ContextHelp;
|
|
13
|
+
let resolveClippingBoundaryElement;
|
|
14
|
+
|
|
15
|
+
describe("ContextHelp", function () {
|
|
16
|
+
before(function (done) {
|
|
17
|
+
initJSDOM().then(() => {
|
|
18
|
+
import("element-internals-polyfill").catch((e) => done(e));
|
|
19
|
+
|
|
20
|
+
if (!global.ResizeObserver) {
|
|
21
|
+
global.ResizeObserver = ResizeObserverMock;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
Promise.all([
|
|
25
|
+
import("../../../../source/components/form/context-help.mjs"),
|
|
26
|
+
import("../../../../source/components/form/util/floating-ui.mjs"),
|
|
27
|
+
])
|
|
28
|
+
.then(([contextHelpModule, floatingUiModule]) => {
|
|
29
|
+
ContextHelp = contextHelpModule.ContextHelp;
|
|
30
|
+
resolveClippingBoundaryElement =
|
|
31
|
+
floatingUiModule.resolveClippingBoundaryElement;
|
|
32
|
+
done();
|
|
33
|
+
})
|
|
34
|
+
.catch((e) => done(e));
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
afterEach(() => {
|
|
39
|
+
let mocks = document.getElementById("mocks");
|
|
40
|
+
mocks.innerHTML = "";
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("should resolve the nearest clipping parent across the shadow boundary", function (done) {
|
|
44
|
+
let mocks = document.getElementById("mocks");
|
|
45
|
+
const outer = document.createElement("div");
|
|
46
|
+
const wrapper = document.createElement("div");
|
|
47
|
+
const help = document.createElement("monster-context-help");
|
|
48
|
+
|
|
49
|
+
outer.style.overflow = "visible";
|
|
50
|
+
wrapper.style.overflow = "hidden";
|
|
51
|
+
wrapper.appendChild(help);
|
|
52
|
+
outer.appendChild(wrapper);
|
|
53
|
+
mocks.appendChild(outer);
|
|
54
|
+
help.innerHTML = "<p>Inline help</p>";
|
|
55
|
+
|
|
56
|
+
setTimeout(() => {
|
|
57
|
+
try {
|
|
58
|
+
expect(help).to.be.instanceof(ContextHelp);
|
|
59
|
+
|
|
60
|
+
const popper = help.shadowRoot.querySelector(
|
|
61
|
+
'[data-monster-role="popper"]',
|
|
62
|
+
);
|
|
63
|
+
expect(popper).to.exist;
|
|
64
|
+
expect(resolveClippingBoundaryElement(help, popper)).to.equal(wrapper);
|
|
65
|
+
done();
|
|
66
|
+
} catch (e) {
|
|
67
|
+
done(e);
|
|
68
|
+
}
|
|
69
|
+
}, 0);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("should default to visible content overflow", function (done) {
|
|
73
|
+
let mocks = document.getElementById("mocks");
|
|
74
|
+
const help = document.createElement("monster-context-help");
|
|
75
|
+
help.innerHTML = "<p>Inline help</p>";
|
|
76
|
+
mocks.appendChild(help);
|
|
77
|
+
|
|
78
|
+
setTimeout(() => {
|
|
79
|
+
try {
|
|
80
|
+
const content = help.shadowRoot.querySelector('[part="content"]');
|
|
81
|
+
expect(help.getOption("popper.contentOverflow")).to.equal("visible");
|
|
82
|
+
expect(content.getAttribute("data-monster-overflow-mode")).to.equal(
|
|
83
|
+
"visible",
|
|
84
|
+
);
|
|
85
|
+
done();
|
|
86
|
+
} catch (e) {
|
|
87
|
+
done(e);
|
|
88
|
+
}
|
|
89
|
+
}, 0);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -62,6 +62,37 @@ describe("PopperButton", function () {
|
|
|
62
62
|
}, 0);
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
+
it("should apply visible content overflow mode to the rendered content wrapper", function (done) {
|
|
66
|
+
let mocks = document.getElementById("mocks");
|
|
67
|
+
const button = document.createElement("monster-popper-button");
|
|
68
|
+
mocks.appendChild(button);
|
|
69
|
+
|
|
70
|
+
setTimeout(() => {
|
|
71
|
+
try {
|
|
72
|
+
const content = button.shadowRoot.querySelector('[part="content"]');
|
|
73
|
+
expect(content).to.exist;
|
|
74
|
+
|
|
75
|
+
button.setOption("popper.contentOverflow", "visible");
|
|
76
|
+
|
|
77
|
+
setTimeout(() => {
|
|
78
|
+
try {
|
|
79
|
+
expect(
|
|
80
|
+
button.getOption("popper.contentOverflow"),
|
|
81
|
+
).to.equal("visible");
|
|
82
|
+
expect(
|
|
83
|
+
content.getAttribute("data-monster-overflow-mode"),
|
|
84
|
+
).to.equal("visible");
|
|
85
|
+
done();
|
|
86
|
+
} catch (e) {
|
|
87
|
+
done(e);
|
|
88
|
+
}
|
|
89
|
+
}, 0);
|
|
90
|
+
} catch (e) {
|
|
91
|
+
done(e);
|
|
92
|
+
}
|
|
93
|
+
}, 0);
|
|
94
|
+
});
|
|
95
|
+
|
|
65
96
|
it("should apply content overflow mode from the HTML attribute", function (done) {
|
|
66
97
|
let mocks = document.getElementById("mocks");
|
|
67
98
|
mocks.innerHTML = `
|
|
@@ -87,6 +118,31 @@ describe("PopperButton", function () {
|
|
|
87
118
|
}, 0);
|
|
88
119
|
});
|
|
89
120
|
|
|
121
|
+
it("should apply visible content overflow mode from the HTML attribute", function (done) {
|
|
122
|
+
let mocks = document.getElementById("mocks");
|
|
123
|
+
mocks.innerHTML = `
|
|
124
|
+
<monster-popper-button
|
|
125
|
+
data-monster-option-popper-content-overflow="visible"
|
|
126
|
+
></monster-popper-button>
|
|
127
|
+
`;
|
|
128
|
+
|
|
129
|
+
setTimeout(() => {
|
|
130
|
+
try {
|
|
131
|
+
const button = mocks.querySelector("monster-popper-button");
|
|
132
|
+
const content = button.shadowRoot.querySelector('[part="content"]');
|
|
133
|
+
expect(button.getOption("popper.contentOverflow")).to.equal(
|
|
134
|
+
"visible",
|
|
135
|
+
);
|
|
136
|
+
expect(content.getAttribute("data-monster-overflow-mode")).to.equal(
|
|
137
|
+
"visible",
|
|
138
|
+
);
|
|
139
|
+
done();
|
|
140
|
+
} catch (e) {
|
|
141
|
+
done(e);
|
|
142
|
+
}
|
|
143
|
+
}, 0);
|
|
144
|
+
});
|
|
145
|
+
|
|
90
146
|
it("should use absolute positioning by default", function (done) {
|
|
91
147
|
let mocks = document.getElementById("mocks");
|
|
92
148
|
const button = document.createElement("monster-popper-button");
|