@schukai/monster 4.136.1 → 4.136.3

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.
Files changed (25) hide show
  1. package/package.json +1 -1
  2. package/source/components/content/stylesheet/camera-capture.mjs +1 -1
  3. package/source/components/content/stylesheet/copy.mjs +1 -1
  4. package/source/components/content/stylesheet/viewer.mjs +0 -29
  5. package/source/components/content/viewer/stylesheet/message.mjs +1 -1
  6. package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +1 -1
  7. package/source/components/form/context-base.mjs +55 -0
  8. package/source/components/form/select.mjs +2 -1
  9. package/source/components/form/style/context-error.pcss +0 -2
  10. package/source/components/form/style/context-help.pcss +0 -2
  11. package/source/components/form/stylesheet/button-bar.mjs +1 -1
  12. package/source/components/form/stylesheet/confirm-button.mjs +1 -1
  13. package/source/components/form/stylesheet/context-error.mjs +7 -14
  14. package/source/components/form/stylesheet/context-help.mjs +7 -14
  15. package/source/components/form/stylesheet/digits.mjs +1 -1
  16. package/source/components/form/stylesheet/field-set.mjs +1 -1
  17. package/source/components/form/stylesheet/login.mjs +1 -1
  18. package/source/components/form/stylesheet/popper-button.mjs +1 -1
  19. package/source/components/form/stylesheet/select.mjs +1 -1
  20. package/source/components/form/util/floating-ui.mjs +124 -9
  21. package/source/components/layout/popper.mjs +13 -2
  22. package/source/components/style/floating-ui.css +61 -1
  23. package/source/components/stylesheet/floating-ui.mjs +13 -6
  24. package/test/cases/components/form/context-help.mjs +73 -0
  25. package/test/cases/components/form/floating-ui.mjs +72 -0
@@ -279,6 +279,17 @@ class Popper extends CustomElement {
279
279
  return this;
280
280
  }
281
281
 
282
+ /**
283
+ * Resolves the effective popper options for the current render pass.
284
+ * Subclasses can override this to adapt positioning without mutating
285
+ * the persisted component options.
286
+ *
287
+ * @return {object}
288
+ */
289
+ resolvePopperOptions() {
290
+ return Object.assign({}, this.getOption("popper", {}));
291
+ }
292
+
282
293
  /**
283
294
  * Resolves the effective content overflow mode for the rendered wrapper.
284
295
  * Subclasses can override this when the configured option is only an intermediate mode.
@@ -587,7 +598,7 @@ function show() {
587
598
  openPositionedPopper(
588
599
  self[controlElementSymbol],
589
600
  popperElement,
590
- self.getOption("popper", {}),
601
+ self.resolvePopperOptions(),
591
602
  );
592
603
 
593
604
  addAttributeToken(controlElement, "class", "open");
@@ -628,7 +639,7 @@ function updatePopper() {
628
639
  this,
629
640
  this[controlElementSymbol],
630
641
  this[popperElementSymbol],
631
- this.getOption("popper", {}),
642
+ this.resolvePopperOptions(),
632
643
  );
633
644
  }
634
645
 
@@ -1,2 +1,62 @@
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: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}
2
+ div[data-monster-role="popper"] {
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: none;
32
+ overflow: visible;
33
+ }
34
+ div[data-monster-role="popper"]
35
+ > [part="content"][data-monster-overflow-mode="visible"] {
36
+ clip-path: none;
37
+ max-height: none;
38
+ max-width: none;
39
+ overflow: visible;
40
+ }
41
+ div[data-monster-role="popper"] div[data-monster-role="arrow"] {
42
+ background: var(--monster-bg-color-primary-1);
43
+ height: calc(
44
+ max(
45
+ var(--monster-popper-witharrrow-distance),
46
+ -1 *
47
+ var(--monster-popper-witharrrow-distance)
48
+ ) *
49
+ 2
50
+ );
51
+ pointer-events: none;
52
+ position: absolute;
53
+ width: calc(
54
+ max(
55
+ var(--monster-popper-witharrrow-distance),
56
+ -1 *
57
+ var(--monster-popper-witharrrow-distance)
58
+ ) *
59
+ 2
60
+ );
61
+ z-index: -1;
62
+ }
@@ -10,10 +10,10 @@
10
10
  * For more information about purchasing a commercial license, please contact Volker Schukai.
11
11
  */
12
12
 
13
- import {addAttributeToken} from "../../dom/attributes.mjs";
14
- import {ATTRIBUTE_ERRORMESSAGE} from "../../dom/constants.mjs";
13
+ import { addAttributeToken } from "../../dom/attributes.mjs";
14
+ import { ATTRIBUTE_ERRORMESSAGE } from "../../dom/constants.mjs";
15
15
 
16
- export {FloatingUiStyleSheet}
16
+ export { FloatingUiStyleSheet };
17
17
 
18
18
  /**
19
19
  * @private
@@ -22,10 +22,17 @@ export {FloatingUiStyleSheet}
22
22
  const FloatingUiStyleSheet = new CSSStyleSheet();
23
23
 
24
24
  try {
25
- FloatingUiStyleSheet.insertRule(`
25
+ FloatingUiStyleSheet.insertRule(
26
+ `
26
27
  @layer floatingui {
27
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: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
- }`, 0);
29
+ }`,
30
+ 0,
31
+ );
29
32
  } catch (e) {
30
- addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + "");
33
+ addAttributeToken(
34
+ document.getRootNode().querySelector("html"),
35
+ ATTRIBUTE_ERRORMESSAGE,
36
+ e + "",
37
+ );
31
38
  }
@@ -11,6 +11,7 @@ const global = getGlobal();
11
11
 
12
12
  let ContextHelp;
13
13
  let resolveClippingBoundaryElement;
14
+ let resolveParentPopperContentBoundary;
14
15
 
15
16
  describe("ContextHelp", function () {
16
17
  before(function (done) {
@@ -29,6 +30,8 @@ describe("ContextHelp", function () {
29
30
  ContextHelp = contextHelpModule.ContextHelp;
30
31
  resolveClippingBoundaryElement =
31
32
  floatingUiModule.resolveClippingBoundaryElement;
33
+ resolveParentPopperContentBoundary =
34
+ floatingUiModule.resolveParentPopperContentBoundary;
32
35
  done();
33
36
  })
34
37
  .catch((e) => done(e));
@@ -88,4 +91,74 @@ describe("ContextHelp", function () {
88
91
  }
89
92
  }, 0);
90
93
  });
94
+
95
+ it("should switch to fixed positioning inside a clipping container", function (done) {
96
+ let mocks = document.getElementById("mocks");
97
+ const wrapper = document.createElement("div");
98
+ const help = document.createElement("monster-context-help");
99
+
100
+ wrapper.style.overflow = "hidden";
101
+ wrapper.appendChild(help);
102
+ mocks.appendChild(wrapper);
103
+ help.innerHTML = "<p>Inline help</p>";
104
+
105
+ setTimeout(() => {
106
+ try {
107
+ help.showDialog();
108
+
109
+ const popper = help.shadowRoot.querySelector(
110
+ '[data-monster-role="popper"]',
111
+ );
112
+ expect(popper).to.exist;
113
+ expect(popper.style.position).to.equal("fixed");
114
+ done();
115
+ } catch (e) {
116
+ done(e);
117
+ }
118
+ }, 0);
119
+ });
120
+
121
+ it("should switch to fixed positioning inside a parent popper content wrapper with overflow both", function (done) {
122
+ let mocks = document.getElementById("mocks");
123
+ const host = document.createElement("div");
124
+ const help = document.createElement("monster-context-help");
125
+
126
+ mocks.appendChild(host);
127
+ const shadowRoot = host.attachShadow({ mode: "open" });
128
+ shadowRoot.innerHTML = `
129
+ <div data-monster-role="popper">
130
+ <div part="content"
131
+ data-monster-overflow-mode="both">
132
+ </div>
133
+ </div>
134
+ `;
135
+ shadowRoot.querySelector('[part="content"]').appendChild(help);
136
+ help.innerHTML = "<p>Nested help</p>";
137
+
138
+ setTimeout(() => {
139
+ try {
140
+ const control = help.shadowRoot.querySelector(
141
+ '[data-monster-role="control"]',
142
+ );
143
+ const popper = help.shadowRoot.querySelector(
144
+ '[data-monster-role="popper"]',
145
+ );
146
+
147
+ expect(
148
+ resolveParentPopperContentBoundary(control, popper),
149
+ ).to.equal(shadowRoot.querySelector('[part="content"]'));
150
+
151
+ const content = help.shadowRoot.querySelector('[part="content"]');
152
+ expect(content.getAttribute("data-monster-overflow-mode")).to.equal(
153
+ "both",
154
+ );
155
+
156
+ help.showDialog();
157
+ expect(popper.style.position).to.equal("fixed");
158
+ done();
159
+ } catch (e) {
160
+ done(e);
161
+ }
162
+ }, 0);
163
+ });
91
164
  });
@@ -135,4 +135,76 @@ describe("form floating-ui boundary resolution", function () {
135
135
  expect(content.style.maxWidth).to.equal("");
136
136
  expect(content.style.maxHeight).to.equal("100px");
137
137
  });
138
+
139
+ it("should not clamp the floating element height when content overflow is visible", function () {
140
+ const mocks = document.getElementById("mocks");
141
+ const popper = document.createElement("div");
142
+ const content = document.createElement("div");
143
+
144
+ popper.style.maxHeight = "300px";
145
+ content.style.maxHeight = "240px";
146
+ content.setAttribute("part", "content");
147
+ content.setAttribute("data-monster-overflow-mode", "visible");
148
+
149
+ popper.appendChild(content);
150
+ mocks.appendChild(popper);
151
+
152
+ applyAdaptiveFloatingElementSize(popper, {
153
+ availableWidth: 220,
154
+ availableHeight: 160,
155
+ });
156
+
157
+ expect(popper.style.maxHeight).to.equal("");
158
+ expect(content.style.maxHeight).to.equal("240px");
159
+ });
160
+
161
+ it("should keep at least one readable line for scrollable content", function () {
162
+ const mocks = document.getElementById("mocks");
163
+ const popper = document.createElement("div");
164
+ const content = document.createElement("div");
165
+
166
+ popper.style.maxHeight = "300px";
167
+ content.setAttribute("part", "content");
168
+ content.textContent = "A long help text that still needs one readable line.";
169
+ content.style.fontSize = "16px";
170
+ content.style.lineHeight = "24px";
171
+ popper.appendChild(content);
172
+ mocks.appendChild(popper);
173
+
174
+ applyAdaptiveFloatingElementSize(popper, {
175
+ availableWidth: 220,
176
+ availableHeight: 10,
177
+ });
178
+
179
+ expect(content.style.maxHeight).to.equal("24px");
180
+ });
181
+
182
+ it("should use the first slotted element line height for the minimum readable size", function () {
183
+ const mocks = document.getElementById("mocks");
184
+ const popperHost = document.createElement("div");
185
+ const slottedParagraph = document.createElement("p");
186
+ slottedParagraph.textContent = "Readable help line";
187
+ slottedParagraph.style.lineHeight = "26px";
188
+
189
+ mocks.appendChild(popperHost);
190
+ const shadowRoot = popperHost.attachShadow({ mode: "open" });
191
+ shadowRoot.innerHTML = `
192
+ <div data-monster-role="popper">
193
+ <div part="content">
194
+ <slot></slot>
195
+ </div>
196
+ </div>
197
+ `;
198
+
199
+ const popper = shadowRoot.querySelector('[data-monster-role="popper"]');
200
+ const content = shadowRoot.querySelector('[part="content"]');
201
+ popperHost.appendChild(slottedParagraph);
202
+
203
+ applyAdaptiveFloatingElementSize(popper, {
204
+ availableWidth: 220,
205
+ availableHeight: 10,
206
+ });
207
+
208
+ expect(content.style.maxHeight).to.equal("26px");
209
+ });
138
210
  });