@watermarkinsights/ripple 5.19.1-alpha.2 → 5.20.0-alpha.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.
Files changed (159) hide show
  1. package/dist/cjs/{app-globals-ad5069a2.js → app-globals-b26975cf.js} +1 -1
  2. package/dist/cjs/loader.cjs.js +2 -2
  3. package/dist/cjs/priv-option-list.cjs.entry.js +4 -2
  4. package/dist/cjs/ripple.cjs.js +2 -2
  5. package/dist/cjs/wm-option_2.cjs.entry.js +95 -186
  6. package/dist/cjs/wm-toggletip.cjs.entry.js +4 -4
  7. package/dist/collection/components/selects/priv-option-list/priv-option-list.js +4 -2
  8. package/dist/collection/components/selects/wm-select/wm-select.css +51 -79
  9. package/dist/collection/components/selects/wm-select/wm-select.js +110 -197
  10. package/dist/collection/components/wm-toggletip/wm-toggletip.js +4 -4
  11. package/dist/esm/{app-globals-14723564.js → app-globals-0290058e.js} +1 -1
  12. package/dist/esm/{chartFunctions-613e9c87.js → chartFunctions-3a54f8ac.js} +1 -1
  13. package/dist/esm/{functions-38e392cb.js → functions-669184a6.js} +1 -1
  14. package/dist/esm/{intl-0b8f342e.js → intl-7906e2d7.js} +1 -1
  15. package/dist/esm/loader.js +2 -2
  16. package/dist/esm/priv-calendar.entry.js +1 -1
  17. package/dist/esm/priv-chart-popover.entry.js +1 -1
  18. package/dist/esm/priv-option-list.entry.js +6 -4
  19. package/dist/esm/ripple.js +2 -2
  20. package/dist/esm/wm-action-menu_2.entry.js +1 -1
  21. package/dist/esm/wm-button.entry.js +1 -1
  22. package/dist/esm/wm-chart.entry.js +3 -3
  23. package/dist/esm/wm-date-range.entry.js +1 -1
  24. package/dist/esm/wm-datepicker.entry.js +1 -1
  25. package/dist/esm/wm-file.entry.js +1 -1
  26. package/dist/esm/wm-flyout.entry.js +2 -2
  27. package/dist/esm/wm-input.entry.js +2 -2
  28. package/dist/esm/wm-line-chart.entry.js +3 -3
  29. package/dist/esm/wm-modal-pss_3.entry.js +2 -2
  30. package/dist/esm/wm-modal_3.entry.js +2 -2
  31. package/dist/esm/wm-navigation_3.entry.js +2 -2
  32. package/dist/esm/wm-navigator.entry.js +1 -1
  33. package/dist/esm/wm-nested-select.entry.js +2 -2
  34. package/dist/esm/wm-optgroup.entry.js +1 -1
  35. package/dist/esm/wm-option_2.entry.js +97 -188
  36. package/dist/esm/wm-pagination.entry.js +2 -2
  37. package/dist/esm/wm-progress-indicator_3.entry.js +2 -2
  38. package/dist/esm/wm-search.entry.js +2 -2
  39. package/dist/esm/wm-snackbar.entry.js +2 -2
  40. package/dist/esm/wm-tab-item_3.entry.js +1 -1
  41. package/dist/esm/wm-tag-input.entry.js +2 -2
  42. package/dist/esm/wm-tag-option.entry.js +1 -1
  43. package/dist/esm/wm-textarea.entry.js +2 -2
  44. package/dist/esm/wm-timepicker.entry.js +1 -1
  45. package/dist/esm/wm-toggletip.entry.js +5 -5
  46. package/dist/esm/wm-uploader.entry.js +2 -2
  47. package/dist/esm-es5/{app-globals-14723564.js → app-globals-0290058e.js} +1 -1
  48. package/dist/esm-es5/{chartFunctions-613e9c87.js → chartFunctions-3a54f8ac.js} +1 -1
  49. package/dist/esm-es5/{functions-38e392cb.js → functions-669184a6.js} +1 -1
  50. package/dist/esm-es5/{intl-0b8f342e.js → intl-7906e2d7.js} +1 -1
  51. package/dist/esm-es5/loader.js +1 -1
  52. package/dist/esm-es5/priv-calendar.entry.js +1 -1
  53. package/dist/esm-es5/priv-chart-popover.entry.js +1 -1
  54. package/dist/esm-es5/priv-option-list.entry.js +1 -1
  55. package/dist/esm-es5/ripple.js +1 -1
  56. package/dist/esm-es5/wm-action-menu_2.entry.js +1 -1
  57. package/dist/esm-es5/wm-button.entry.js +1 -1
  58. package/dist/esm-es5/wm-chart.entry.js +1 -1
  59. package/dist/esm-es5/wm-date-range.entry.js +1 -1
  60. package/dist/esm-es5/wm-datepicker.entry.js +1 -1
  61. package/dist/esm-es5/wm-file.entry.js +1 -1
  62. package/dist/esm-es5/wm-flyout.entry.js +1 -1
  63. package/dist/esm-es5/wm-input.entry.js +1 -1
  64. package/dist/esm-es5/wm-line-chart.entry.js +1 -1
  65. package/dist/esm-es5/wm-modal-pss_3.entry.js +1 -1
  66. package/dist/esm-es5/wm-modal_3.entry.js +1 -1
  67. package/dist/esm-es5/wm-navigation_3.entry.js +1 -1
  68. package/dist/esm-es5/wm-navigator.entry.js +1 -1
  69. package/dist/esm-es5/wm-nested-select.entry.js +1 -1
  70. package/dist/esm-es5/wm-optgroup.entry.js +1 -1
  71. package/dist/esm-es5/wm-option_2.entry.js +1 -1
  72. package/dist/esm-es5/wm-pagination.entry.js +1 -1
  73. package/dist/esm-es5/wm-progress-indicator_3.entry.js +1 -1
  74. package/dist/esm-es5/wm-search.entry.js +1 -1
  75. package/dist/esm-es5/wm-snackbar.entry.js +1 -1
  76. package/dist/esm-es5/wm-tab-item_3.entry.js +1 -1
  77. package/dist/esm-es5/wm-tag-input.entry.js +1 -1
  78. package/dist/esm-es5/wm-tag-option.entry.js +1 -1
  79. package/dist/esm-es5/wm-textarea.entry.js +1 -1
  80. package/dist/esm-es5/wm-timepicker.entry.js +1 -1
  81. package/dist/esm-es5/wm-toggletip.entry.js +1 -1
  82. package/dist/esm-es5/wm-uploader.entry.js +1 -1
  83. package/dist/ripple/{p-8e2f3a45.entry.js → p-009a6e5a.entry.js} +1 -1
  84. package/dist/ripple/{p-bde7e77b.system.entry.js → p-036fd03b.system.entry.js} +1 -1
  85. package/dist/ripple/p-03759d86.system.entry.js +1 -0
  86. package/dist/ripple/{p-7c3bf608.entry.js → p-047e510d.entry.js} +1 -1
  87. package/dist/ripple/p-059efd2a.entry.js +1 -0
  88. package/dist/ripple/{p-92c8361f.js → p-0ae9b6d3.js} +1 -1
  89. package/dist/ripple/{p-3d8754ba.system.entry.js → p-0c20a096.system.entry.js} +1 -1
  90. package/dist/ripple/{p-7edd25f7.system.js → p-176dcfc0.system.js} +1 -1
  91. package/dist/ripple/{p-d815809f.js → p-1806e50b.js} +1 -1
  92. package/dist/ripple/{p-f9bbb123.system.entry.js → p-1841c319.system.entry.js} +1 -1
  93. package/dist/ripple/{p-9609d8e7.entry.js → p-1ad6c15b.entry.js} +1 -1
  94. package/dist/ripple/{p-1de87de8.system.entry.js → p-1eb2ec31.system.entry.js} +1 -1
  95. package/dist/ripple/{p-3133ce3c.system.entry.js → p-1efa25b5.system.entry.js} +1 -1
  96. package/dist/ripple/{p-39a4934f.entry.js → p-21c100d8.entry.js} +1 -1
  97. package/dist/ripple/{p-a5c5c64c.entry.js → p-222624ae.entry.js} +1 -1
  98. package/dist/ripple/{p-96f86eb4.system.entry.js → p-22d4c7e0.system.entry.js} +1 -1
  99. package/dist/ripple/{p-fbad04d7.system.entry.js → p-25c17efe.system.entry.js} +1 -1
  100. package/dist/ripple/{p-5405df80.system.entry.js → p-26ab5004.system.entry.js} +1 -1
  101. package/dist/ripple/{p-bcb953cf.system.js → p-324f341f.system.js} +1 -1
  102. package/dist/ripple/{p-be87d02c.entry.js → p-328b9560.entry.js} +1 -1
  103. package/dist/ripple/{p-960d2cf0.system.entry.js → p-3c9972a6.system.entry.js} +1 -1
  104. package/dist/ripple/{p-ce9bb8ac.system.entry.js → p-4b0b66e0.system.entry.js} +1 -1
  105. package/dist/ripple/{p-41664372.entry.js → p-54759960.entry.js} +1 -1
  106. package/dist/ripple/{p-2b7259cb.system.entry.js → p-55cdfcb4.system.entry.js} +1 -1
  107. package/dist/ripple/{p-f4390a0a.system.entry.js → p-5bf2eb50.system.entry.js} +1 -1
  108. package/dist/ripple/{p-667fdcbb.system.entry.js → p-65d3f9c4.system.entry.js} +1 -1
  109. package/dist/ripple/{p-ecd1c2ba.entry.js → p-66489ded.entry.js} +1 -1
  110. package/dist/ripple/{p-6a70dc0b.system.entry.js → p-68e90b50.system.entry.js} +1 -1
  111. package/dist/ripple/{p-118093e1.entry.js → p-69b38da5.entry.js} +1 -1
  112. package/dist/ripple/{p-b1fb99e4.system.entry.js → p-6a40014e.system.entry.js} +1 -1
  113. package/dist/ripple/{p-00eaa361.system.entry.js → p-6d32911c.system.entry.js} +1 -1
  114. package/dist/ripple/{p-60e16c79.entry.js → p-6ec4129b.entry.js} +1 -1
  115. package/dist/ripple/{p-908057b2.entry.js → p-71cc21a4.entry.js} +1 -1
  116. package/dist/ripple/{p-7134a305.system.entry.js → p-7394f4e9.system.entry.js} +1 -1
  117. package/dist/ripple/{p-6f38976c.entry.js → p-7d708fab.entry.js} +1 -1
  118. package/dist/ripple/{p-608971f2.system.js → p-88a7ccee.system.js} +1 -1
  119. package/dist/ripple/{p-85830dbc.system.entry.js → p-8c73dadf.system.entry.js} +1 -1
  120. package/dist/ripple/{p-b511ebfd.js → p-91669f66.js} +1 -1
  121. package/dist/ripple/{p-65abcbb4.system.js → p-95f19440.system.js} +1 -1
  122. package/dist/ripple/{p-2f82bfb9.system.entry.js → p-96a7c1b9.system.entry.js} +1 -1
  123. package/dist/ripple/{p-31bac55d.entry.js → p-9ac6957b.entry.js} +1 -1
  124. package/dist/ripple/p-9e1ea6e2.entry.js +1 -0
  125. package/dist/ripple/{p-8ec6ec53.entry.js → p-a0ef456d.entry.js} +1 -1
  126. package/dist/ripple/{p-abcdd7be.system.entry.js → p-acb4d87c.system.entry.js} +1 -1
  127. package/dist/ripple/{p-957f13fb.entry.js → p-ad10664f.entry.js} +1 -1
  128. package/dist/ripple/{p-f91fc18d.entry.js → p-ae2520e4.entry.js} +1 -1
  129. package/dist/ripple/{p-63233a4b.system.entry.js → p-b1282d28.system.entry.js} +1 -1
  130. package/dist/ripple/{p-4d0abf7a.entry.js → p-b55883ee.entry.js} +1 -1
  131. package/dist/ripple/{p-4b8f7d1e.entry.js → p-bb364d6b.entry.js} +1 -1
  132. package/dist/ripple/{p-1a89139d.system.entry.js → p-bd37b0f9.system.entry.js} +1 -1
  133. package/dist/ripple/{p-2508b801.entry.js → p-bdac9bec.entry.js} +1 -1
  134. package/dist/ripple/{p-c7f3ef7f.system.entry.js → p-c0f4f1ea.system.entry.js} +1 -1
  135. package/dist/ripple/{p-374f46f4.entry.js → p-c1d6740e.entry.js} +1 -1
  136. package/dist/ripple/{p-0bce3f83.entry.js → p-c70fa14f.entry.js} +1 -1
  137. package/dist/ripple/{p-4602304a.system.entry.js → p-c73882de.system.entry.js} +1 -1
  138. package/dist/ripple/{p-0825151e.entry.js → p-c85dae6b.entry.js} +1 -1
  139. package/dist/ripple/{p-44cc05f6.system.entry.js → p-c8dfc321.system.entry.js} +1 -1
  140. package/dist/ripple/{p-700ca4a0.entry.js → p-d784f4b4.entry.js} +1 -1
  141. package/dist/ripple/{p-9202d9e9.entry.js → p-dbc3a44d.entry.js} +1 -1
  142. package/dist/ripple/{p-a7cde3fc.entry.js → p-dfa30c3d.entry.js} +1 -1
  143. package/dist/ripple/{p-e660d0b8.system.entry.js → p-e1a15515.system.entry.js} +1 -1
  144. package/dist/ripple/{p-9e89655f.entry.js → p-ea10c498.entry.js} +1 -1
  145. package/dist/ripple/{p-86a61a2a.entry.js → p-ebfa5876.entry.js} +1 -1
  146. package/dist/ripple/{p-26667070.entry.js → p-ec9f782e.entry.js} +1 -1
  147. package/dist/ripple/p-f7ed42b0.system.js +1 -0
  148. package/dist/ripple/{p-a14dee02.system.entry.js → p-f8fd7172.system.entry.js} +1 -1
  149. package/dist/ripple/{p-e5c34af5.system.entry.js → p-fb61a10e.system.entry.js} +1 -1
  150. package/dist/ripple/{p-b0e81de1.js → p-fbc46f7e.js} +1 -1
  151. package/dist/ripple/{p-2db6573e.system.entry.js → p-ff6b7376.system.entry.js} +1 -1
  152. package/dist/ripple/ripple.esm.js +1 -1
  153. package/dist/ripple/ripple.js +1 -1
  154. package/dist/types/components/selects/wm-select/wm-select.d.ts +9 -17
  155. package/package.json +2 -2
  156. package/dist/ripple/p-0a46b050.entry.js +0 -1
  157. package/dist/ripple/p-39936fc9.system.entry.js +0 -1
  158. package/dist/ripple/p-4b322285.entry.js +0 -1
  159. package/dist/ripple/p-95d0c131.system.js +0 -1
@@ -1,34 +1,14 @@
1
1
  import { h, Host } from "@stencil/core";
2
2
  import { forceUpdate } from "@stencil/core";
3
- import { getTextDir, toBool, handleDisabledAttribute, showTooltip, hideTooltip, debounce, findAllScrollableParents, } from "../../../global/functions";
3
+ import { getTextDir, shouldOpenUp, isElOrChild, toBool, handleDisabledAttribute, showTooltip, hideTooltip } from "../../../global/functions";
4
4
  import { globalMessages, selectMessages } from "../../../global/intl";
5
5
  export class Select {
6
6
  constructor() {
7
- this.scrollableParents = [];
8
- this.returnFocus = false;
9
- this.hasAnchor = CSS.supports("top", "anchor(bottom)"); // for FF polyfill
7
+ this.openUp = false;
10
8
  //////////////////////////////////////
11
9
  // for multiselect button text
12
10
  this.overflowCount = 0;
13
11
  this.displayedOptions = [];
14
- this.previousDisplayedOptions = [];
15
- this.debouncedScroll = debounce(() => {
16
- if (this.hasAnchor) {
17
- const popoverRect = this.dropdownEl.getBoundingClientRect();
18
- const anchorRect = this.buttonEl.getBoundingClientRect();
19
- // Heuristic: Popover is ABOVE the anchor (it opened upwards)
20
- this.isUp = popoverRect.bottom < anchorRect.top;
21
- this.isExpanded = true;
22
- this.optionListEl.handleInitialFocus(this.elToFocus);
23
- this.elToFocus = undefined;
24
- }
25
- else {
26
- this.dropdownPosition();
27
- }
28
- }, 100);
29
- this.debouncedResize = debounce(() => {
30
- this.dropdownPosition();
31
- }, 100);
32
12
  this.disabled = false;
33
13
  this.maxHeight = "200px";
34
14
  this.label = undefined;
@@ -42,8 +22,6 @@ export class Select {
42
22
  this.searchPlaceholder = selectMessages.searchPlaceholder;
43
23
  this.allSelectedMessage = selectMessages.allSelected;
44
24
  this.isExpanded = false;
45
- this.isUp = false;
46
- this.isHidden = false;
47
25
  this.announcement = "";
48
26
  }
49
27
  get childOptions() {
@@ -62,149 +40,58 @@ export class Select {
62
40
  //////////////////////////////////////
63
41
  handleOptionSelection() {
64
42
  if (!this.multiple) {
65
- this.returnFocus = true;
66
- this.dropdownEl.hidePopover();
43
+ this.close();
67
44
  }
68
45
  }
69
46
  handleChildEnter() {
70
47
  // only occurs for multiselects. handle the click, then close
71
- this.returnFocus = true;
72
- this.dropdownEl.hidePopover();
73
- }
74
- closeDropdownOnEscape() {
75
- this.returnFocus = true;
76
- this.dropdownEl.hidePopover();
77
- }
78
- handleBeforeToggle() {
79
- if (!this.hasAnchor) {
80
- // Start hidden to prevent flash during positioning calculation
81
- this.isHidden = true;
82
- }
83
- }
84
- handleToggle(ev) {
85
- ev.newState === "open" ? this.open() : this.close();
86
- }
87
- dropdownPosition() {
88
- // polyfill for opening up or down + positioning according to screen
89
- // (must recalculate on scroll, resize)
90
- // Using transform for better performance - only affects composite layer, no layout recalculation
91
- const buttonElRect = this.buttonEl.getBoundingClientRect();
92
- const spaceAbove = buttonElRect.top;
93
- const spaceBelow = document.documentElement.clientHeight - buttonElRect.bottom;
94
- const dropdownHeight = this.dropdownEl.clientHeight;
95
- // Clear any previously set positioning properties
96
- this.el.style.removeProperty("--dropdown-translate-y");
97
- this.el.style.removeProperty("--dropdown-max-height");
98
- this.el.style.removeProperty("--dropdown-left");
99
- // Set horizontal position and width to match button
100
- this.el.style.setProperty("--dropdown-left", buttonElRect.left + "px");
101
- this.el.style.setProperty("--button-width", buttonElRect.width + "px");
102
- if (dropdownHeight <= spaceBelow) {
103
- // Case 1: Enough space below - position dropdown below the button
104
- this.el.style.setProperty("--dropdown-translate-y", buttonElRect.bottom + "px");
105
- }
106
- else if (dropdownHeight <= spaceAbove) {
107
- // Case 2: Not enough space below, but enough above - position dropdown above the button
108
- this.el.style.setProperty("--dropdown-translate-y", buttonElRect.top - dropdownHeight + "px");
109
- }
110
- else {
111
- // Case 3: Not enough space in either direction - use the larger available space and constrain height
112
- if (spaceBelow >= spaceAbove) {
113
- // Use space below and constrain dropdown height
114
- this.el.style.setProperty("--dropdown-translate-y", buttonElRect.bottom + "px");
115
- this.el.style.setProperty("--dropdown-max-height", spaceBelow + "px");
116
- }
117
- else {
118
- // Use space above and constrain dropdown height
119
- this.el.style.setProperty("--dropdown-translate-y", "0px");
120
- this.el.style.setProperty("--dropdown-max-height", spaceAbove + "px");
121
- }
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);
122
61
  }
123
- this.isHidden = false;
124
62
  }
125
- open() {
126
- if (!this.isExpanded && !this.isDisabled) {
127
- // polyfill for browsers without anchor() support (FF)
128
- if (!this.hasAnchor) {
129
- this.dropdownPosition();
130
- }
131
- requestAnimationFrame(() => {
132
- const popoverRect = this.dropdownEl.getBoundingClientRect();
133
- const anchorRect = this.buttonEl.getBoundingClientRect();
134
- // Heuristic: Popover is ABOVE the anchor (it opened upwards)
135
- this.isUp = popoverRect.top < anchorRect.top;
136
- this.isExpanded = true;
137
- this.optionListEl.handleInitialFocus(this.elToFocus);
138
- this.elToFocus = undefined;
139
- });
63
+ handleClick(ev) {
64
+ if (!isElOrChild(this.el, ev.target)) {
65
+ this.close();
140
66
  }
141
67
  }
142
- close() {
143
- if (this.isExpanded) {
144
- this.isExpanded = false;
145
- this.optionListEl.unfocusAll();
146
- window.setTimeout(() => {
147
- if (!this.hasAnchor) {
148
- this.isHidden = true;
149
- }
150
- if (this.optionListEl.multiple) {
151
- this.optionListEl.updateOptionVisibility();
152
- }
153
- // clear search field, reset filtered / bolded state of wm-options
154
- if (this.search) {
155
- this.optionListEl.clearSearch();
156
- }
157
- }, 150);
158
- if (this.returnFocus) {
159
- requestAnimationFrame(() => {
160
- this.buttonEl.focus();
161
- this.returnFocus = false;
162
- });
163
- }
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();
164
72
  }
165
73
  }
166
74
  handleKey(ev) {
167
75
  switch (ev.key) {
168
76
  case "Tab":
169
77
  // if tabbing backwards, close and return focus to button. Otherwise, close but do not redirect focus.
170
- if (this.isExpanded && ev.shiftKey) {
171
- this.returnFocus = true;
172
- }
173
- this.dropdownEl.hidePopover();
78
+ this.close(ev.shiftKey ? true : false);
174
79
  break;
175
80
  case "ArrowDown":
176
81
  if (this.isExpanded === false) {
177
82
  ev.preventDefault();
178
- this.elToFocus = "next";
179
- this.dropdownEl.showPopover();
83
+ this.open("next");
180
84
  }
181
85
  break;
182
86
  case "ArrowUp":
183
87
  if (this.isExpanded === false) {
184
88
  ev.preventDefault();
185
- this.elToFocus = "previous";
186
- this.dropdownEl.showPopover();
89
+ this.open("previous");
187
90
  }
188
91
  break;
189
92
  }
190
93
  }
191
- handleResize() {
192
- if (!this.hasAnchor && this.isExpanded) {
193
- this.isHidden = true;
194
- this.debouncedResize();
195
- }
196
- }
197
- handleScroll() {
198
- if (this.isExpanded) {
199
- this.isHidden = true;
200
- this.debouncedScroll();
201
- }
202
- }
203
94
  componentWillLoad() {
204
- if (!this.hasAnchor) {
205
- // Start hidden to prevent flash on first load
206
- this.isHidden = true;
207
- }
208
95
  if (!this.label) {
209
96
  console.error("For accessibility purposes, this component requires a label (even if `label-position` is set to `none`).");
210
97
  }
@@ -221,6 +108,8 @@ export class Select {
221
108
  });
222
109
  }
223
110
  handleChildChange() {
111
+ // on update of children or children selected state, reset button text and rerender
112
+ this.setButtonText();
224
113
  forceUpdate(this.el);
225
114
  if (this.multiple) {
226
115
  // update state of clone options
@@ -229,19 +118,43 @@ export class Select {
229
118
  }
230
119
  componentDidLoad() {
231
120
  this.wmSelectDidLoad.emit();
232
- if (!this.hasAnchor) {
233
- this.scrollableParents = findAllScrollableParents(this.el);
234
- // Add scroll listeners to all scrollable parents
235
- this.scrollableParents.forEach((parent) => {
236
- if (parent === document.documentElement) {
237
- // For document element, listen to window scroll event
238
- window.addEventListener("scroll", () => this.handleScroll());
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();
239
145
  }
240
- else {
241
- // For regular elements, listen to their scroll event
242
- parent.addEventListener("scroll", () => this.handleScroll());
146
+ // clear search field, reset filtered / bolded state of wm-options
147
+ if (this.search) {
148
+ this.optionListEl.clearSearch();
243
149
  }
244
- });
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();
156
+ }
157
+ }, 150);
245
158
  }
246
159
  }
247
160
  announceError() {
@@ -255,6 +168,7 @@ export class Select {
255
168
  handleComponentBlur(ev) {
256
169
  // Do not close or emit custom blur event when blurring to an element inside (wm-option)
257
170
  if (!this.el.contains(ev.relatedTarget)) {
171
+ this.close(false);
258
172
  this.wmSelectBlurred.emit();
259
173
  }
260
174
  }
@@ -264,6 +178,28 @@ export class Select {
264
178
  showTooltip("right", ev.target, this.label);
265
179
  }
266
180
  }
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
+ }
267
203
  announce(message) {
268
204
  // \u00A0 is a non-breaking space character, which causes the message to be read as a new one
269
205
  if (this.liveRegionEl.textContent === message) {
@@ -272,7 +208,6 @@ export class Select {
272
208
  this.announcement = message;
273
209
  }
274
210
  renderButtonText() {
275
- this.displayedOptions = this.childOptions.filter((x) => x.selected);
276
211
  if (this.multiple && this.displayedOptions.length < 1) {
277
212
  return h("span", null, this.placeholder);
278
213
  }
@@ -280,28 +215,6 @@ export class Select {
280
215
  return this.allSelectedMessage;
281
216
  }
282
217
  else {
283
- // handle overflow + counter for multiselect
284
- // only bother if things have changed
285
- const hasChanged = this.displayedOptions !== this.previousDisplayedOptions;
286
- if (this.multiple && hasChanged) {
287
- // this is a fixed measurement accounting for the max width of a 3 character overflow counter
288
- const overflowCounterWidth = 38;
289
- const computedStyle = window.getComputedStyle(this.buttonEl);
290
- // there seems to be no quick way to get an elements width without padding, except for subtracting padding manually
291
- const paddingLeft = parseInt(computedStyle.getPropertyValue("padding-left").slice(0, -2));
292
- const paddingRight = parseInt(computedStyle.getPropertyValue("padding-right").slice(0, -2));
293
- const availableSpace = this.buttonEl.clientWidth - paddingLeft - paddingRight - overflowCounterWidth;
294
- this.overflowCount = 0;
295
- this.measurementAreaEl.textContent = this.displayedOptions.map((x) => x.textContent).join(", ");
296
- let optionsTotalWidth = this.measurementAreaEl.clientWidth;
297
- while (optionsTotalWidth > availableSpace && this.displayedOptions.length > 1) {
298
- this.overflowCount++;
299
- this.displayedOptions.pop();
300
- this.measurementAreaEl.textContent = this.displayedOptions.map((x) => x.textContent).join(", ");
301
- optionsTotalWidth = this.measurementAreaEl.clientWidth;
302
- }
303
- this.previousDisplayedOptions = this.displayedOptions;
304
- }
305
218
  return this.displayedOptions.map((x, idx) => (h("span", null, idx > 0 ? ", " : "", x.textContent)));
306
219
  }
307
220
  }
@@ -312,22 +225,18 @@ export class Select {
312
225
  }
313
226
  render() {
314
227
  const showSubinfo = !this.multiple && this.selectedOptions.length > 0 && this.selectedOptions[0].subinfo;
315
- return (h(Host, { key: 'f73046e3e0d19f90e1de9f6c104b186159e08551', onBlur: (ev) => this.handleComponentBlur(ev) }, h("div", { key: '78f69feb04ef0436bb3b7f0bdeb08c67c69aa025', class: `wrapper ${getTextDir()} label-${this.labelPosition} ${this.errorMessage ? "invalid" : ""}` }, h("div", { key: 'a3a54f3c4b01271bb472a2dcaeff653ae37191b8', class: "label-wrapper" }, h("label", { key: 'fac48d7e7a6ee92a6c28bcc6d76aa9b0358cb2fa', class: "label", id: "label", htmlFor: "selectbtn", onMouseEnter: (ev) => this.handleLabelMouseEnter(ev), onMouseLeave: () => hideTooltip() }, this.label),
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),
316
238
  // we can't use aria-required because the listbox is in a sub-component and it is not announced
317
- this.requiredField && (h("span", { key: 'a78da94fc8742122542de24709dae541058aeab1', class: "required" }, h("span", { key: '055fb76d88b0680ede31d3c700a640b5c1cb498f', class: "sr-only" }, globalMessages.requiredField), h("span", { key: 'e1db2d800c6b5789d8a50ce73b02899b4c8cf105', "aria-hidden": "true" }, "*")))), h("div", { key: '9a1b34ee65e711a6bfd55149af12ed03899294cc', class: "button-wrapper" }, h("button", { key: 'b7c86d83006cb532787d3f1df0c9c9f3b54470e7', 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: 'ed2cc72a353f2bae29fdd5d8ea3f5b5dedc85c6b', class: `overflowcontrol ${showSubinfo ? "hassubinfo" : ""}` }, h("span", { key: 'cd68f6e2d0200649a57bb8f8c9c7ad423c551848', class: "button-text" }, this.renderButtonText()), showSubinfo && h("span", { key: '2501335ceaa6612cd720c71b0ea3c6efb68fa698', class: "subinfo" }, this.selectedOptions[0].subinfo)), h("div", { key: 'dacf8d5e2223a9700854ef4fac3ecabf1c8702a2', class: `expand-icon svg-icon ${this.isExpanded ? "svg-expand-less" : "svg-expand-more"}` }), this.renderOverflowCount(), h("div", { key: '161a40394450b4bac8ac91435a2b03ef9a0f8277', ref: (el) => (this.measurementAreaEl = el), class: "measurement-area", "aria-hidden": "true" })), h("div", { key: 'ed6cdbdfe2d290440b1bd33938b4cee31a70047e',
318
- // is-open is for the CSS transition in modern browsers
319
- // hidden is to wait for position calculations in Firefox
320
- class: `dropdown ${this.isExpanded ? "is-open" : ""} ${this.isHidden ? "hidden" : ""} ${this.isUp ? "upward" : ""}`, id: "dropdown", popover: "auto", ref: (el) => (this.dropdownEl = el),
321
- // @ts-ignore -- don't tell typescript but we're in the future
322
- onToggle: (ev) => this.handleToggle(ev) }, h("priv-option-list", { key: '14ab958ca5cb5a3ac3fa970ed138ec5b47089779', ref: (el) => (this.optionListEl = el), multiple: this.multiple, search: this.search, selectAll: this.selectAll, maxHeight: this.maxHeight, searchPlaceholder: this.searchPlaceholder, onOptionListCloseRequested: () => {
323
- this.dropdownEl.hidePopover();
324
- }, onOptionListAllSelected: () => {
325
- this.returnFocus = true;
326
- this.wmSelectAllSelected.emit();
327
- }, onOptionListAllDeselected: () => {
328
- this.returnFocus = true;
329
- this.wmSelectAllDeselected.emit();
330
- } }, h("slot", { key: '98699fb0f36674cbae13f226fa923d6228fdad97' }))), h("div", { key: '69a49e6a2fe618bf9ce1a7e08527630a2d48cb8b', id: "error", class: this.errorMessage ? "error-message" : "" }, this.errorMessage), h("div", { key: '374538b9eb797924abfe74049fec191a41ae7501', id: "announcement", "aria-live": "polite", "aria-atomic": "true", class: "sr-only", ref: (el) => (this.liveRegionEl = el) }, this.announcement)))));
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)))));
331
240
  }
332
241
  static get is() { return "wm-select"; }
333
242
  static get encapsulation() { return "shadow"; }
@@ -563,8 +472,6 @@ export class Select {
563
472
  static get states() {
564
473
  return {
565
474
  "isExpanded": {},
566
- "isUp": {},
567
- "isHidden": {},
568
475
  "announcement": {}
569
476
  };
570
477
  }
@@ -656,22 +563,28 @@ export class Select {
656
563
  "passive": false
657
564
  }, {
658
565
  "name": "wmEscKeyPressed",
659
- "method": "closeDropdownOnEscape",
566
+ "method": "closePopupOnEscape",
660
567
  "target": undefined,
661
568
  "capture": false,
662
569
  "passive": false
663
570
  }, {
664
- "name": "keydown",
665
- "method": "handleKey",
571
+ "name": "wmOptionBlurred",
572
+ "method": "handleOptionBlur",
666
573
  "target": undefined,
667
574
  "capture": false,
668
575
  "passive": false
669
576
  }, {
670
- "name": "resize",
671
- "method": "handleResize",
672
- "target": "window",
577
+ "name": "click",
578
+ "method": "handleClick",
579
+ "target": "document",
580
+ "capture": true,
581
+ "passive": false
582
+ }, {
583
+ "name": "keydown",
584
+ "method": "handleKey",
585
+ "target": undefined,
673
586
  "capture": false,
674
- "passive": true
587
+ "passive": false
675
588
  }];
676
589
  }
677
590
  }
@@ -28,7 +28,7 @@ export class Toggletip {
28
28
  this.isHidden = true;
29
29
  }
30
30
  get isOpen() {
31
- return this.toggletipEl.matches(":popover-open");
31
+ return this.toggletipEl && this.toggletipEl.matches(":popover-open");
32
32
  }
33
33
  get tooltipMessage() {
34
34
  switch (this.toggletipType) {
@@ -229,11 +229,11 @@ export class Toggletip {
229
229
  }
230
230
  }
231
231
  render() {
232
- return (h(Host, { key: '2127bc9c0e5bebbf58fce82b7ea772a3b6fe2ada', class: `size-${this.targetSize}` }, h("button", { key: '55335d84975af0a4e6928b71d08745050454d4e4', ref: (el) => (this.buttonEl = el), class: "button", type: "button", "aria-label": this.label, popoverTarget: "toggletip", popoverTargetAction: "toggle", onClick: () => this.open(),
232
+ return (h(Host, { key: 'f8a626c9e0311a0a05d58d12787c0e9a3be5ca8a', class: `size-${this.targetSize}` }, h("button", { key: 'c2e2dbc45ce9900a8025973f0fd7a3870eca0afa', ref: (el) => (this.buttonEl = el), class: "button", type: "button", "aria-label": this.label, popoverTarget: "toggletip", popoverTargetAction: "toggle", onClick: () => this.open(),
233
233
  // In order to position the tooltip identically to the toggletip, its presence is determined by these four events
234
- onMouseEnter: () => !this.isOpen && showTooltip(this.toggletipPosition, this.el, this.tooltipMessage), onMouseLeave: () => hideTooltip(), onFocus: () => !this.isOpen && showTooltip(this.toggletipPosition, this.el, this.tooltipMessage), onBlur: () => this.handleBlur() }, this.renderIcon()), h("div", { key: 'de52ea584962f47a035c900af10e31951ec49ef6', popover: "", ref: (el) => (this.toggletipEl = el), class: `toggletip ${this.targetSize} ${this.isHidden ? "hidden" : ""}`, id: "toggletip",
234
+ onMouseEnter: () => !this.isOpen && showTooltip(this.toggletipPosition, this.el, this.tooltipMessage), onMouseLeave: () => hideTooltip(), onFocus: () => !this.isOpen && showTooltip(this.toggletipPosition, this.el, this.tooltipMessage), onBlur: () => this.handleBlur() }, this.renderIcon()), h("div", { key: '3a786c92826bc07b6ec0bb3119f1adfeacc25656', popover: "", ref: (el) => (this.toggletipEl = el), class: `toggletip ${this.targetSize} ${this.isHidden ? "hidden" : ""}`, id: "toggletip",
235
235
  // @ts-ignore - despite what Typescript says, this is a valid event for popover elements
236
- onToggle: (ev) => this.handlePopoverToggle(ev) }, this.tooltip), h("div", { key: '88e8da7742e5aa390fd17be1efd6067d25f71209', ref: (el) => (this.liveRegionEl = el), class: "live-region sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true" })));
236
+ onToggle: (ev) => this.handlePopoverToggle(ev) }, this.tooltip), h("div", { key: '7ed3b737df01ff9b2bbf3182e8cf3b3188d24b83', ref: (el) => (this.liveRegionEl = el), class: "live-region sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true" })));
237
237
  }
238
238
  static get is() { return "wm-toggletip"; }
239
239
  static get encapsulation() { return "shadow"; }
@@ -1,6 +1,6 @@
1
1
  import './index-130e07bb.js';
2
2
 
3
- const version = "5.19.1-alpha.2";
3
+ const version = "5.20.0-alpha.0";
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-38e392cb.js';
2
+ import { i as intl, c as checkForActiveElInShadow, e as safeMultiplyFloat, f as getPosition } from './functions-669184a6.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, 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 };
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 };
@@ -1,4 +1,4 @@
1
- import { i as intl } from './functions-38e392cb.js';
1
+ import { i as intl } from './functions-669184a6.js';
2
2
 
3
3
  const globalMessages = {
4
4
  characterLimitReached: intl.formatMessage({