@watermarkinsights/ripple 5.20.0-alpha.7 → 5.20.0-alpha.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.
Files changed (161) hide show
  1. package/dist/cjs/{app-globals-25f6d847.js → app-globals-36cafd76.js} +1 -1
  2. package/dist/cjs/loader.cjs.js +2 -2
  3. package/dist/cjs/priv-option-list.cjs.entry.js +2 -4
  4. package/dist/cjs/ripple.cjs.js +2 -2
  5. package/dist/cjs/wm-option_2.cjs.entry.js +175 -95
  6. package/dist/cjs/wm-tab-item_3.cjs.entry.js +5 -5
  7. package/dist/collection/components/selects/priv-option-list/priv-option-list.js +2 -4
  8. package/dist/collection/components/selects/wm-select/wm-select.css +67 -55
  9. package/dist/collection/components/selects/wm-select/wm-select.js +186 -110
  10. package/dist/collection/components/wm-tabs/wm-tab-item/wm-tab-item.css +1 -0
  11. package/dist/collection/components/wm-tabs/wm-tab-list/wm-tab-list.css +1 -0
  12. package/dist/collection/components/wm-tabs/wm-tab-list/wm-tab-list.js +3 -3
  13. package/dist/esm/{app-globals-bbbe7a48.js → app-globals-89e7e2af.js} +1 -1
  14. package/dist/esm/{chartFunctions-3a54f8ac.js → chartFunctions-613e9c87.js} +1 -1
  15. package/dist/esm/{functions-669184a6.js → functions-38e392cb.js} +1 -1
  16. package/dist/esm/{intl-7906e2d7.js → intl-0b8f342e.js} +1 -1
  17. package/dist/esm/loader.js +2 -2
  18. package/dist/esm/priv-calendar.entry.js +1 -1
  19. package/dist/esm/priv-chart-popover.entry.js +1 -1
  20. package/dist/esm/priv-option-list.entry.js +4 -6
  21. package/dist/esm/ripple.js +2 -2
  22. package/dist/esm/wm-action-menu_2.entry.js +1 -1
  23. package/dist/esm/wm-button.entry.js +1 -1
  24. package/dist/esm/wm-chart.entry.js +3 -3
  25. package/dist/esm/wm-date-range.entry.js +1 -1
  26. package/dist/esm/wm-datepicker.entry.js +1 -1
  27. package/dist/esm/wm-file.entry.js +1 -1
  28. package/dist/esm/wm-flyout.entry.js +2 -2
  29. package/dist/esm/wm-input.entry.js +2 -2
  30. package/dist/esm/wm-line-chart.entry.js +3 -3
  31. package/dist/esm/wm-modal-pss_3.entry.js +2 -2
  32. package/dist/esm/wm-modal_3.entry.js +2 -2
  33. package/dist/esm/wm-navigation_3.entry.js +2 -2
  34. package/dist/esm/wm-navigator.entry.js +1 -1
  35. package/dist/esm/wm-nested-select.entry.js +2 -2
  36. package/dist/esm/wm-optgroup.entry.js +1 -1
  37. package/dist/esm/wm-option_2.entry.js +177 -97
  38. package/dist/esm/wm-pagination.entry.js +2 -2
  39. package/dist/esm/wm-progress-indicator_3.entry.js +2 -2
  40. package/dist/esm/wm-search.entry.js +2 -2
  41. package/dist/esm/wm-snackbar.entry.js +2 -2
  42. package/dist/esm/wm-tab-item_3.entry.js +6 -6
  43. package/dist/esm/wm-tag-input.entry.js +2 -2
  44. package/dist/esm/wm-tag-option.entry.js +1 -1
  45. package/dist/esm/wm-textarea.entry.js +2 -2
  46. package/dist/esm/wm-timepicker.entry.js +1 -1
  47. package/dist/esm/wm-toggletip.entry.js +1 -1
  48. package/dist/esm/wm-uploader.entry.js +2 -2
  49. package/dist/esm-es5/{app-globals-bbbe7a48.js → app-globals-89e7e2af.js} +1 -1
  50. package/dist/esm-es5/{chartFunctions-3a54f8ac.js → chartFunctions-613e9c87.js} +1 -1
  51. package/dist/esm-es5/{functions-669184a6.js → functions-38e392cb.js} +1 -1
  52. package/dist/esm-es5/{intl-7906e2d7.js → intl-0b8f342e.js} +1 -1
  53. package/dist/esm-es5/loader.js +1 -1
  54. package/dist/esm-es5/priv-calendar.entry.js +1 -1
  55. package/dist/esm-es5/priv-chart-popover.entry.js +1 -1
  56. package/dist/esm-es5/priv-option-list.entry.js +1 -1
  57. package/dist/esm-es5/ripple.js +1 -1
  58. package/dist/esm-es5/wm-action-menu_2.entry.js +1 -1
  59. package/dist/esm-es5/wm-button.entry.js +1 -1
  60. package/dist/esm-es5/wm-chart.entry.js +1 -1
  61. package/dist/esm-es5/wm-date-range.entry.js +1 -1
  62. package/dist/esm-es5/wm-datepicker.entry.js +1 -1
  63. package/dist/esm-es5/wm-file.entry.js +1 -1
  64. package/dist/esm-es5/wm-flyout.entry.js +1 -1
  65. package/dist/esm-es5/wm-input.entry.js +1 -1
  66. package/dist/esm-es5/wm-line-chart.entry.js +1 -1
  67. package/dist/esm-es5/wm-modal-pss_3.entry.js +1 -1
  68. package/dist/esm-es5/wm-modal_3.entry.js +1 -1
  69. package/dist/esm-es5/wm-navigation_3.entry.js +1 -1
  70. package/dist/esm-es5/wm-navigator.entry.js +1 -1
  71. package/dist/esm-es5/wm-nested-select.entry.js +1 -1
  72. package/dist/esm-es5/wm-optgroup.entry.js +1 -1
  73. package/dist/esm-es5/wm-option_2.entry.js +1 -1
  74. package/dist/esm-es5/wm-pagination.entry.js +1 -1
  75. package/dist/esm-es5/wm-progress-indicator_3.entry.js +1 -1
  76. package/dist/esm-es5/wm-search.entry.js +1 -1
  77. package/dist/esm-es5/wm-snackbar.entry.js +1 -1
  78. package/dist/esm-es5/wm-tab-item_3.entry.js +1 -1
  79. package/dist/esm-es5/wm-tag-input.entry.js +1 -1
  80. package/dist/esm-es5/wm-tag-option.entry.js +1 -1
  81. package/dist/esm-es5/wm-textarea.entry.js +1 -1
  82. package/dist/esm-es5/wm-timepicker.entry.js +1 -1
  83. package/dist/esm-es5/wm-toggletip.entry.js +1 -1
  84. package/dist/esm-es5/wm-uploader.entry.js +1 -1
  85. package/dist/ripple/{p-6d32911c.system.entry.js → p-00eaa361.system.entry.js} +1 -1
  86. package/dist/ripple/{p-c85dae6b.entry.js → p-0825151e.entry.js} +1 -1
  87. package/dist/ripple/{p-c70fa14f.entry.js → p-0bce3f83.entry.js} +1 -1
  88. package/dist/ripple/{p-69b38da5.entry.js → p-118093e1.entry.js} +1 -1
  89. package/dist/ripple/{p-de14d683.system.entry.js → p-17964357.system.entry.js} +1 -1
  90. package/dist/ripple/{p-bd37b0f9.system.entry.js → p-1a89139d.system.entry.js} +1 -1
  91. package/dist/ripple/{p-03759d86.system.entry.js → p-1fcf0ea8.system.entry.js} +1 -1
  92. package/dist/ripple/p-24594868.system.entry.js +1 -0
  93. package/dist/ripple/{p-bdac9bec.entry.js → p-2508b801.entry.js} +1 -1
  94. package/dist/ripple/{p-1027e508.entry.js → p-26ffcd83.entry.js} +1 -1
  95. package/dist/ripple/{p-55cdfcb4.system.entry.js → p-2b7259cb.system.entry.js} +1 -1
  96. package/dist/ripple/{p-ff6b7376.system.entry.js → p-2db6573e.system.entry.js} +1 -1
  97. package/dist/ripple/{p-1efa25b5.system.entry.js → p-3133ce3c.system.entry.js} +1 -1
  98. package/dist/ripple/{p-9ac6957b.entry.js → p-31bac55d.entry.js} +1 -1
  99. package/dist/ripple/{p-ce2d310c.entry.js → p-3612ee73.entry.js} +1 -1
  100. package/dist/ripple/{p-21c100d8.entry.js → p-39a4934f.entry.js} +1 -1
  101. package/dist/ripple/{p-54759960.entry.js → p-41664372.entry.js} +1 -1
  102. package/dist/ripple/{p-c8dfc321.system.entry.js → p-44cc05f6.system.entry.js} +1 -1
  103. package/dist/ripple/{p-c73882de.system.entry.js → p-4602304a.system.entry.js} +1 -1
  104. package/dist/ripple/{p-bb364d6b.entry.js → p-4b8f7d1e.entry.js} +1 -1
  105. package/dist/ripple/{p-b55883ee.entry.js → p-4d0abf7a.entry.js} +1 -1
  106. package/dist/ripple/{p-d99c9eb8.entry.js → p-4df8346a.entry.js} +1 -1
  107. package/dist/ripple/{p-9eaab627.system.entry.js → p-507ea41f.system.entry.js} +1 -1
  108. package/dist/ripple/{p-26ab5004.system.entry.js → p-5405df80.system.entry.js} +1 -1
  109. package/dist/ripple/{p-b9f36d37.entry.js → p-56b6d9f6.entry.js} +1 -1
  110. package/dist/ripple/{p-686b20f5.system.entry.js → p-56e376b2.system.entry.js} +1 -1
  111. package/dist/ripple/{p-88a7ccee.system.js → p-608971f2.system.js} +1 -1
  112. package/dist/ripple/{p-6ec4129b.entry.js → p-60e16c79.entry.js} +1 -1
  113. package/dist/ripple/{p-95f19440.system.js → p-65abcbb4.system.js} +1 -1
  114. package/dist/ripple/{p-65d3f9c4.system.entry.js → p-667fdcbb.system.entry.js} +1 -1
  115. package/dist/ripple/{p-68e90b50.system.entry.js → p-6a70dc0b.system.entry.js} +1 -1
  116. package/dist/ripple/{p-7394f4e9.system.entry.js → p-7134a305.system.entry.js} +1 -1
  117. package/dist/ripple/{p-24dcf159.entry.js → p-72e1fdb5.entry.js} +1 -1
  118. package/dist/ripple/{p-047e510d.entry.js → p-7c3bf608.entry.js} +1 -1
  119. package/dist/ripple/{p-176dcfc0.system.js → p-7edd25f7.system.js} +1 -1
  120. package/dist/ripple/{p-ebfa5876.entry.js → p-86a61a2a.entry.js} +1 -1
  121. package/dist/ripple/{p-eea39358.system.entry.js → p-8d1e0f23.system.entry.js} +1 -1
  122. package/dist/ripple/{p-009a6e5a.entry.js → p-8e2f3a45.entry.js} +1 -1
  123. package/dist/ripple/{p-a0ef456d.entry.js → p-8ec6ec53.entry.js} +1 -1
  124. package/dist/ripple/{p-71cc21a4.entry.js → p-908057b2.entry.js} +1 -1
  125. package/dist/ripple/{p-dbc3a44d.entry.js → p-9202d9e9.entry.js} +1 -1
  126. package/dist/ripple/{p-0ae9b6d3.js → p-92c8361f.js} +1 -1
  127. package/dist/ripple/{p-ad10664f.entry.js → p-957f13fb.entry.js} +1 -1
  128. package/dist/ripple/{p-1ad6c15b.entry.js → p-9609d8e7.entry.js} +1 -1
  129. package/dist/ripple/{p-3c9972a6.system.entry.js → p-960d2cf0.system.entry.js} +1 -1
  130. package/dist/ripple/{p-22d4c7e0.system.entry.js → p-96f86eb4.system.entry.js} +1 -1
  131. package/dist/ripple/{p-ea10c498.entry.js → p-9e89655f.entry.js} +1 -1
  132. package/dist/ripple/{p-f8fd7172.system.entry.js → p-a14dee02.system.entry.js} +1 -1
  133. package/dist/ripple/{p-222624ae.entry.js → p-a5c5c64c.entry.js} +1 -1
  134. package/dist/ripple/{p-dfa30c3d.entry.js → p-a7cde3fc.entry.js} +1 -1
  135. package/dist/ripple/{p-acb4d87c.system.entry.js → p-abcdd7be.system.entry.js} +1 -1
  136. package/dist/ripple/{p-f6ad9cc2.system.entry.js → p-b0da7ad4.system.entry.js} +1 -1
  137. package/dist/ripple/{p-6a40014e.system.entry.js → p-b1fb99e4.system.entry.js} +1 -1
  138. package/dist/ripple/{p-91669f66.js → p-b511ebfd.js} +1 -1
  139. package/dist/ripple/p-b5739e00.system.js +1 -0
  140. package/dist/ripple/p-b921ee01.entry.js +1 -0
  141. package/dist/ripple/{p-036fd03b.system.entry.js → p-bde7e77b.system.entry.js} +1 -1
  142. package/dist/ripple/{p-c0f4f1ea.system.entry.js → p-c7f3ef7f.system.entry.js} +1 -1
  143. package/dist/ripple/{p-1230edab.js → p-d2ae64dd.js} +1 -1
  144. package/dist/ripple/{p-1806e50b.js → p-d815809f.js} +1 -1
  145. package/dist/ripple/{p-fb61a10e.system.entry.js → p-e5c34af5.system.entry.js} +1 -1
  146. package/dist/ripple/{p-e1a15515.system.entry.js → p-e660d0b8.system.entry.js} +1 -1
  147. package/dist/ripple/{p-66489ded.entry.js → p-ecd1c2ba.entry.js} +1 -1
  148. package/dist/ripple/{p-1ef41643.system.js → p-ee89aa62.system.js} +1 -1
  149. package/dist/ripple/p-f11198be.entry.js +1 -0
  150. package/dist/ripple/{p-5bf2eb50.system.entry.js → p-f4390a0a.system.entry.js} +1 -1
  151. package/dist/ripple/{p-ae2520e4.entry.js → p-f91fc18d.entry.js} +1 -1
  152. package/dist/ripple/{p-1841c319.system.entry.js → p-f9bbb123.system.entry.js} +1 -1
  153. package/dist/ripple/{p-25c17efe.system.entry.js → p-fbad04d7.system.entry.js} +1 -1
  154. package/dist/ripple/ripple.esm.js +1 -1
  155. package/dist/ripple/ripple.js +1 -1
  156. package/dist/types/components/selects/wm-select/wm-select.d.ts +16 -9
  157. package/package.json +2 -2
  158. package/dist/ripple/p-6cbc9f7b.entry.js +0 -1
  159. package/dist/ripple/p-7d22f98e.system.entry.js +0 -1
  160. package/dist/ripple/p-9e1ea6e2.entry.js +0 -1
  161. package/dist/ripple/p-e4281595.system.js +0 -1
@@ -1,14 +1,20 @@
1
1
  import { h, Host } from "@stencil/core";
2
2
  import { forceUpdate } from "@stencil/core";
3
- import { getTextDir, shouldOpenUp, isElOrChild, toBool, handleDisabledAttribute, showTooltip, hideTooltip } from "../../../global/functions";
3
+ import { getTextDir, toBool, handleDisabledAttribute, showTooltip, hideTooltip, debounce, findAllScrollableParents, } from "../../../global/functions";
4
4
  import { globalMessages, selectMessages } from "../../../global/intl";
5
5
  export class Select {
6
6
  constructor() {
7
- this.openUp = false;
7
+ this.scrollableParents = [];
8
+ this.returnFocus = false;
9
+ this.hasAnchor = CSS.supports("top", "anchor(bottom)"); // for FF polyfill
8
10
  //////////////////////////////////////
9
11
  // for multiselect button text
10
12
  this.overflowCount = 0;
11
13
  this.displayedOptions = [];
14
+ this.previousDisplayedOptions = [];
15
+ this.debouncedReposition = debounce(() => {
16
+ this.dropdownPosition();
17
+ }, 100);
12
18
  this.disabled = false;
13
19
  this.maxHeight = "200px";
14
20
  this.label = undefined;
@@ -22,6 +28,8 @@ export class Select {
22
28
  this.searchPlaceholder = selectMessages.searchPlaceholder;
23
29
  this.allSelectedMessage = selectMessages.allSelected;
24
30
  this.isExpanded = false;
31
+ this.isHidden = false;
32
+ this.openUp = false;
25
33
  this.announcement = "";
26
34
  }
27
35
  get childOptions() {
@@ -40,58 +48,152 @@ export class Select {
40
48
  //////////////////////////////////////
41
49
  handleOptionSelection() {
42
50
  if (!this.multiple) {
43
- this.close();
51
+ this.returnFocus = true;
52
+ this.dropdownEl.hidePopover();
44
53
  }
45
54
  }
46
55
  handleChildEnter() {
47
56
  // only occurs for multiselects. handle the click, then close
48
- this.close();
49
- }
50
- closePopupOnEscape() {
51
- this.close();
52
- }
53
- handleOptionBlur(ev) {
54
- // if the Option is blurred to something other than the component emit a blur event with the appropriate relatedTarget
55
- // keeps our component's blur events accurate, and closes when focusing browser address bar
56
- if (!isElOrChild(this.el, ev.detail.relatedTarget)) {
57
- const event = new CustomEvent("blur");
58
- // @ts-ignore
59
- event.relatedTarget = ev.detail.relatedTarget;
60
- this.el.dispatchEvent(event);
57
+ this.returnFocus = true;
58
+ this.dropdownEl.hidePopover();
59
+ }
60
+ closeDropdownOnEscape() {
61
+ this.returnFocus = true;
62
+ this.dropdownEl.hidePopover();
63
+ }
64
+ handleBeforeToggle() {
65
+ if (!this.hasAnchor) {
66
+ // Start hidden to prevent flash during positioning calculation
67
+ this.isHidden = true;
61
68
  }
62
69
  }
63
- handleClick(ev) {
64
- if (!isElOrChild(this.el, ev.target)) {
65
- this.close();
70
+ handleToggle(ev) {
71
+ ev.newState === "open" ? this.open() : this.close();
72
+ }
73
+ dropdownPosition() {
74
+ // polyfill for opening up or down + positioning according to screen
75
+ // (must recalculate on scroll, resize)
76
+ // Using transform for better performance - only affects composite layer, no layout recalculation
77
+ const buttonElRect = this.buttonEl.getBoundingClientRect();
78
+ const spaceAbove = buttonElRect.top;
79
+ const spaceBelow = document.documentElement.clientHeight - buttonElRect.bottom;
80
+ const dropdownHeight = this.dropdownEl.clientHeight;
81
+ // Clear any previously set positioning properties
82
+ this.el.style.removeProperty("--dropdown-translate-y");
83
+ this.el.style.removeProperty("--dropdown-max-height");
84
+ this.el.style.removeProperty("--dropdown-left");
85
+ // Set horizontal position and width to match button
86
+ this.el.style.setProperty("--dropdown-left", buttonElRect.left + "px");
87
+ this.el.style.setProperty("--button-width", buttonElRect.width + "px");
88
+ if (dropdownHeight <= spaceBelow) {
89
+ // Case 1: Enough space below - position dropdown below the button
90
+ this.el.style.setProperty("--dropdown-translate-y", buttonElRect.bottom + "px");
91
+ }
92
+ else if (dropdownHeight <= spaceAbove) {
93
+ // Case 2: Not enough space below, but enough above - position dropdown above the button
94
+ this.el.style.setProperty("--dropdown-translate-y", buttonElRect.top - dropdownHeight + "px");
95
+ }
96
+ else {
97
+ // Case 3: Not enough space in either direction - use the larger available space and constrain height
98
+ if (spaceBelow >= spaceAbove) {
99
+ // Use space below and constrain dropdown height
100
+ this.el.style.setProperty("--dropdown-translate-y", buttonElRect.bottom + "px");
101
+ this.el.style.setProperty("--dropdown-max-height", spaceBelow + "px");
102
+ }
103
+ else {
104
+ // Use space above and constrain dropdown height
105
+ this.el.style.setProperty("--dropdown-translate-y", "0px");
106
+ this.el.style.setProperty("--dropdown-max-height", spaceAbove + "px");
107
+ }
66
108
  }
109
+ this.isHidden = false;
67
110
  }
68
- handleButtonBlur(ev) {
69
- if (isElOrChild(this.el, ev.relatedTarget)) {
70
- // do not emit a blur event when opening the dropdown and focusing the Options
71
- ev.stopPropagation();
111
+ open() {
112
+ if (!this.isExpanded && !this.isDisabled) {
113
+ // polyfill for browsers without anchor() support (FF)
114
+ if (!this.hasAnchor) {
115
+ this.dropdownPosition();
116
+ }
117
+ requestAnimationFrame(() => {
118
+ const anchorRect = this.buttonEl.getBoundingClientRect();
119
+ const hasSpaceBelow = this.dropdownEl.offsetHeight <= document.documentElement.clientHeight - anchorRect.bottom;
120
+ const hasSpaceAbove = this.dropdownEl.offsetHeight <= anchorRect.top;
121
+ this.openUp = !hasSpaceBelow && hasSpaceAbove;
122
+ this.isExpanded = true;
123
+ });
124
+ setTimeout(() => {
125
+ // focusing doesn't work when within requestAnimationFrame
126
+ this.optionListEl.handleInitialFocus(this.elToFocus);
127
+ this.elToFocus = undefined;
128
+ }, 50);
129
+ }
130
+ }
131
+ close() {
132
+ if (this.isExpanded) {
133
+ this.optionListEl.unfocusAll();
134
+ window.setTimeout(() => {
135
+ if (!this.hasAnchor) {
136
+ this.isHidden = true;
137
+ }
138
+ if (this.optionListEl.multiple) {
139
+ this.optionListEl.updateOptionVisibility();
140
+ }
141
+ // clear search field, reset filtered / bolded state of wm-options
142
+ if (this.search) {
143
+ this.optionListEl.clearSearch();
144
+ }
145
+ this.isExpanded = false;
146
+ }, 150);
147
+ if (this.returnFocus) {
148
+ requestAnimationFrame(() => {
149
+ this.buttonEl.focus();
150
+ this.returnFocus = false;
151
+ });
152
+ }
72
153
  }
73
154
  }
74
155
  handleKey(ev) {
75
156
  switch (ev.key) {
76
157
  case "Tab":
77
158
  // if tabbing backwards, close and return focus to button. Otherwise, close but do not redirect focus.
78
- this.close(ev.shiftKey ? true : false);
159
+ if (this.isExpanded && ev.shiftKey) {
160
+ this.returnFocus = true;
161
+ }
162
+ this.dropdownEl.hidePopover();
79
163
  break;
80
164
  case "ArrowDown":
81
165
  if (this.isExpanded === false) {
82
166
  ev.preventDefault();
83
- this.open("next");
167
+ this.elToFocus = "next";
168
+ this.dropdownEl.showPopover();
84
169
  }
85
170
  break;
86
171
  case "ArrowUp":
87
172
  if (this.isExpanded === false) {
88
173
  ev.preventDefault();
89
- this.open("previous");
174
+ this.elToFocus = "previous";
175
+ this.dropdownEl.showPopover();
90
176
  }
91
177
  break;
92
178
  }
93
179
  }
180
+ handleResize() {
181
+ if (!this.hasAnchor && this.isExpanded) {
182
+ this.isHidden = true;
183
+ this.debouncedReposition();
184
+ }
185
+ }
186
+ handleScroll() {
187
+ if (this.isExpanded) {
188
+ this.isHidden = true;
189
+ this.debouncedReposition();
190
+ }
191
+ }
94
192
  componentWillLoad() {
193
+ if (!this.hasAnchor) {
194
+ // Start hidden to prevent flash on first load
195
+ this.isHidden = true;
196
+ }
95
197
  if (!this.label) {
96
198
  console.error("For accessibility purposes, this component requires a label (even if `label-position` is set to `none`).");
97
199
  }
@@ -108,8 +210,6 @@ export class Select {
108
210
  });
109
211
  }
110
212
  handleChildChange() {
111
- // on update of children or children selected state, reset button text and rerender
112
- this.setButtonText();
113
213
  forceUpdate(this.el);
114
214
  if (this.multiple) {
115
215
  // update state of clone options
@@ -118,43 +218,19 @@ export class Select {
118
218
  }
119
219
  componentDidLoad() {
120
220
  this.wmSelectDidLoad.emit();
121
- this.dropdownEl.classList.add("hidden");
122
- forceUpdate(this.el);
123
- this.setButtonText();
124
- }
125
- open(optionToSelect) {
126
- if (!this.isDisabled) {
127
- this.openUp = shouldOpenUp(this.el, this.dropdownEl.clientHeight, this.labelEl.clientHeight);
128
- this.isExpanded = true;
129
- this.dropdownEl.classList.add("open");
130
- this.dropdownEl.classList.remove("hidden");
131
- window.requestAnimationFrame(() => {
132
- this.optionListEl.handleInitialFocus(optionToSelect);
133
- });
134
- }
135
- }
136
- close(returnFocus = true) {
137
- if (this.isExpanded) {
138
- this.isExpanded = false;
139
- this.optionListEl.unfocusAll();
140
- this.dropdownEl.classList.remove("open");
141
- window.setTimeout(() => {
142
- this.dropdownEl.classList.add("hidden");
143
- if (this.optionListEl.multiple) {
144
- this.optionListEl.updateOptionVisibility();
221
+ if (!this.hasAnchor) {
222
+ this.scrollableParents = findAllScrollableParents(this.el);
223
+ // Add scroll listeners to all scrollable parents
224
+ this.scrollableParents.forEach((parent) => {
225
+ if (parent === document.documentElement) {
226
+ // For document element, listen to window scroll event
227
+ window.addEventListener("scroll", () => this.handleScroll());
145
228
  }
146
- // clear search field, reset filtered / bolded state of wm-options
147
- if (this.search) {
148
- this.optionListEl.clearSearch();
149
- }
150
- // Returns focus to button after popup closes (no need if user is tabbing)
151
- // Delay is necessary for screenreader to get new expanded state before focus
152
- // window.requestAnimationFrame is probably enough, but since we are already using setTimeout it may as well be here
153
- // also UX wise, it makes sense for the button to only be focused after the animation is complete
154
- if (returnFocus) {
155
- this.buttonEl.focus();
229
+ else {
230
+ // For regular elements, listen to their scroll event
231
+ parent.addEventListener("scroll", () => this.handleScroll());
156
232
  }
157
- }, 150);
233
+ });
158
234
  }
159
235
  }
160
236
  announceError() {
@@ -168,7 +244,6 @@ export class Select {
168
244
  handleComponentBlur(ev) {
169
245
  // Do not close or emit custom blur event when blurring to an element inside (wm-option)
170
246
  if (!this.el.contains(ev.relatedTarget)) {
171
- this.close(false);
172
247
  this.wmSelectBlurred.emit();
173
248
  }
174
249
  }
@@ -178,28 +253,6 @@ export class Select {
178
253
  showTooltip("right", ev.target, this.label);
179
254
  }
180
255
  }
181
- setButtonText() {
182
- this.displayedOptions = this.childOptions.filter((x) => x.selected);
183
- // handle overflow + counter for multiselect
184
- if (this.multiple) {
185
- // this is a fixed measurement accounting for the max width of a 3 character overflow counter
186
- const overflowCounterWidth = 38;
187
- const computedStyle = window.getComputedStyle(this.buttonEl);
188
- // there seems to be no quick way to get an elements width without padding, except for subtracting padding manually
189
- const paddingLeft = parseInt(computedStyle.getPropertyValue("padding-left").slice(0, -2));
190
- const paddingRight = parseInt(computedStyle.getPropertyValue("padding-right").slice(0, -2));
191
- const availableSpace = this.buttonEl.clientWidth - paddingLeft - paddingRight - overflowCounterWidth;
192
- this.overflowCount = 0;
193
- this.measurementAreaEl.textContent = this.displayedOptions.map((x) => x.textContent).join(", ");
194
- let optionsTotalWidth = this.measurementAreaEl.clientWidth;
195
- while (optionsTotalWidth > availableSpace && this.displayedOptions.length > 1) {
196
- this.overflowCount++;
197
- this.displayedOptions.pop();
198
- this.measurementAreaEl.textContent = this.displayedOptions.map((x) => x.textContent).join(", ");
199
- optionsTotalWidth = this.measurementAreaEl.clientWidth;
200
- }
201
- }
202
- }
203
256
  announce(message) {
204
257
  // \u00A0 is a non-breaking space character, which causes the message to be read as a new one
205
258
  if (this.liveRegionEl.textContent === message) {
@@ -208,6 +261,7 @@ export class Select {
208
261
  this.announcement = message;
209
262
  }
210
263
  renderButtonText() {
264
+ this.displayedOptions = this.childOptions.filter((x) => x.selected);
211
265
  if (this.multiple && this.displayedOptions.length < 1) {
212
266
  return h("span", null, this.placeholder);
213
267
  }
@@ -215,6 +269,28 @@ export class Select {
215
269
  return this.allSelectedMessage;
216
270
  }
217
271
  else {
272
+ // handle overflow + counter for multiselect
273
+ // only bother if things have changed
274
+ const hasChanged = this.displayedOptions !== this.previousDisplayedOptions;
275
+ if (this.multiple && hasChanged) {
276
+ // this is a fixed measurement accounting for the max width of a 3 character overflow counter
277
+ const overflowCounterWidth = 38;
278
+ const computedStyle = window.getComputedStyle(this.buttonEl);
279
+ // there seems to be no quick way to get an elements width without padding, except for subtracting padding manually
280
+ const paddingLeft = parseInt(computedStyle.getPropertyValue("padding-left").slice(0, -2));
281
+ const paddingRight = parseInt(computedStyle.getPropertyValue("padding-right").slice(0, -2));
282
+ const availableSpace = this.buttonEl.clientWidth - paddingLeft - paddingRight - overflowCounterWidth;
283
+ this.overflowCount = 0;
284
+ this.measurementAreaEl.textContent = this.displayedOptions.map((x) => x.textContent).join(", ");
285
+ let optionsTotalWidth = this.measurementAreaEl.clientWidth;
286
+ while (optionsTotalWidth > availableSpace && this.displayedOptions.length > 1) {
287
+ this.overflowCount++;
288
+ this.displayedOptions.pop();
289
+ this.measurementAreaEl.textContent = this.displayedOptions.map((x) => x.textContent).join(", ");
290
+ optionsTotalWidth = this.measurementAreaEl.clientWidth;
291
+ }
292
+ this.previousDisplayedOptions = this.displayedOptions;
293
+ }
218
294
  return this.displayedOptions.map((x, idx) => (h("span", null, idx > 0 ? ", " : "", x.textContent)));
219
295
  }
220
296
  }
@@ -225,18 +301,22 @@ export class Select {
225
301
  }
226
302
  render() {
227
303
  const showSubinfo = !this.multiple && this.selectedOptions.length > 0 && this.selectedOptions[0].subinfo;
228
- const buttonProps = {
229
- id: "selectbtn",
230
- ["disabled"]: this.isDisabled,
231
- ["aria-controls"]: "list",
232
- ["aria-labelledby"]: "label selectbtn",
233
- ["aria-describedby"]: "error",
234
- ["aria-expanded"]: this.isExpanded ? "true" : "false",
235
- onClick: () => (this.isExpanded ? this.close() : this.open()),
236
- };
237
- return (h(Host, { key: '27f57d30b836eac8dc27ae98a425015d86a0948b', onBlur: (ev) => this.handleComponentBlur(ev) }, h("div", { key: '8f48d8e8d616244350e61d6e81f350640131bbf0', class: `wrapper ${getTextDir()} label-${this.labelPosition} ${this.errorMessage ? "invalid" : ""}` }, h("div", { key: '39d3bcec9b67d671a6bdbb6a3ee738832189ea51', ref: (el) => (this.labelEl = el), class: "label-wrapper" }, h("label", { key: 'b0bb90a215ac20de94afa8dba56e839bdc590dc1', class: "label", id: "label", htmlFor: "selectbtn", onMouseEnter: (ev) => this.handleLabelMouseEnter(ev), onMouseLeave: () => hideTooltip() }, this.label),
304
+ return (h(Host, { key: '4ec7d687b40ffcef80fbce21e6880680c72d03a7', onBlur: (ev) => this.handleComponentBlur(ev) }, h("div", { key: 'c400196d862a763af6f4f5d4663a8f3e805a9ddd', class: `wrapper ${getTextDir()} label-${this.labelPosition} ${this.errorMessage ? "invalid" : ""}` }, h("div", { key: '1c7df9eee5ebc62a12bd36e97918e144c7e4dc72', class: "label-wrapper" }, h("label", { key: '752c9ce6491c959afda2105a5e2c6063ce4ee52e', class: "label", id: "label", htmlFor: "selectbtn", onMouseEnter: (ev) => this.handleLabelMouseEnter(ev), onMouseLeave: () => hideTooltip() }, this.label),
238
305
  // we can't use aria-required because the listbox is in a sub-component and it is not announced
239
- this.requiredField && (h("span", { key: '4a5648503a023ff1eba34db936d49709e14da9f1', class: "required" }, h("span", { key: '3fe783c7174d3d827b20589cad412d32fa4cd978', class: "sr-only" }, globalMessages.requiredField), h("span", { key: '85ac4ca35f1077ade1bdda403b8888cc206ff28e', "aria-hidden": "true" }, "*")))), h("div", { key: 'c2e70d87db2d533713ac9c5a877ddba98a9a9a2f', class: "button-wrapper" }, h("button", Object.assign({ key: '460c6ac5cde8637b0098201966ca4268301ac2b7' }, buttonProps, { class: "displayedoption", ref: (el) => (this.buttonEl = el), onBlur: (ev) => this.handleButtonBlur(ev) }), h("span", { key: '3af3357f45ceacc5689e90e2bdc6459cab591c2f', class: `overflowcontrol ${showSubinfo ? "hassubinfo" : ""}` }, h("span", { key: 'bd9869db1146e54cc47c2965ebe2776873e2a18e', class: "button-text" }, this.renderButtonText()), showSubinfo && h("span", { key: 'b22d952625e93fab98ebb1b688101fd8891a4af7', class: "subinfo" }, this.selectedOptions[0].subinfo)), h("div", { key: '1f6448ee167d1847eff8fb5bc7a30e0a964e6efe', class: `expand-icon svg-icon ${this.isExpanded ? "svg-expand-less" : "svg-expand-more"}` }), this.renderOverflowCount(), h("div", { key: '0d550b97a3e08e9b708f2f4c3d91f9cac76ba5d8', ref: (el) => (this.measurementAreaEl = el), class: "measurement-area", "aria-hidden": "true" })), h("div", { key: '59cc7fcfa25d9d3eab8e4d70cdcd365e36e160ad', class: `dropdown ${this.isExpanded ? "open" : ""} ${this.openUp ? "upwards" : ""}`, ref: (el) => (this.dropdownEl = el) }, h("priv-option-list", { key: '9fb7d0396527bc18bb8f5d00d64c858470d0698d', ref: (el) => (this.optionListEl = el), multiple: this.multiple, search: this.search, selectAll: this.selectAll, maxHeight: this.maxHeight, searchPlaceholder: this.searchPlaceholder, onOptionListCloseRequested: () => this.close(), onOptionListAllSelected: () => this.wmSelectAllSelected.emit(), onOptionListAllDeselected: () => this.wmSelectAllDeselected.emit() }, h("slot", { key: '4c307bca5104ec962ca050b46adf882fb78bb74a' }))), h("div", { key: '06f11b61b475cc6cd78c2a8278b8455a79405e17', id: "error", class: this.errorMessage ? "error-message" : "" }, this.errorMessage), h("div", { key: '86cf865fbb7fd0e2c88290fe92e6062ada7d9ab6', id: "announcement", "aria-live": "polite", "aria-atomic": "true", class: "sr-only", ref: (el) => (this.liveRegionEl = el) }, this.announcement)))));
306
+ this.requiredField && (h("span", { key: 'c0b4660ed16129c1a3aaf5252aa5e7c71eb42f20', class: "required" }, h("span", { key: '8c4a41df3473c88021f8d73f09fdfd33e3ad1c48', class: "sr-only" }, globalMessages.requiredField), h("span", { key: '303e6f18bef3d30b32508c6192ac363bbc8fb80c', "aria-hidden": "true" }, "*")))), h("div", { key: '7acc269a0e60042549cbc3fc6879b3e471f1b016', class: "button-wrapper" }, h("button", { key: 'd1e7751c22951130f92ca6fdc2c9f253e4e63b5b', id: "selectbtn", disabled: this.isDisabled, "aria-labelledby": "label selectbtn", "aria-describedby": "error", popoverTarget: "dropdown", popoverTargetAction: "toggle", class: "displayedoption", ref: (el) => (this.buttonEl = el) }, h("span", { key: '6236a027968e849c873e1d09bf89910ca627b760', class: `overflowcontrol ${showSubinfo ? "hassubinfo" : ""}` }, h("span", { key: '3af139e809e636873cd53dfb53141c0c606e4963', class: "button-text" }, this.renderButtonText()), showSubinfo && h("span", { key: '5894b37ef490101b0ba38547745f450c0521a8ea', class: "subinfo" }, this.selectedOptions[0].subinfo)), h("div", { key: '6bce5cbddd6160c0d2eeb8de27ed7f0d46fffb38', class: `expand-icon svg-icon ${this.isExpanded ? "svg-expand-less" : "svg-expand-more"}` }), this.renderOverflowCount(), h("div", { key: 'a0d9da60b818f8a576f6fcaab422b9ec31d42fd4', ref: (el) => (this.measurementAreaEl = el), class: "measurement-area", "aria-hidden": "true" })), h("div", { key: 'dc70db1f203700702cf3586412eef64ab108b86f',
307
+ // is-open is for the CSS transition in modern browsers
308
+ // hidden is to wait for position calculations in Firefox
309
+ class: `dropdown ${this.isExpanded ? "is-open" : ""} ${this.isHidden ? "hidden" : ""} ${this.openUp ? "upward" : ""}`, id: "dropdown", popover: "auto", ref: (el) => (this.dropdownEl = el),
310
+ // @ts-ignore -- don't tell typescript but we're in the future
311
+ onToggle: (ev) => this.handleToggle(ev) }, h("priv-option-list", { key: '09db81570f9990ec4cf87f16b52320ec82701a04', ref: (el) => (this.optionListEl = el), multiple: this.multiple, search: this.search, selectAll: this.selectAll, maxHeight: this.maxHeight, searchPlaceholder: this.searchPlaceholder, onOptionListCloseRequested: () => {
312
+ this.dropdownEl.hidePopover();
313
+ }, onOptionListAllSelected: () => {
314
+ this.returnFocus = true;
315
+ this.wmSelectAllSelected.emit();
316
+ }, onOptionListAllDeselected: () => {
317
+ this.returnFocus = true;
318
+ this.wmSelectAllDeselected.emit();
319
+ } }, h("slot", { key: '420515d805ad1039ed3b72bd2968a0a29c27a5fc' }))), h("div", { key: '3bda216f90f3d6b10b92034996d3bdc90a4ffd60', id: "error", class: this.errorMessage ? "error-message" : "" }, this.errorMessage), h("div", { key: '032fb47f7c64c04d518740dbcb31efcd761baed6', id: "announcement", "aria-live": "polite", "aria-atomic": "true", class: "sr-only", ref: (el) => (this.liveRegionEl = el) }, this.announcement)))));
240
320
  }
241
321
  static get is() { return "wm-select"; }
242
322
  static get encapsulation() { return "shadow"; }
@@ -472,6 +552,8 @@ export class Select {
472
552
  static get states() {
473
553
  return {
474
554
  "isExpanded": {},
555
+ "isHidden": {},
556
+ "openUp": {},
475
557
  "announcement": {}
476
558
  };
477
559
  }
@@ -563,28 +645,22 @@ export class Select {
563
645
  "passive": false
564
646
  }, {
565
647
  "name": "wmEscKeyPressed",
566
- "method": "closePopupOnEscape",
648
+ "method": "closeDropdownOnEscape",
567
649
  "target": undefined,
568
650
  "capture": false,
569
651
  "passive": false
570
- }, {
571
- "name": "wmOptionBlurred",
572
- "method": "handleOptionBlur",
573
- "target": undefined,
574
- "capture": false,
575
- "passive": false
576
- }, {
577
- "name": "click",
578
- "method": "handleClick",
579
- "target": "document",
580
- "capture": true,
581
- "passive": false
582
652
  }, {
583
653
  "name": "keydown",
584
654
  "method": "handleKey",
585
655
  "target": undefined,
586
656
  "capture": false,
587
657
  "passive": false
658
+ }, {
659
+ "name": "resize",
660
+ "method": "handleResize",
661
+ "target": "window",
662
+ "capture": false,
663
+ "passive": true
588
664
  }];
589
665
  }
590
666
  }
@@ -903,6 +903,7 @@
903
903
  white-space: normal;
904
904
  word-break: break-word;
905
905
  width: 100%;
906
+ text-align: center;
906
907
  }
907
908
  .tab-item .tab[aria-selected=true] {
908
909
  font-weight: 700;
@@ -911,6 +911,7 @@
911
911
  }
912
912
  :host wm-button.left-arrow,
913
913
  :host wm-button.right-arrow {
914
+ --icon-size: 1.25rem;
914
915
  display: none;
915
916
  flex-shrink: 0;
916
917
  }
@@ -261,15 +261,15 @@ export class TabList {
261
261
  "margin-inline": "-" + this.customPadding,
262
262
  };
263
263
  }
264
- return (h(Host, { key: '951f6dcf457201034adca055366df0107df6a116' }, h("div", { key: '489cf5f1acf3c985c6208e9b5b6f507422251c6c', class: "component-wrapper", style: margins }, h("wm-button", { key: '062540e6c8a16182f17bdc6d47c5add7635a66b1', class: `left-arrow ${this.scrollArrowsVisible ? "visible" : ""}`, "aria-controls": "tablist", customBackground: this.customBackground, buttonType: "navigational", icon: "chevron-left", tooltip: intl.formatMessage({
264
+ return (h(Host, { key: '951f6dcf457201034adca055366df0107df6a116' }, h("div", { key: '489cf5f1acf3c985c6208e9b5b6f507422251c6c', class: "component-wrapper", style: margins }, h("wm-button", { key: 'c83f686c864b91ef3ac2530a47196e3a767b8609', class: `left-arrow ${this.scrollArrowsVisible ? "visible" : ""}`, "aria-controls": "tablist", customBackground: this.customBackground, buttonType: "navigational", icon: "#previous", tooltip: intl.formatMessage({
265
265
  id: "tabs.showPreviousTabs",
266
266
  defaultMessage: "Show previous tabs",
267
267
  description: "Tooltip for button scrolling tab group.",
268
- }), onClick: (ev) => this.handleLeftArrowClick(ev) }), h("ul", { key: 'bcf105f97872f8c7384db699174e475d39a499d7', id: "tablist", ref: (el) => (this.tabContainerEl = el), class: `tabcontainer ${this.customBackground || ""} ${this.containerFadeLeft ? "fade-left" : ""} ${this.containerFadeRight ? "fade-right" : ""}`, role: "tablist", tabIndex: -1 }, h("slot", { key: 'b246faf22421f7809c35f866f1db7c67a34b81e5' })), h("wm-button", { key: '20c961f2dd956363348c627babff111efd53c788', class: `right-arrow ${this.scrollArrowsVisible ? "visible" : ""}`, "aria-controls": "tablist", customBackground: this.customBackground, buttonType: "navigational", icon: "chevron-right", tooltip: intl.formatMessage({
268
+ }), onClick: (ev) => this.handleLeftArrowClick(ev) }), h("ul", { key: 'ed524296e4c43f0602c54dc7345cb9403f491e82', id: "tablist", ref: (el) => (this.tabContainerEl = el), class: `tabcontainer ${this.customBackground || ""} ${this.containerFadeLeft ? "fade-left" : ""} ${this.containerFadeRight ? "fade-right" : ""}`, role: "tablist", tabIndex: -1 }, h("slot", { key: '072e8fdff4e4831df0f89002475acd29ef2633d3' })), h("wm-button", { key: '4364a7c4d9ffde71307573bf08c48e8cbba06372', class: `right-arrow ${this.scrollArrowsVisible ? "visible" : ""}`, "aria-controls": "tablist", customBackground: this.customBackground, buttonType: "navigational", icon: "#next", tooltip: intl.formatMessage({
269
269
  id: "tabs.showNextTabs",
270
270
  defaultMessage: "Show next tabs",
271
271
  description: "Tooltip for button scrolling tab group.",
272
- }), onClick: (ev) => this.handleRightArrowClick(ev) }), h("span", { key: '36dc64a76fb0d4061c2123b7734fb85a89a79a43', "aria-live": "assertive", class: "sr-only", ref: (el) => (this.liveRegionEl = el) }, this.announcement))));
272
+ }), onClick: (ev) => this.handleRightArrowClick(ev) }), h("span", { key: 'c347bc2cb5002812bc4c14ef442ae7d820138ac8', "aria-live": "assertive", class: "sr-only", ref: (el) => (this.liveRegionEl = el) }, this.announcement))));
273
273
  }
274
274
  static get is() { return "wm-tab-list"; }
275
275
  static get encapsulation() { return "shadow"; }
@@ -1,6 +1,6 @@
1
1
  import './index-130e07bb.js';
2
2
 
3
- const version = "5.20.0-alpha.7";
3
+ const version = "5.20.0-alpha.9";
4
4
 
5
5
  // PRINT RIPPLE VERSION IN CONSOLE
6
6
  // test envs return 0 for plugin.length
@@ -1,5 +1,5 @@
1
1
  import { h } from './index-130e07bb.js';
2
- import { i as intl, c as checkForActiveElInShadow, e as safeMultiplyFloat, f as getPosition } from './functions-669184a6.js';
2
+ import { i as intl, c as checkForActiveElInShadow, e as safeMultiplyFloat, f as getPosition } from './functions-38e392cb.js';
3
3
 
4
4
  const colors = {
5
5
  salmon: "#ff5f4e",
@@ -10585,4 +10585,4 @@ const weekdays = [
10585
10585
  intl.formatMessage({ id: "date.saturday", defaultMessage: "Saturday" }),
10586
10586
  ];
10587
10587
 
10588
- export { findPrev as A, getTextDir as B, isElOrChild as C, throttle as D, getContextMeasurements as E, dateFind as F, calendar_months as G, findParentWithHiddenOverflow as H, transposeMatrix as I, wrapAround as J, getSmallestSkipInterval as K, calcPercentageInRange as L, makeISO as M, getMonthLength as N, weekdays as O, handleDisabledAttribute as a, triggerFormSubmit as b, checkForActiveElInShadow as c, debounce as d, safeMultiplyFloat as e, getPosition as f, generateId as g, hideTooltip as h, intl as i, findAllScrollableParents as j, dateToISO as k, shouldOpenUp as l, hasRoomRight as m, truncateText as n, getLastFocusableDescendant as o, csvToArray as p, snakeCaseToCamelCase as q, getNewIndexToFocus as r, showTooltip as s, toBool as t, getCumulativeScrollOffset as u, shouldOpenDown as v, shouldShiftRight as w, shouldShiftLeft as x, measureText as y, findNext as z };
10588
+ export { findPrev as A, getTextDir as B, throttle as C, getContextMeasurements as D, dateFind as E, calendar_months as F, findParentWithHiddenOverflow as G, transposeMatrix as H, wrapAround as I, getSmallestSkipInterval as J, calcPercentageInRange as K, isElOrChild as L, makeISO as M, getMonthLength as N, weekdays as O, handleDisabledAttribute as a, triggerFormSubmit as b, checkForActiveElInShadow as c, debounce as d, safeMultiplyFloat as e, getPosition as f, generateId as g, hideTooltip as h, intl as i, findAllScrollableParents as j, dateToISO as k, shouldOpenUp as l, hasRoomRight as m, truncateText as n, getLastFocusableDescendant as o, csvToArray as p, snakeCaseToCamelCase as q, getNewIndexToFocus as r, showTooltip as s, toBool as t, getCumulativeScrollOffset as u, shouldOpenDown as v, shouldShiftRight as w, shouldShiftLeft as x, measureText as y, findNext as z };
@@ -1,4 +1,4 @@
1
- import { i as intl } from './functions-669184a6.js';
1
+ import { i as intl } from './functions-38e392cb.js';
2
2
 
3
3
  const globalMessages = {
4
4
  characterLimitReached: intl.formatMessage({