@schukai/monster 4.129.9 → 4.130.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/package.json +1 -1
- package/source/components/content/image-editor.mjs +1 -0
- package/source/components/datatable/change-button.mjs +1 -1
- package/source/components/datatable/pagination.mjs +2 -1
- package/source/components/datatable/save-button.mjs +1 -0
- package/source/components/files/file-manager.mjs +1 -0
- package/source/components/form/api-button.mjs +2 -1
- package/source/components/form/context-error.mjs +1 -0
- package/source/components/form/context-help.mjs +1 -0
- package/source/components/form/credential-button.mjs +1 -0
- package/source/components/form/field-set.mjs +2 -1
- package/source/components/form/popper-button.mjs +3 -0
- package/source/components/form/quantity.mjs +2 -1
- package/source/components/form/repeat-field-set.mjs +1 -0
- package/source/components/form/toggle-switch.mjs +1 -0
- package/source/components/form/util/floating-ui.mjs +37 -1
- package/source/components/layout/popper.mjs +45 -2
- package/source/components/layout/stylesheet/popper.mjs +1 -1
- package/source/components/notify/monitor-attribute-errors.mjs +1 -1
- package/source/components/state/log.mjs +1 -0
- package/source/components/state/state.mjs +1 -0
- package/source/components/state/thread.mjs +1 -0
- package/source/components/style/floating-ui.css +1 -1
- package/source/components/style/floating-ui.pcss +1 -6
- package/source/components/stylesheet/floating-ui.mjs +1 -1
- package/test/cases/components/form/floating-ui.mjs +61 -0
- package/test/cases/components/form/popper-button.mjs +31 -0
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.
|
|
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.130.0"}
|
|
@@ -274,6 +274,7 @@ const rotateResetButtonElementSymbol = Symbol("rotateResetButtonElement");
|
|
|
274
274
|
* An Image Editor Component
|
|
275
275
|
*
|
|
276
276
|
* @fragments /fragments/components/content/image-editor/
|
|
277
|
+
* @example /examples/components/content/image-editor-basic Basic editor workflow
|
|
277
278
|
*
|
|
278
279
|
* @since 4.68.0
|
|
279
280
|
* @copyright Volker Schukai
|
|
@@ -187,7 +187,7 @@ function initControlReferences() {
|
|
|
187
187
|
const selector2 = this.getOption("overlay.selector");
|
|
188
188
|
|
|
189
189
|
if (isString(selector2)) {
|
|
190
|
-
const element = findElementWithSelectorUpwards(this,
|
|
190
|
+
const element = findElementWithSelectorUpwards(this, selector2);
|
|
191
191
|
if (element === null) {
|
|
192
192
|
throw new Error("the selector must match exactly one element");
|
|
193
193
|
}
|
|
@@ -102,7 +102,8 @@ const compactNextIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" heig
|
|
|
102
102
|
*
|
|
103
103
|
* @fragments /fragments/components/datatable/pagination
|
|
104
104
|
*
|
|
105
|
-
* @example /examples/components/datatable/pagination-simple
|
|
105
|
+
* @example /examples/components/datatable/pagination-simple Datasource pagination
|
|
106
|
+
* @example /examples/components/datatable/pagination-programmatic Programmatic pagination state
|
|
106
107
|
*
|
|
107
108
|
* @copyright Volker Schukai
|
|
108
109
|
* @summary The Pagination component is used to show the current page and the total number of pages.
|
|
@@ -84,6 +84,7 @@ const internalDisableVersionSymbol = Symbol("internalDisableVersion");
|
|
|
84
84
|
* @fragments /fragments/components/datatable/save-button
|
|
85
85
|
*
|
|
86
86
|
* @example /examples/components/datatable/save-button-simple Simple example
|
|
87
|
+
* @example /examples/components/datatable/save-button-workflow Draft changes workflow
|
|
87
88
|
*
|
|
88
89
|
* @issue https://localhost.alvine.dev:8440/development/issues/closed/274.html
|
|
89
90
|
*
|
|
@@ -137,6 +137,7 @@ const saveAllButtonSymbol = Symbol("saveAllButton");
|
|
|
137
137
|
* A file manager for navigating and editing files.
|
|
138
138
|
*
|
|
139
139
|
* @fragments /fragments/components/files/file-manager/
|
|
140
|
+
* @example /examples/components/files/file-manager-basic Basic file manager workflow
|
|
140
141
|
*
|
|
141
142
|
* @since 4.44.0
|
|
142
143
|
* @summary A file manager control that builds a tree navigation from an API and opens files in tabs.
|
|
@@ -57,10 +57,11 @@ const containerElementSymbol = Symbol("containerElement");
|
|
|
57
57
|
* @fragments /fragments/components/form/api-button/
|
|
58
58
|
*
|
|
59
59
|
* @example /examples/components/form/api-button-simple API Button
|
|
60
|
+
* @example /examples/components/form/api-button-workflow API workflow with events
|
|
60
61
|
*
|
|
61
62
|
* @since 3.32.0
|
|
62
63
|
* @copyright Volker Schukai
|
|
63
|
-
* @summary
|
|
64
|
+
* @summary An API button that loads actions dynamically and executes follow-up requests
|
|
64
65
|
* @fires monster-button-set
|
|
65
66
|
* @fires monster-api-button-click
|
|
66
67
|
* @fires monster-api-button-successful
|
|
@@ -60,6 +60,7 @@ const iconElementSymbol = Symbol("iconElement");
|
|
|
60
60
|
* @fragments /fragments/components/form/context-error
|
|
61
61
|
*
|
|
62
62
|
* @example /examples/components/form/context-error-simple
|
|
63
|
+
* @example /examples/components/form/context-error-live-validation
|
|
63
64
|
*
|
|
64
65
|
* @since 3.55.0
|
|
65
66
|
* @copyright Volker Schukai
|
|
@@ -25,6 +25,7 @@ export { ContextHelp };
|
|
|
25
25
|
* @fragments /fragments/components/form/context-help
|
|
26
26
|
*
|
|
27
27
|
* @example /examples/components/form/context-help-simple
|
|
28
|
+
* @example /examples/components/form/context-help-inline-guidance
|
|
28
29
|
*
|
|
29
30
|
* @since 3.29.0
|
|
30
31
|
* @copyright Volker Schukai
|
|
@@ -53,6 +53,7 @@ const passwordWiredSymbol = Symbol("passwordWired");
|
|
|
53
53
|
* @fragments /fragments/components/form/credential-button/
|
|
54
54
|
*
|
|
55
55
|
* @example /examples/components/form/credential-button-simple
|
|
56
|
+
* @example /examples/components/form/credential-button-retry
|
|
56
57
|
*
|
|
57
58
|
* @since 3.91.0
|
|
58
59
|
* @copyright Volker Schukai
|
|
@@ -75,7 +75,8 @@ const extendedSwitchElementSymbol = Symbol("extendedSwitchElement");
|
|
|
75
75
|
*
|
|
76
76
|
* @fragments /fragments/components/form/field-set/
|
|
77
77
|
*
|
|
78
|
-
* @example /examples/components/form/field-set-simple
|
|
78
|
+
* @example /examples/components/form/field-set-simple Shipping field set
|
|
79
|
+
* @example /examples/components/form/field-set-preferences Compact settings field set
|
|
79
80
|
*
|
|
80
81
|
* @since 3.65.0
|
|
81
82
|
* @copyright Volker Schukai
|
|
@@ -53,7 +53,8 @@ const holdIntervalSymbol = Symbol("holdInterval");
|
|
|
53
53
|
*
|
|
54
54
|
* @fragments /fragments/components/form/quantity/
|
|
55
55
|
*
|
|
56
|
-
* @example /examples/components/form/quantity-simple
|
|
56
|
+
* @example /examples/components/form/quantity-simple Basic quantity control
|
|
57
|
+
* @example /examples/components/form/quantity-decimal Decimal pricing stepper
|
|
57
58
|
*
|
|
58
59
|
* @since 4.41.0
|
|
59
60
|
* @copyright Volker Schukai
|
|
@@ -70,6 +70,7 @@ const itemDefaultsSymbol = Symbol("itemDefaults");
|
|
|
70
70
|
* A repeatable field-set control that manages array data.
|
|
71
71
|
*
|
|
72
72
|
* @fragments /fragments/components/form/repeat-field-set/
|
|
73
|
+
* @example /examples/components/form/repeat-field-set-simple Repeatable contacts
|
|
73
74
|
*
|
|
74
75
|
* @since 3.78.0
|
|
75
76
|
* @summary A repeatable field-set control
|
|
@@ -58,6 +58,7 @@ export const STATE_OFF = "off";
|
|
|
58
58
|
* @fragments /fragments/components/form/toggle-switch
|
|
59
59
|
*
|
|
60
60
|
* @example /examples/components/form/toggle-switch-simple Simple example
|
|
61
|
+
* @example /examples/components/form/toggle-switch-custom-values Custom values and labels
|
|
61
62
|
*
|
|
62
63
|
* @since 3.57.0
|
|
63
64
|
* @copyright Volker Schukai
|
|
@@ -309,7 +309,8 @@ function findNearestClippingContainer(element) {
|
|
|
309
309
|
while (current) {
|
|
310
310
|
if (
|
|
311
311
|
current instanceof HTMLElement &&
|
|
312
|
-
isClippingContainer(getComputedStyle(current))
|
|
312
|
+
isClippingContainer(getComputedStyle(current)) &&
|
|
313
|
+
!shouldIgnoreClippingContainer(current)
|
|
313
314
|
) {
|
|
314
315
|
return current;
|
|
315
316
|
}
|
|
@@ -341,6 +342,41 @@ function getComposedParent(node) {
|
|
|
341
342
|
return node.parentNode || null;
|
|
342
343
|
}
|
|
343
344
|
|
|
345
|
+
function shouldIgnoreClippingContainer(element) {
|
|
346
|
+
if (!(element instanceof HTMLElement)) {
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (!isPopperContentWrapper(element)) {
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const parent = getComposedParent(element);
|
|
355
|
+
return (
|
|
356
|
+
parent instanceof HTMLElement &&
|
|
357
|
+
parent.getAttribute("data-monster-role") === "popper"
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function isPopperContentWrapper(element) {
|
|
362
|
+
if (!(element instanceof HTMLElement)) {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (!element.hasAttribute("data-monster-overflow-mode")) {
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const part = element.getAttribute("part");
|
|
371
|
+
return (
|
|
372
|
+
isString(part) &&
|
|
373
|
+
part
|
|
374
|
+
.split(/\s+/)
|
|
375
|
+
.filter((token) => token.length > 0)
|
|
376
|
+
.includes("content")
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
|
|
344
380
|
function isClippingContainer(style) {
|
|
345
381
|
if (!style) {
|
|
346
382
|
return false;
|
|
@@ -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|visible
|
|
158
|
+
* @property {string} popper.contentOverflow - Content clipping mode: both|horizontal|visible|smart
|
|
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
|
|
@@ -200,6 +200,10 @@ class Popper extends CustomElement {
|
|
|
200
200
|
|
|
201
201
|
if (path === "popper.contentOverflow") {
|
|
202
202
|
applyContentOverflowMode.call(this);
|
|
203
|
+
} else if (path === "content") {
|
|
204
|
+
queueMicrotask(() => {
|
|
205
|
+
applyContentOverflowMode.call(this);
|
|
206
|
+
});
|
|
203
207
|
}
|
|
204
208
|
|
|
205
209
|
return this;
|
|
@@ -282,7 +286,16 @@ class Popper extends CustomElement {
|
|
|
282
286
|
* @return {string}
|
|
283
287
|
*/
|
|
284
288
|
resolveContentOverflowMode() {
|
|
285
|
-
|
|
289
|
+
const configuredMode = this.getOption("popper.contentOverflow", "both");
|
|
290
|
+
if (configuredMode !== "smart") {
|
|
291
|
+
return configuredMode;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (containsNestedOverlayContent(this.getOption("content"))) {
|
|
295
|
+
return "horizontal";
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return "both";
|
|
286
299
|
}
|
|
287
300
|
|
|
288
301
|
/**
|
|
@@ -702,6 +715,9 @@ function initOverflowObserver() {
|
|
|
702
715
|
() => {
|
|
703
716
|
applyContentOverflowMode.call(this);
|
|
704
717
|
};
|
|
718
|
+
this[attributeObserverSymbol]["data-monster-option-content"] = () => {
|
|
719
|
+
applyContentOverflowMode.call(this);
|
|
720
|
+
};
|
|
705
721
|
}
|
|
706
722
|
|
|
707
723
|
/**
|
|
@@ -743,4 +759,31 @@ function getTemplate() {
|
|
|
743
759
|
`;
|
|
744
760
|
}
|
|
745
761
|
|
|
762
|
+
function containsNestedOverlayContent(content) {
|
|
763
|
+
const selector = [
|
|
764
|
+
"monster-details",
|
|
765
|
+
"monster-message-state-button",
|
|
766
|
+
"monster-popper",
|
|
767
|
+
"monster-popper-button",
|
|
768
|
+
"monster-select",
|
|
769
|
+
"details",
|
|
770
|
+
].join(",");
|
|
771
|
+
|
|
772
|
+
if (typeof content === "string") {
|
|
773
|
+
const container = document.createElement("div");
|
|
774
|
+
container.innerHTML = content;
|
|
775
|
+
return container.querySelector(selector) instanceof HTMLElement;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
if (!(content instanceof HTMLElement)) {
|
|
779
|
+
return false;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
if (content.matches(selector)) {
|
|
783
|
+
return true;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
return content.querySelector(selector) instanceof HTMLElement;
|
|
787
|
+
}
|
|
788
|
+
|
|
746
789
|
registerCustomElement(Popper);
|
|
@@ -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:
|
|
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:none;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
|
);
|
|
@@ -47,7 +47,7 @@ const mutationObserversSymbol = Symbol("mutationObservers");
|
|
|
47
47
|
*
|
|
48
48
|
* @since 3.98.0
|
|
49
49
|
* @copyright Volker Schukai
|
|
50
|
-
* @summary
|
|
50
|
+
* @summary Watches the DOM for `data-monster-error` attributes and can forward them to `monster-notify`.
|
|
51
51
|
*/
|
|
52
52
|
class MonitorAttributeErrors extends CustomElement {
|
|
53
53
|
/**
|
|
@@ -58,6 +58,7 @@ const timeAgoIntervalSymbol = Symbol("timeAgoInterval");
|
|
|
58
58
|
* @fragments /fragments/components/state/log
|
|
59
59
|
*
|
|
60
60
|
* @example /examples/components/state/log-simple Log
|
|
61
|
+
* @example /examples/components/state/log-live-feed Live deployment feed
|
|
61
62
|
*
|
|
62
63
|
* @issue https://localhost.alvine.dev:8444/development/issues/closed/270.html
|
|
63
64
|
*
|
|
@@ -28,6 +28,7 @@ export { State };
|
|
|
28
28
|
* @fragments /fragments/components/state/state
|
|
29
29
|
*
|
|
30
30
|
* @example /examples/components/state/state-simple State
|
|
31
|
+
* @example /examples/components/state/state-actionable Actionable empty state
|
|
31
32
|
*
|
|
32
33
|
* @since 1.5.0
|
|
33
34
|
* @copyright Volker Schukai
|
|
@@ -54,6 +54,7 @@ const timeAgoIntervalSymbol = Symbol("timeAgoInterval");
|
|
|
54
54
|
* @fragments /fragments/components/state/thread
|
|
55
55
|
*
|
|
56
56
|
* @example /examples/components/state/thread-simple Thread
|
|
57
|
+
* @example /examples/components/state/thread-review Review thread with nested replies
|
|
57
58
|
*
|
|
58
59
|
* @issue https://localhost.alvine.dev:8444/development/issues/open/374.html
|
|
59
60
|
*
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** generated from floating-ui.pcss **/
|
|
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:
|
|
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:none;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}
|
|
@@ -31,12 +31,7 @@ div[data-monster-role=popper] {
|
|
|
31
31
|
|
|
32
32
|
& > [part=content][data-monster-overflow-mode=horizontal] {
|
|
33
33
|
overflow: visible;
|
|
34
|
-
clip-path:
|
|
35
|
-
calc(-1 * var(--monster-popper-content-block-overflow, 100vh))
|
|
36
|
-
0
|
|
37
|
-
calc(-1 * var(--monster-popper-content-block-overflow, 100vh))
|
|
38
|
-
0
|
|
39
|
-
);
|
|
34
|
+
clip-path: none;
|
|
40
35
|
}
|
|
41
36
|
|
|
42
37
|
& > [part=content][data-monster-overflow-mode=visible] {
|
|
@@ -24,7 +24,7 @@ const FloatingUiStyleSheet = new CSSStyleSheet();
|
|
|
24
24
|
try {
|
|
25
25
|
FloatingUiStyleSheet.insertRule(`
|
|
26
26
|
@layer floatingui {
|
|
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:
|
|
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:none;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
28
|
}`, 0);
|
|
29
29
|
} catch (e) {
|
|
30
30
|
addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + "");
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as chai from "chai";
|
|
2
|
+
import { initJSDOM } from "../../../util/jsdom.mjs";
|
|
3
|
+
|
|
4
|
+
let expect = chai.expect;
|
|
5
|
+
|
|
6
|
+
let resolveClippingBoundaryElement;
|
|
7
|
+
|
|
8
|
+
describe("form floating-ui boundary resolution", function () {
|
|
9
|
+
before(function (done) {
|
|
10
|
+
initJSDOM()
|
|
11
|
+
.then(() => {
|
|
12
|
+
return import(
|
|
13
|
+
"../../../../source/components/form/util/floating-ui.mjs"
|
|
14
|
+
);
|
|
15
|
+
})
|
|
16
|
+
.then((m) => {
|
|
17
|
+
resolveClippingBoundaryElement = m.resolveClippingBoundaryElement;
|
|
18
|
+
done();
|
|
19
|
+
})
|
|
20
|
+
.catch((e) => done(e));
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
const mocks = document.getElementById("mocks");
|
|
25
|
+
mocks.innerHTML = "";
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should ignore parent popper content wrappers as clipping boundaries for nested controls", function () {
|
|
29
|
+
const mocks = document.getElementById("mocks");
|
|
30
|
+
const wrapper = document.createElement("div");
|
|
31
|
+
const popperHost = document.createElement("div");
|
|
32
|
+
const selectHost = document.createElement("div");
|
|
33
|
+
|
|
34
|
+
wrapper.style.overflow = "hidden";
|
|
35
|
+
mocks.appendChild(wrapper);
|
|
36
|
+
wrapper.appendChild(popperHost);
|
|
37
|
+
|
|
38
|
+
const popperShadow = popperHost.attachShadow({ mode: "open" });
|
|
39
|
+
popperShadow.innerHTML = `
|
|
40
|
+
<div data-monster-role="popper">
|
|
41
|
+
<div part="content"
|
|
42
|
+
data-monster-overflow-mode="both"
|
|
43
|
+
style="overflow: auto;">
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
popperShadow.querySelector('[part="content"]').appendChild(selectHost);
|
|
49
|
+
|
|
50
|
+
const selectShadow = selectHost.attachShadow({ mode: "open" });
|
|
51
|
+
selectShadow.innerHTML = `
|
|
52
|
+
<div data-monster-role="control"></div>
|
|
53
|
+
<div data-monster-role="popper"></div>
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
const control = selectShadow.querySelector('[data-monster-role="control"]');
|
|
57
|
+
const popper = selectShadow.querySelector('[data-monster-role="popper"]');
|
|
58
|
+
|
|
59
|
+
expect(resolveClippingBoundaryElement(control, popper)).to.equal(wrapper);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -62,6 +62,37 @@ describe("PopperButton", function () {
|
|
|
62
62
|
}, 0);
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
+
it("should resolve nested overlay content to horizontal overflow by default", 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(
|
|
76
|
+
"content",
|
|
77
|
+
"<div><monster-select></monster-select></div>",
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
setTimeout(() => {
|
|
81
|
+
try {
|
|
82
|
+
expect(
|
|
83
|
+
content.getAttribute("data-monster-overflow-mode"),
|
|
84
|
+
).to.equal("horizontal");
|
|
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 visible content overflow mode to the rendered content wrapper", function (done) {
|
|
66
97
|
let mocks = document.getElementById("mocks");
|
|
67
98
|
const button = document.createElement("monster-popper-button");
|