@schukai/monster 4.129.0 → 4.129.2

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 (35) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/package.json +1 -1
  3. package/source/components/content/stylesheet/camera-capture.mjs +1 -1
  4. package/source/components/content/stylesheet/copy.mjs +1 -1
  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/message-state-button.mjs +234 -18
  8. package/source/components/form/popper-button.mjs +51 -9
  9. package/source/components/form/select.mjs +76 -14
  10. package/source/components/form/style/context-error.pcss +15 -0
  11. package/source/components/form/style/context-help.pcss +13 -1
  12. package/source/components/form/style/message-state-button.pcss +46 -3
  13. package/source/components/form/stylesheet/button-bar.mjs +1 -1
  14. package/source/components/form/stylesheet/confirm-button.mjs +1 -1
  15. package/source/components/form/stylesheet/context-error.mjs +1 -1
  16. package/source/components/form/stylesheet/context-help.mjs +1 -1
  17. package/source/components/form/stylesheet/digits.mjs +1 -1
  18. package/source/components/form/stylesheet/field-set.mjs +1 -1
  19. package/source/components/form/stylesheet/login.mjs +1 -1
  20. package/source/components/form/stylesheet/message-state-button.mjs +1 -1
  21. package/source/components/form/stylesheet/popper-button.mjs +1 -1
  22. package/source/components/form/stylesheet/select.mjs +1 -1
  23. package/source/components/form/util/floating-ui.mjs +808 -168
  24. package/source/components/layout/popper.mjs +139 -15
  25. package/source/components/layout/stylesheet/popper.mjs +1 -1
  26. package/source/components/style/floating-ui.css +8 -0
  27. package/source/components/style/floating-ui.pcss +10 -0
  28. package/source/components/stylesheet/floating-ui.mjs +1 -1
  29. package/source/dom/util/extract-keys.mjs +46 -10
  30. package/source/dom/util/init-options-from-attributes.mjs +4 -2
  31. package/source/dom/util/set-option-from-attribute.mjs +4 -2
  32. package/test/cases/components/form/message-state-button.mjs +272 -0
  33. package/test/cases/components/form/popper-button.mjs +89 -0
  34. package/test/cases/dom/util/extract-keys.mjs +34 -23
  35. package/test/cases/dom/util/init-options-from-attributes.mjs +21 -0
@@ -37,9 +37,13 @@ export { MessageStateButton };
37
37
  const buttonElementSymbol = Symbol("buttonElement");
38
38
  const innerDisabledObserverSymbol = Symbol("innerDisabledObserver");
39
39
  const popperElementSymbol = Symbol("popperElement");
40
+ const contentElementSymbol = Symbol("contentElement");
40
41
  const messageElementSymbol = Symbol("messageElement");
41
42
  const measurementPopperSymbol = Symbol("measurementPopper");
42
43
  const autoHideTimerSymbol = Symbol("autoHideTimer");
44
+ const MESSAGE_LAYOUT_OVERLAY = "overlay";
45
+ const MESSAGE_LAYOUT_PROSE = "prose";
46
+ const MESSAGE_LAYOUT_WIDE = "wide";
43
47
 
44
48
  /**
45
49
  * A specialized button component that combines state management with message display capabilities.
@@ -111,6 +115,8 @@ class MessageStateButton extends Popper {
111
115
  * @property {string|number} message.width.min Minimum width (px, rem, em, vw)
112
116
  * @property {string|number} message.width.max Maximum width (px, rem, em, vw)
113
117
  * @property {number} message.width.viewportRatio Max width as ratio of viewport width (0-1)
118
+ * @property {Object} popper Popper options inherited from the base popper
119
+ * @property {string} popper.contentOverflow Content clipping mode: both|horizontal|smart
114
120
  * @property {string} mode The mode of the button, can be `manual` or `submit`
115
121
  * @property {string} labels.button Button label
116
122
  * @property {Object} classes Classes for internal elements
@@ -122,20 +128,25 @@ class MessageStateButton extends Popper {
122
128
  * @property {string} aria.label Aria label for the button
123
129
  */
124
130
  get defaults() {
125
- return Object.assign({}, super.defaults, {
131
+ const defaults = super.defaults;
132
+
133
+ return Object.assign({}, defaults, {
126
134
  message: {
127
135
  title: undefined,
128
136
  content: undefined,
129
137
  icon: undefined,
130
138
  width: {
131
139
  min: "12rem",
132
- max: "32rem",
133
- viewportRatio: 0.7,
140
+ max: null,
141
+ viewportRatio: null,
134
142
  },
135
143
  },
136
144
  templates: {
137
145
  main: getTemplate(),
138
146
  },
147
+ popper: Object.assign({}, defaults.popper, {
148
+ contentOverflow: "smart",
149
+ }),
139
150
  mode: "manual",
140
151
  labels: {
141
152
  button: "<slot></slot>",
@@ -234,6 +245,8 @@ class MessageStateButton extends Popper {
234
245
  );
235
246
  }
236
247
 
248
+ applyResolvedMessagePresentation.call(this);
249
+
237
250
  return this;
238
251
  }
239
252
 
@@ -247,6 +260,7 @@ class MessageStateButton extends Popper {
247
260
  this.setOption("message.content", undefined);
248
261
  this.setOption("message.icon", undefined);
249
262
  clearAutoHideTimer.call(this);
263
+ applyResolvedMessagePresentation.call(this);
250
264
  return this;
251
265
  }
252
266
 
@@ -258,6 +272,7 @@ class MessageStateButton extends Popper {
258
272
  */
259
273
  showMessage(timeout) {
260
274
  clearAutoHideTimer.call(this);
275
+ applyResolvedMessagePresentation.call(this);
261
276
  applyMeasuredMessageWidth.call(this);
262
277
  this.showDialog.call(this);
263
278
 
@@ -287,6 +302,13 @@ class MessageStateButton extends Popper {
287
302
  return this;
288
303
  }
289
304
 
305
+ /**
306
+ * @return {string}
307
+ */
308
+ resolveContentOverflowMode() {
309
+ return resolveContentOverflowMode.call(this);
310
+ }
311
+
290
312
  /**
291
313
  *
292
314
  * @return {MessageStateButton}
@@ -438,9 +460,12 @@ function initControlReferences() {
438
460
  this[popperElementSymbol] = this.shadowRoot.querySelector(
439
461
  `[${ATTRIBUTE_ROLE}=popper]`,
440
462
  );
463
+ this[contentElementSymbol] =
464
+ this.shadowRoot.querySelector(`[part="content"]`);
441
465
  this[messageElementSymbol] = this.shadowRoot.querySelector(
442
466
  `[${ATTRIBUTE_ROLE}=message]`,
443
467
  );
468
+ applyResolvedMessagePresentation.call(this);
444
469
  }
445
470
 
446
471
  /**
@@ -534,8 +559,11 @@ function getTemplate() {
534
559
 
535
560
  <div data-monster-role="popper" part="popper" tabindex="-1" class="monster-color-primary-1">
536
561
  <div data-monster-role="arrow"></div>
537
- <div data-monster-role="message" part="message" class="flex"
538
- data-monster-patch="path:message.content"></div>
562
+ <div part="content"
563
+ class="flex">
564
+ <div data-monster-role="message" part="message" class="flex"
565
+ data-monster-patch="path:message.content"></div>
566
+ </div>
539
567
  </div>
540
568
  </div>
541
569
  </div>
@@ -561,7 +589,166 @@ function getMeasurementContent(content) {
561
589
 
562
590
  /**
563
591
  * @private
564
- * @return {{popper: HTMLElement, message: HTMLElement}|null}
592
+ * @return {void}
593
+ */
594
+ function applyResolvedMessagePresentation() {
595
+ const contentElement = this[contentElementSymbol];
596
+ const messageElement = this[messageElementSymbol];
597
+ const layoutMode = resolveMessageLayoutMode.call(this);
598
+ const overflowMode = this.resolveContentOverflowMode();
599
+
600
+ if (contentElement instanceof HTMLElement) {
601
+ contentElement.setAttribute("data-monster-overflow-mode", overflowMode);
602
+ contentElement.setAttribute("data-monster-message-layout", layoutMode);
603
+ }
604
+
605
+ if (messageElement instanceof HTMLElement) {
606
+ messageElement.setAttribute("data-monster-message-layout", layoutMode);
607
+ }
608
+
609
+ if (this[measurementPopperSymbol]?.content instanceof HTMLElement) {
610
+ this[measurementPopperSymbol].content.setAttribute(
611
+ "data-monster-overflow-mode",
612
+ overflowMode,
613
+ );
614
+ this[measurementPopperSymbol].content.setAttribute(
615
+ "data-monster-message-layout",
616
+ layoutMode,
617
+ );
618
+ }
619
+
620
+ if (this[measurementPopperSymbol]?.message instanceof HTMLElement) {
621
+ this[measurementPopperSymbol].message.setAttribute(
622
+ "data-monster-message-layout",
623
+ layoutMode,
624
+ );
625
+ }
626
+ }
627
+
628
+ /**
629
+ * @private
630
+ * @return {string}
631
+ */
632
+ function resolveContentOverflowMode() {
633
+ const configuredMode = this.getOption("popper.contentOverflow", "smart");
634
+
635
+ if (configuredMode !== "smart") {
636
+ return configuredMode;
637
+ }
638
+
639
+ if (resolveMessageLayoutMode.call(this) === MESSAGE_LAYOUT_OVERLAY) {
640
+ return "horizontal";
641
+ }
642
+
643
+ return "both";
644
+ }
645
+
646
+ /**
647
+ * @private
648
+ * @return {string}
649
+ */
650
+ function resolveMessageLayoutMode() {
651
+ const content = this.getOption("message.content");
652
+
653
+ if (containsNestedOverlayContent(content)) {
654
+ return MESSAGE_LAYOUT_OVERLAY;
655
+ }
656
+
657
+ if (containsWideContent(content)) {
658
+ return MESSAGE_LAYOUT_WIDE;
659
+ }
660
+
661
+ return MESSAGE_LAYOUT_PROSE;
662
+ }
663
+
664
+ /**
665
+ * @private
666
+ * @param {unknown} content
667
+ * @return {boolean}
668
+ */
669
+ function containsNestedOverlayContent(content) {
670
+ const selector = [
671
+ "monster-details",
672
+ "monster-message-state-button",
673
+ "monster-popper",
674
+ "monster-popper-button",
675
+ "monster-select",
676
+ "details",
677
+ ].join(",");
678
+
679
+ if (isString(content)) {
680
+ const container = document.createElement("div");
681
+ container.innerHTML = content;
682
+ return container.querySelector(selector) instanceof HTMLElement;
683
+ }
684
+
685
+ if (!(content instanceof HTMLElement)) {
686
+ return false;
687
+ }
688
+
689
+ if (content.matches(selector)) {
690
+ return true;
691
+ }
692
+
693
+ return content.querySelector(selector) instanceof HTMLElement;
694
+ }
695
+
696
+ /**
697
+ * @private
698
+ * @param {unknown} content
699
+ * @return {boolean}
700
+ */
701
+ function containsWideContent(content) {
702
+ const root = getContentSearchRoot(content);
703
+ if (!(root instanceof HTMLElement)) {
704
+ return false;
705
+ }
706
+
707
+ const selector = [
708
+ '[data-monster-message-layout="wide"]',
709
+ "pre",
710
+ "table",
711
+ '[style*="white-space: nowrap"]',
712
+ '[style*="white-space:nowrap"]',
713
+ '[style*="overflow-x: auto"]',
714
+ '[style*="overflow-x:auto"]',
715
+ '[style*="overflow-x: scroll"]',
716
+ '[style*="overflow-x:scroll"]',
717
+ '[style*="overflow: auto"]',
718
+ '[style*="overflow:auto"]',
719
+ '[style*="overflow: scroll"]',
720
+ '[style*="overflow:scroll"]',
721
+ ].join(",");
722
+
723
+ if (root.matches(selector)) {
724
+ return true;
725
+ }
726
+
727
+ return root.querySelector(selector) instanceof HTMLElement;
728
+ }
729
+
730
+ /**
731
+ * @private
732
+ * @param {unknown} content
733
+ * @return {HTMLElement|null}
734
+ */
735
+ function getContentSearchRoot(content) {
736
+ if (isString(content)) {
737
+ const container = document.createElement("div");
738
+ container.innerHTML = content;
739
+ return container;
740
+ }
741
+
742
+ if (content instanceof HTMLElement) {
743
+ return content;
744
+ }
745
+
746
+ return null;
747
+ }
748
+
749
+ /**
750
+ * @private
751
+ * @return {{popper: HTMLElement, content: HTMLElement, message: HTMLElement}|null}
565
752
  */
566
753
  function ensureMeasurementPopper() {
567
754
  if (this[measurementPopperSymbol]) {
@@ -588,14 +775,19 @@ function ensureMeasurementPopper() {
588
775
  popper.className = this[popperElementSymbol].className;
589
776
  }
590
777
 
778
+ const content = document.createElement("div");
779
+ content.setAttribute("part", "content");
780
+
591
781
  const message = document.createElement("div");
592
782
  message.setAttribute(ATTRIBUTE_ROLE, "message");
593
783
  message.className = "flex";
594
784
 
595
- popper.appendChild(message);
785
+ content.appendChild(message);
786
+ popper.appendChild(content);
596
787
  this.shadowRoot.appendChild(popper);
597
788
 
598
- this[measurementPopperSymbol] = { popper, message };
789
+ this[measurementPopperSymbol] = { popper, content, message };
790
+ applyResolvedMessagePresentation.call(this);
599
791
  return this[measurementPopperSymbol];
600
792
  }
601
793
 
@@ -623,6 +815,8 @@ function applyMeasuredMessageWidth() {
623
815
  measurement.popper.className = popper.className;
624
816
  }
625
817
 
818
+ applyResolvedMessagePresentation.call(this);
819
+
626
820
  measurement.message.innerHTML = "";
627
821
  if (isString(measureContent)) {
628
822
  measurement.message.innerHTML = measureContent;
@@ -637,6 +831,7 @@ function applyMeasuredMessageWidth() {
637
831
  const rootFontSize =
638
832
  parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
639
833
  const widthOptions = this.getOption("message.width", {});
834
+ const layoutMode = resolveMessageLayoutMode.call(this);
640
835
  const minWidthOption = resolveLength(
641
836
  widthOptions?.min,
642
837
  fontSize,
@@ -649,21 +844,23 @@ function applyMeasuredMessageWidth() {
649
844
  rootFontSize,
650
845
  window.innerWidth,
651
846
  );
652
- const viewportRatio =
653
- typeof widthOptions?.viewportRatio === "number" &&
654
- widthOptions.viewportRatio > 0 &&
655
- widthOptions.viewportRatio <= 1
656
- ? widthOptions.viewportRatio
657
- : 0.7;
847
+ const viewportPadding = rootFontSize * 2;
848
+ const viewportWidthLimit = Math.max(0, window.innerWidth - viewportPadding);
849
+ const viewportRatio = resolveViewportRatio(
850
+ widthOptions?.viewportRatio,
851
+ layoutMode,
852
+ );
853
+ const fallbackMaxWidth =
854
+ layoutMode === MESSAGE_LAYOUT_WIDE ? viewportWidthLimit : fontSize * 32;
658
855
 
659
856
  const minWidth = Math.max(0, minWidthOption ?? Math.round(fontSize * 12));
660
857
  const maxViewportWidth = Math.max(
661
858
  minWidth,
662
- window.innerWidth * viewportRatio,
859
+ Math.min(window.innerWidth * viewportRatio, viewportWidthLimit),
663
860
  );
664
861
  const maxWidth = Math.max(
665
862
  minWidth,
666
- Math.min(maxWidthOption ?? fontSize * 32, maxViewportWidth),
863
+ Math.min(maxWidthOption ?? fallbackMaxWidth, maxViewportWidth),
667
864
  );
668
865
  const targetWidth = Math.max(
669
866
  minWidth,
@@ -673,8 +870,27 @@ function applyMeasuredMessageWidth() {
673
870
  popper.style.width = `${targetWidth}px`;
674
871
  popper.style.minWidth = `${minWidth}px`;
675
872
  popper.style.maxWidth = `${maxWidth}px`;
676
- popper.style.whiteSpace = "normal";
677
- popper.style.overflowWrap = "anywhere";
873
+ popper.style.removeProperty("white-space");
874
+ popper.style.removeProperty("overflow-wrap");
875
+ }
876
+
877
+ /**
878
+ * @private
879
+ * @param {unknown} value
880
+ * @param {string} layoutMode
881
+ * @return {number}
882
+ */
883
+ function resolveViewportRatio(value, layoutMode) {
884
+ if (
885
+ typeof value === "number" &&
886
+ Number.isFinite(value) &&
887
+ value > 0 &&
888
+ value <= 1
889
+ ) {
890
+ return value;
891
+ }
892
+
893
+ return layoutMode === MESSAGE_LAYOUT_WIDE ? 1 : 0.7;
678
894
  }
679
895
 
680
896
  /**
@@ -25,9 +25,8 @@ import {
25
25
  import { isFunction } from "../../types/is.mjs";
26
26
  import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
27
27
  import { Popper } from "../layout/popper.mjs";
28
- import { STYLE_DISPLAY_MODE_BLOCK } from "./constants.mjs";
29
28
  import { PopperButtonStyleSheet } from "./stylesheet/popper-button.mjs";
30
- import { positionPopper } from "./util/floating-ui.mjs";
29
+ import { isPositionedPopperOpen, positionPopper } from "./util/floating-ui.mjs";
31
30
  import { AccessibilityStyleSheet } from "../stylesheet/accessibility.mjs";
32
31
  import "./button.mjs";
33
32
  import { addErrorAttribute } from "../../dom/error.mjs";
@@ -353,12 +352,16 @@ class PopperButton extends Popper {
353
352
  */
354
353
  function initEventHandler() {
355
354
  this[closeEventHandler] = (event) => {
356
- const path = event.composedPath();
357
-
358
- for (const [, element] of Object.entries(path)) {
359
- if (element === this) {
360
- return;
361
- }
355
+ if (
356
+ isEventInsidePopperButton(
357
+ this,
358
+ event,
359
+ this[controlElementSymbol],
360
+ this[buttonElementSymbol],
361
+ this[popperElementSymbol],
362
+ )
363
+ ) {
364
+ return;
362
365
  }
363
366
  this.hideDialog();
364
367
  };
@@ -366,6 +369,45 @@ function initEventHandler() {
366
369
  return this;
367
370
  }
368
371
 
372
+ function isEventInsidePopperButton(
373
+ owner,
374
+ event,
375
+ controlElement,
376
+ buttonElement,
377
+ popperElement,
378
+ ) {
379
+ const path = event.composedPath?.() || [];
380
+
381
+ for (const element of path) {
382
+ if (
383
+ element === owner ||
384
+ element === controlElement ||
385
+ element === buttonElement ||
386
+ element === popperElement
387
+ ) {
388
+ return true;
389
+ }
390
+ }
391
+
392
+ const target = path[0] || event.target;
393
+ if (!(target instanceof Node)) {
394
+ return false;
395
+ }
396
+
397
+ if (owner instanceof HTMLElement && owner.contains(target)) {
398
+ return true;
399
+ }
400
+
401
+ if (
402
+ owner?.shadowRoot instanceof ShadowRoot &&
403
+ owner.shadowRoot.contains(target)
404
+ ) {
405
+ return true;
406
+ }
407
+
408
+ return false;
409
+ }
410
+
369
411
  /**
370
412
  * @private
371
413
  */
@@ -408,7 +450,7 @@ function disconnectResizeObserver() {
408
450
  * @private
409
451
  */
410
452
  function updatePopper() {
411
- if (this[popperElementSymbol].style.display !== STYLE_DISPLAY_MODE_BLOCK) {
453
+ if (!isPositionedPopperOpen(this[popperElementSymbol])) {
412
454
  return;
413
455
  }
414
456
 
@@ -63,9 +63,13 @@ import { ProxyObserver } from "../../types/proxyobserver.mjs";
63
63
  import { validateArray, validateString } from "../../types/validate.mjs";
64
64
  import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
65
65
  import { Processing } from "../../util/processing.mjs";
66
- import { STYLE_DISPLAY_MODE_BLOCK } from "./constants.mjs";
67
66
  import { SelectStyleSheet } from "./stylesheet/select.mjs";
68
- import { positionPopper } from "./util/floating-ui.mjs";
67
+ import {
68
+ closePositionedPopper,
69
+ isPositionedPopperOpen,
70
+ openPositionedPopper,
71
+ positionPopper,
72
+ } from "./util/floating-ui.mjs";
69
73
  import { Pathfinder } from "../../data/pathfinder.mjs";
70
74
  import { TokenList } from "../../types/tokenlist.mjs";
71
75
 
@@ -381,6 +385,14 @@ class Select extends CustomControl {
381
385
  initOptionObserver.call(this);
382
386
  }
383
387
 
388
+ setOption(path, value) {
389
+ if (path === "features.closeOnSelect") {
390
+ this[closeOnSelectAutoSymbol] = false;
391
+ }
392
+
393
+ return super.setOption(path, value);
394
+ }
395
+
384
396
  /**
385
397
  * This method is called by the `instanceof` operator.
386
398
  * @return {Symbol}
@@ -3149,7 +3161,10 @@ function gatherState() {
3149
3161
  addErrorAttribute(this, e);
3150
3162
  });
3151
3163
 
3152
- if (this.getOption("features.closeOnSelect") === true) {
3164
+ if (
3165
+ this.getOption("features.closeOnSelect") === true &&
3166
+ isPositionedPopperOpen(this[popperElementSymbol])
3167
+ ) {
3153
3168
  hide.call(this);
3154
3169
  }
3155
3170
 
@@ -3717,7 +3732,7 @@ function fetchData(url) {
3717
3732
  * @private
3718
3733
  */
3719
3734
  function hide() {
3720
- this[popperElementSymbol].style.display = "none";
3735
+ closePositionedPopper(this[popperElementSymbol]);
3721
3736
  setStatusOrRemoveBadges.call(this, "closed");
3722
3737
  removeAttributeToken(this[controlElementSymbol], "class", "open");
3723
3738
  unregisterFromHost.call(this);
@@ -3733,7 +3748,7 @@ function show() {
3733
3748
  return;
3734
3749
  }
3735
3750
 
3736
- if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
3751
+ if (isPositionedPopperOpen(this[popperElementSymbol])) {
3737
3752
  return;
3738
3753
  }
3739
3754
 
@@ -3786,7 +3801,11 @@ function show() {
3786
3801
  }
3787
3802
 
3788
3803
  this[popperElementSymbol].style.visibility = "hidden";
3789
- this[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
3804
+ openPositionedPopper(
3805
+ this[controlElementSymbol],
3806
+ this[popperElementSymbol],
3807
+ this.getOption("popper", {}),
3808
+ );
3790
3809
  setStatusOrRemoveBadges.call(this, "open");
3791
3810
 
3792
3811
  addAttributeToken(this[controlElementSymbol], "class", "open");
@@ -3984,7 +4003,7 @@ function refreshSelectPaginationLayout() {
3984
4003
  * @private
3985
4004
  */
3986
4005
  function toggle() {
3987
- if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
4006
+ if (isPositionedPopperOpen(this[popperElementSymbol])) {
3988
4007
  hide.call(this);
3989
4008
  } else {
3990
4009
  show.call(this);
@@ -4053,12 +4072,16 @@ function initEventHandler() {
4053
4072
  * @param {Event} event
4054
4073
  */
4055
4074
  self[closeEventHandler] = (event) => {
4056
- const path = event.composedPath();
4057
-
4058
- for (const [, element] of Object.entries(path)) {
4059
- if (element === self) {
4060
- return;
4061
- }
4075
+ if (
4076
+ isEventInsideSelect(
4077
+ self,
4078
+ event,
4079
+ self[controlElementSymbol],
4080
+ self[containerElementSymbol],
4081
+ self[popperElementSymbol],
4082
+ )
4083
+ ) {
4084
+ return;
4062
4085
  }
4063
4086
  hide.call(self);
4064
4087
  };
@@ -4257,6 +4280,45 @@ function initEventHandler() {
4257
4280
  return self;
4258
4281
  }
4259
4282
 
4283
+ function isEventInsideSelect(
4284
+ owner,
4285
+ event,
4286
+ controlElement,
4287
+ containerElement,
4288
+ popperElement,
4289
+ ) {
4290
+ const path = event.composedPath?.() || [];
4291
+
4292
+ for (const element of path) {
4293
+ if (
4294
+ element === owner ||
4295
+ element === controlElement ||
4296
+ element === containerElement ||
4297
+ element === popperElement
4298
+ ) {
4299
+ return true;
4300
+ }
4301
+ }
4302
+
4303
+ const target = path[0] || event.target;
4304
+ if (!(target instanceof Node)) {
4305
+ return false;
4306
+ }
4307
+
4308
+ if (owner instanceof HTMLElement && owner.contains(target)) {
4309
+ return true;
4310
+ }
4311
+
4312
+ if (
4313
+ owner?.shadowRoot instanceof ShadowRoot &&
4314
+ owner.shadowRoot.contains(target)
4315
+ ) {
4316
+ return true;
4317
+ }
4318
+
4319
+ return false;
4320
+ }
4321
+
4260
4322
  /**
4261
4323
  * @private
4262
4324
  * @return {Select}
@@ -4395,7 +4457,7 @@ function initControlReferences() {
4395
4457
  * @private
4396
4458
  */
4397
4459
  function updatePopper() {
4398
- if (this[popperElementSymbol].style.display !== STYLE_DISPLAY_MODE_BLOCK) {
4460
+ if (!isPositionedPopperOpen(this[popperElementSymbol])) {
4399
4461
  return;
4400
4462
  }
4401
4463
 
@@ -32,6 +32,21 @@
32
32
  /* transform: translateY(0.15em);*/
33
33
  }
34
34
 
35
+ div[data-monster-role="popper"] {
36
+ max-width: min(var(--monster-popper-max-width, calc(100vw - 2rem)), 32rem);
37
+
38
+ & > [part="content"] {
39
+ display: block;
40
+ max-width: 100%;
41
+ max-height: none;
42
+ overflow: visible;
43
+ white-space: normal;
44
+ text-wrap: pretty;
45
+ word-break: break-word;
46
+ overflow-wrap: anywhere;
47
+ }
48
+ }
49
+
35
50
  :host([disabled]) [data-monster-role="button"] svg {
36
51
  cursor: default;
37
52
  pointer-events: none;
@@ -24,8 +24,20 @@
24
24
  }
25
25
  }
26
26
 
27
- [data-monster-role="popper"] {
27
+ div[data-monster-role="popper"] {
28
28
  z-index: var(--monster-z-index-tooltip-overlay);
29
+ max-width: min(var(--monster-popper-max-width, calc(100vw - 2rem)), 32rem);
30
+
31
+ & > [part="content"] {
32
+ display: block;
33
+ max-width: 100%;
34
+ max-height: none;
35
+ overflow: visible;
36
+ white-space: normal;
37
+ text-wrap: pretty;
38
+ word-break: break-word;
39
+ overflow-wrap: anywhere;
40
+ }
29
41
  }
30
42
 
31
43
  :host {