@watermarkinsights/ripple 5.6.0 → 5.7.0-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 (212) hide show
  1. package/dist/cjs/{chartFunctions-6fd43417.js → chartFunctions-995023b1.js} +1 -1
  2. package/dist/cjs/{functions-04149f6d.js → functions-e24249e6.js} +6 -0
  3. package/dist/cjs/{global-4a315ae6.js → global-b4e48f66.js} +1 -1
  4. package/dist/cjs/index-e86c28b6.js +12 -0
  5. package/dist/cjs/{intl-b1e99809.js → intl-5aeba788.js} +1 -1
  6. package/dist/cjs/loader.cjs.js +2 -2
  7. package/dist/cjs/priv-calendar.cjs.entry.js +1 -1
  8. package/dist/cjs/priv-chart-popover.cjs.entry.js +1 -1
  9. package/dist/cjs/priv-option-list.cjs.entry.js +410 -0
  10. package/dist/cjs/ripple.cjs.js +2 -2
  11. package/dist/cjs/wm-action-menu_2.cjs.entry.js +1 -1
  12. package/dist/cjs/wm-button.cjs.entry.js +1 -1
  13. package/dist/cjs/wm-chart.cjs.entry.js +3 -3
  14. package/dist/cjs/wm-date-range.cjs.entry.js +1 -1
  15. package/dist/cjs/wm-datepicker.cjs.entry.js +1 -1
  16. package/dist/cjs/wm-file.cjs.entry.js +1 -1
  17. package/dist/cjs/wm-input.cjs.entry.js +2 -2
  18. package/dist/cjs/wm-line-chart.cjs.entry.js +3 -3
  19. package/dist/cjs/wm-modal-header.cjs.entry.js +2 -2
  20. package/dist/cjs/wm-modal.cjs.entry.js +2 -2
  21. package/dist/cjs/wm-navigation_3.cjs.entry.js +2 -2
  22. package/dist/cjs/wm-navigator.cjs.entry.js +1 -1
  23. package/dist/cjs/wm-nested-select.cjs.entry.js +306 -0
  24. package/dist/cjs/wm-optgroup.cjs.entry.js +58 -0
  25. package/dist/cjs/wm-option_2.cjs.entry.js +38 -343
  26. package/dist/cjs/wm-pagination.cjs.entry.js +1 -1
  27. package/dist/cjs/wm-progress-indicator_3.cjs.entry.js +2 -2
  28. package/dist/cjs/wm-search.cjs.entry.js +2 -2
  29. package/dist/cjs/wm-snackbar.cjs.entry.js +2 -2
  30. package/dist/cjs/wm-tab-item_3.cjs.entry.js +1 -1
  31. package/dist/cjs/wm-tag-input.cjs.entry.js +2 -2
  32. package/dist/cjs/wm-tag-option.cjs.entry.js +1 -1
  33. package/dist/cjs/wm-textarea.cjs.entry.js +2 -2
  34. package/dist/cjs/wm-timepicker.cjs.entry.js +1 -1
  35. package/dist/cjs/wm-toggletip.cjs.entry.js +1 -1
  36. package/dist/cjs/wm-uploader.cjs.entry.js +2 -2
  37. package/dist/collection/collection-manifest.json +5 -2
  38. package/dist/collection/components/selects/priv-option-list/priv-option-list.css +131 -0
  39. package/dist/collection/components/selects/priv-option-list/priv-option-list.js +785 -0
  40. package/dist/collection/components/selects/wm-nested-select/wm-nested-select.css +390 -0
  41. package/dist/collection/components/selects/wm-nested-select/wm-nested-select.js +586 -0
  42. package/dist/collection/components/selects/wm-optgroup/wm-optgroup.css +51 -0
  43. package/dist/collection/components/selects/wm-optgroup/wm-optgroup.js +208 -0
  44. package/dist/collection/components/{wm-option → selects/wm-option}/wm-option.css +1 -1
  45. package/dist/collection/components/{wm-option → selects/wm-option}/wm-option.js +30 -9
  46. package/dist/collection/components/{wm-select → selects/wm-select}/wm-select.css +5 -72
  47. package/dist/collection/components/{wm-select → selects/wm-select}/wm-select.js +20 -387
  48. package/dist/collection/components/{wm-select → selects/wm-select}/wm-select.spec.js +61 -61
  49. package/dist/collection/components/wm-modal/wm-modal.js +1 -1
  50. package/dist/collection/dev/nested-select.js +36 -0
  51. package/dist/collection/global/functions.js +5 -0
  52. package/dist/esm/{chartFunctions-f5eb7f59.js → chartFunctions-dfcb1edf.js} +1 -1
  53. package/dist/esm/{functions-cf37f81f.js → functions-b791a892.js} +6 -1
  54. package/dist/esm/{global-016b76a8.js → global-8a4502dd.js} +1 -1
  55. package/dist/esm/index-558b5a82.js +12 -0
  56. package/dist/esm/{intl-c72b75dc.js → intl-f2f7ce8b.js} +1 -1
  57. package/dist/esm/loader.js +2 -2
  58. package/dist/esm/priv-calendar.entry.js +1 -1
  59. package/dist/esm/priv-chart-popover.entry.js +1 -1
  60. package/dist/esm/priv-option-list.entry.js +406 -0
  61. package/dist/esm/ripple.js +2 -2
  62. package/dist/esm/wm-action-menu_2.entry.js +1 -1
  63. package/dist/esm/wm-button.entry.js +1 -1
  64. package/dist/esm/wm-chart.entry.js +3 -3
  65. package/dist/esm/wm-date-range.entry.js +1 -1
  66. package/dist/esm/wm-datepicker.entry.js +1 -1
  67. package/dist/esm/wm-file.entry.js +1 -1
  68. package/dist/esm/wm-input.entry.js +2 -2
  69. package/dist/esm/wm-line-chart.entry.js +3 -3
  70. package/dist/esm/wm-modal-header.entry.js +2 -2
  71. package/dist/esm/wm-modal.entry.js +2 -2
  72. package/dist/esm/wm-navigation_3.entry.js +2 -2
  73. package/dist/esm/wm-navigator.entry.js +1 -1
  74. package/dist/esm/wm-nested-select.entry.js +302 -0
  75. package/dist/esm/wm-optgroup.entry.js +54 -0
  76. package/dist/esm/wm-option_2.entry.js +38 -343
  77. package/dist/esm/wm-pagination.entry.js +1 -1
  78. package/dist/esm/wm-progress-indicator_3.entry.js +2 -2
  79. package/dist/esm/wm-search.entry.js +2 -2
  80. package/dist/esm/wm-snackbar.entry.js +2 -2
  81. package/dist/esm/wm-tab-item_3.entry.js +1 -1
  82. package/dist/esm/wm-tag-input.entry.js +2 -2
  83. package/dist/esm/wm-tag-option.entry.js +1 -1
  84. package/dist/esm/wm-textarea.entry.js +2 -2
  85. package/dist/esm/wm-timepicker.entry.js +1 -1
  86. package/dist/esm/wm-toggletip.entry.js +1 -1
  87. package/dist/esm/wm-uploader.entry.js +2 -2
  88. package/dist/esm-es5/{chartFunctions-f5eb7f59.js → chartFunctions-dfcb1edf.js} +1 -1
  89. package/dist/esm-es5/{functions-cf37f81f.js → functions-b791a892.js} +1 -1
  90. package/dist/esm-es5/global-8a4502dd.js +1 -0
  91. package/dist/esm-es5/index-558b5a82.js +1 -1
  92. package/dist/esm-es5/{intl-c72b75dc.js → intl-f2f7ce8b.js} +1 -1
  93. package/dist/esm-es5/loader.js +1 -1
  94. package/dist/esm-es5/priv-calendar.entry.js +1 -1
  95. package/dist/esm-es5/priv-chart-popover.entry.js +1 -1
  96. package/dist/esm-es5/priv-option-list.entry.js +1 -0
  97. package/dist/esm-es5/ripple.js +1 -1
  98. package/dist/esm-es5/wm-action-menu_2.entry.js +1 -1
  99. package/dist/esm-es5/wm-button.entry.js +1 -1
  100. package/dist/esm-es5/wm-chart.entry.js +1 -1
  101. package/dist/esm-es5/wm-date-range.entry.js +1 -1
  102. package/dist/esm-es5/wm-datepicker.entry.js +1 -1
  103. package/dist/esm-es5/wm-file.entry.js +1 -1
  104. package/dist/esm-es5/wm-input.entry.js +1 -1
  105. package/dist/esm-es5/wm-line-chart.entry.js +1 -1
  106. package/dist/esm-es5/wm-modal-header.entry.js +1 -1
  107. package/dist/esm-es5/wm-modal.entry.js +1 -1
  108. package/dist/esm-es5/wm-navigation_3.entry.js +1 -1
  109. package/dist/esm-es5/wm-navigator.entry.js +1 -1
  110. package/dist/esm-es5/wm-nested-select.entry.js +1 -0
  111. package/dist/esm-es5/wm-optgroup.entry.js +1 -0
  112. package/dist/esm-es5/wm-option_2.entry.js +1 -1
  113. package/dist/esm-es5/wm-pagination.entry.js +1 -1
  114. package/dist/esm-es5/wm-progress-indicator_3.entry.js +1 -1
  115. package/dist/esm-es5/wm-search.entry.js +1 -1
  116. package/dist/esm-es5/wm-snackbar.entry.js +1 -1
  117. package/dist/esm-es5/wm-tab-item_3.entry.js +1 -1
  118. package/dist/esm-es5/wm-tag-input.entry.js +1 -1
  119. package/dist/esm-es5/wm-tag-option.entry.js +1 -1
  120. package/dist/esm-es5/wm-textarea.entry.js +1 -1
  121. package/dist/esm-es5/wm-timepicker.entry.js +1 -1
  122. package/dist/esm-es5/wm-toggletip.entry.js +1 -1
  123. package/dist/esm-es5/wm-uploader.entry.js +1 -1
  124. package/dist/ripple/p-01addccd.entry.js +1 -0
  125. package/dist/ripple/p-01e29a2a.system.js +1 -0
  126. package/dist/ripple/{p-2d0e4020.system.entry.js → p-0b1c6965.system.entry.js} +1 -1
  127. package/dist/ripple/p-0c259c1a.system.entry.js +1 -0
  128. package/dist/ripple/{p-2ccf8450.system.entry.js → p-1389302e.system.entry.js} +1 -1
  129. package/dist/ripple/{p-20a800a7.entry.js → p-13f51c06.entry.js} +1 -1
  130. package/dist/ripple/{p-f4b64ded.entry.js → p-149a22bf.entry.js} +1 -1
  131. package/dist/ripple/{p-76825602.js → p-16f65bf4.js} +1 -1
  132. package/dist/ripple/p-1796b85d.entry.js +1 -0
  133. package/dist/ripple/p-1c170fb3.entry.js +1 -0
  134. package/dist/ripple/{p-3ea0e27c.entry.js → p-1e625a5e.entry.js} +1 -1
  135. package/dist/ripple/{p-31094930.entry.js → p-215793a4.entry.js} +1 -1
  136. package/dist/ripple/{p-fb229776.js → p-21d372ed.js} +1 -1
  137. package/dist/ripple/{p-24103be5.entry.js → p-236af552.entry.js} +1 -1
  138. package/dist/ripple/{p-f177d841.entry.js → p-2e79fa49.entry.js} +1 -1
  139. package/dist/ripple/{p-ed1971ff.system.entry.js → p-30b905eb.system.entry.js} +1 -1
  140. package/dist/ripple/p-3d02b293.system.entry.js +1 -0
  141. package/dist/ripple/{p-86d81e42.entry.js → p-3d50db36.entry.js} +1 -1
  142. package/dist/ripple/{p-53519eed.system.entry.js → p-3deaf4d9.system.entry.js} +1 -1
  143. package/dist/ripple/{p-5f793375.system.entry.js → p-3e415c49.system.entry.js} +1 -1
  144. package/dist/ripple/{p-0b570b66.entry.js → p-41550baa.entry.js} +1 -1
  145. package/dist/ripple/p-45dc49e8.entry.js +1 -0
  146. package/dist/ripple/{p-508362c5.entry.js → p-45f9ad09.entry.js} +1 -1
  147. package/dist/ripple/p-50388b6f.system.entry.js +1 -0
  148. package/dist/ripple/{p-dc7a6037.system.entry.js → p-505eca1c.system.entry.js} +1 -1
  149. package/dist/ripple/{p-762429a8.entry.js → p-5284791c.entry.js} +1 -1
  150. package/dist/ripple/{p-0d05b4a9.entry.js → p-5300b15d.entry.js} +1 -1
  151. package/dist/ripple/p-54f7d3d4.system.entry.js +1 -0
  152. package/dist/ripple/{p-5db92638.system.entry.js → p-5a9e3108.system.entry.js} +1 -1
  153. package/dist/ripple/{p-2d0bcc88.system.entry.js → p-6cc07645.system.entry.js} +1 -1
  154. package/dist/ripple/{p-cd51ee87.system.entry.js → p-6d129ef8.system.entry.js} +1 -1
  155. package/dist/ripple/{p-451433a6.entry.js → p-72165bd2.entry.js} +1 -1
  156. package/dist/ripple/{p-5967bd2a.system.entry.js → p-725230dd.system.entry.js} +1 -1
  157. package/dist/ripple/{p-984287f7.system.entry.js → p-749597da.system.entry.js} +1 -1
  158. package/dist/ripple/{p-fb751343.system.js → p-81c2df85.system.js} +1 -1
  159. package/dist/ripple/{p-74032162.system.js → p-828adbf1.system.js} +1 -1
  160. package/dist/ripple/{p-db8917e4.entry.js → p-83be63f6.entry.js} +1 -1
  161. package/dist/ripple/{p-ce8c6180.system.entry.js → p-84603f1f.system.entry.js} +1 -1
  162. package/dist/ripple/{p-d0387d35.entry.js → p-84ba5b74.entry.js} +1 -1
  163. package/dist/ripple/p-947f8f0d.system.entry.js +1 -0
  164. package/dist/ripple/p-99058787.entry.js +1 -0
  165. package/dist/ripple/{p-9df3574d.system.entry.js → p-a0ecb6d7.system.entry.js} +1 -1
  166. package/dist/ripple/{p-7fdcce90.system.entry.js → p-a3c01e10.system.entry.js} +1 -1
  167. package/dist/ripple/p-ae82b3d2.system.js +1 -0
  168. package/dist/ripple/{p-c61366fd.entry.js → p-aea13873.entry.js} +1 -1
  169. package/dist/ripple/{p-120dbdc8.system.entry.js → p-b01f9998.system.entry.js} +1 -1
  170. package/dist/ripple/{p-bd142645.entry.js → p-b9dbf1f4.entry.js} +1 -1
  171. package/dist/ripple/{p-04f9a60a.entry.js → p-c1e3c2fb.entry.js} +1 -1
  172. package/dist/ripple/{p-8b272d80.system.entry.js → p-c2e00d4a.system.entry.js} +1 -1
  173. package/dist/ripple/{p-76d53189.entry.js → p-c47fab48.entry.js} +1 -1
  174. package/dist/ripple/{p-ffa15c47.system.entry.js → p-c853e185.system.entry.js} +1 -1
  175. package/dist/ripple/{p-c9200deb.system.entry.js → p-ca971eac.system.entry.js} +1 -1
  176. package/dist/ripple/{p-8008f0f2.system.entry.js → p-cad0c5f9.system.entry.js} +1 -1
  177. package/dist/ripple/{p-446e0b2c.system.entry.js → p-db9657eb.system.entry.js} +1 -1
  178. package/dist/ripple/p-db9f8841.system.js +1 -0
  179. package/dist/ripple/p-de8f5e92.js +1 -0
  180. package/dist/ripple/{p-e3899e1f.entry.js → p-df157138.entry.js} +1 -1
  181. package/dist/ripple/{p-ae4460f2.system.entry.js → p-e081fdc2.system.entry.js} +1 -1
  182. package/dist/ripple/{p-dfd1b720.entry.js → p-e687176d.entry.js} +1 -1
  183. package/dist/ripple/{p-d8994408.system.entry.js → p-ed1f6b8d.system.entry.js} +1 -1
  184. package/dist/ripple/{p-db190563.js → p-eddbcb21.js} +1 -1
  185. package/dist/ripple/{p-8a11ee6f.entry.js → p-f2101a0d.entry.js} +1 -1
  186. package/dist/ripple/{p-1aef4b40.entry.js → p-f24572f5.entry.js} +1 -1
  187. package/dist/ripple/{p-97f276aa.system.entry.js → p-f40e1468.system.entry.js} +1 -1
  188. package/dist/ripple/{p-6f4c4231.entry.js → p-f90e4094.entry.js} +1 -1
  189. package/dist/ripple/{p-7f483c55.system.entry.js → p-fa4f1030.system.entry.js} +1 -1
  190. package/dist/ripple/{p-9b75d56c.entry.js → p-ff1ed90f.entry.js} +1 -1
  191. package/dist/ripple/ripple.esm.js +1 -1
  192. package/dist/ripple/ripple.js +1 -1
  193. package/dist/types/components/{wm-select/wm-select.d.ts → selects/priv-option-list/priv-option-list.d.ts} +42 -65
  194. package/dist/types/components/selects/wm-nested-select/wm-nested-select.d.ts +58 -0
  195. package/dist/types/components/selects/wm-optgroup/wm-optgroup.d.ts +17 -0
  196. package/dist/types/components/{wm-option → selects/wm-option}/wm-option.d.ts +3 -2
  197. package/dist/types/components/selects/wm-select/wm-select.d.ts +54 -0
  198. package/dist/types/components.d.ts +154 -2
  199. package/dist/types/global/functions.d.ts +1 -0
  200. package/package.json +1 -1
  201. package/dist/esm-es5/global-016b76a8.js +0 -1
  202. package/dist/ripple/p-11aaef56.system.entry.js +0 -1
  203. package/dist/ripple/p-481a9e2f.system.js +0 -1
  204. package/dist/ripple/p-55668879.system.js +0 -1
  205. package/dist/ripple/p-6636a40b.system.entry.js +0 -1
  206. package/dist/ripple/p-9603168d.entry.js +0 -1
  207. package/dist/ripple/p-a40b0af9.system.js +0 -1
  208. package/dist/ripple/p-a895f1ef.entry.js +0 -1
  209. package/dist/ripple/p-f9494a9d.js +0 -1
  210. /package/dist/collection/components/{wm-option → selects/wm-option}/wm-option.e2e.js +0 -0
  211. /package/dist/collection/components/{wm-option → selects/wm-option}/wm-option.spec.js +0 -0
  212. /package/dist/collection/components/{wm-select → selects/wm-select}/wm-select.e2e.js +0 -0
@@ -0,0 +1,586 @@
1
+ import { h, Host, forceUpdate } from "@stencil/core";
2
+ import { getTextDir, intl, isElOrChild, shouldOpenUp, toBool } from "../../../global/functions";
3
+ import { globalMessages } from "../../../global/intl";
4
+ export class NestedSelect {
5
+ constructor() {
6
+ this.openUp = false;
7
+ this.overflowCount = 0;
8
+ this.displayedOptions = [];
9
+ this.clearSelectionMessage = this.multiple
10
+ ? intl.formatMessage({
11
+ id: "select.multiClearSelection",
12
+ defaultMessage: "Clear all Selections",
13
+ description: "Button text to clear selection. Use imperative",
14
+ })
15
+ : intl.formatMessage({
16
+ id: "select.singleClearSelection",
17
+ defaultMessage: "Clear Selection",
18
+ description: "Button text to clear selection. Use imperative",
19
+ });
20
+ this.disabled = false;
21
+ this.maxHeight = undefined;
22
+ this.label = undefined;
23
+ this.labelPosition = "top";
24
+ this.requiredField = false;
25
+ this.errorMessage = undefined;
26
+ this.multiple = false;
27
+ this.search = false;
28
+ this.selectAll = false;
29
+ this.placeholder = this.multiple
30
+ ? intl.formatMessage({
31
+ id: "select.multiPlaceholder",
32
+ defaultMessage: "Make a selection",
33
+ description: "Placeholder text for multiple select. Use imperative",
34
+ })
35
+ : intl.formatMessage({
36
+ id: "select.singlePlaceholder",
37
+ defaultMessage: "Select an Option",
38
+ description: "Placeholder text for single select. Use imperative",
39
+ });
40
+ this.searchPlaceholder = intl.formatMessage({
41
+ id: "select.searchPlaceholder",
42
+ defaultMessage: "Search",
43
+ description: "Placeholder text. Use imperative",
44
+ });
45
+ this.allSelectedMessage = intl.formatMessage({
46
+ id: "select.allSelected",
47
+ defaultMessage: "All selected",
48
+ description: "Text displayed when all options are selected",
49
+ });
50
+ this.isExpanded = false;
51
+ this.showClearSelectionButton = false;
52
+ }
53
+ get isDisabled() {
54
+ // string "false" needs to be treated as bool False because react wrappers convert bool to string.
55
+ return toBool(this.disabled);
56
+ }
57
+ get childOptions() {
58
+ return Array.from(this.el.querySelectorAll("wm-option"));
59
+ }
60
+ get optgroupEls() {
61
+ return Array.from(this.el.querySelectorAll("wm-optgroup"));
62
+ }
63
+ get menuitemEls() {
64
+ return Array.from(this.el.shadowRoot.querySelectorAll(".menuitem"));
65
+ }
66
+ get allSelected() {
67
+ return this.childOptions.every((option) => option.selected);
68
+ }
69
+ componentWillLoad() {
70
+ const mutationObserver = new MutationObserver((mutationRecordList) => mutationRecordList.forEach((mutationRecord) => this.handleChildChange(mutationRecord)));
71
+ mutationObserver.observe(this.el, {
72
+ childList: true,
73
+ attributes: true,
74
+ subtree: true,
75
+ attributeFilter: ["selected"],
76
+ });
77
+ }
78
+ componentDidLoad() {
79
+ if (this.maxHeight) {
80
+ this.dropdownEl.style.maxHeight = this.maxHeight;
81
+ }
82
+ }
83
+ handleChildChange(_) {
84
+ // on update of children or children selected state, reset button text and rerender
85
+ this.setButtonText();
86
+ forceUpdate(this.el);
87
+ // this.optionListEl.handleChildChange(_);
88
+ }
89
+ setButtonText() {
90
+ this.displayedOptions = this.childOptions.filter((x) => x.selected);
91
+ // handle overflow + counter for multiselect
92
+ if (this.multiple) {
93
+ // this is a fixed measurement accounting for the max width of a 3 character overflow counter
94
+ const overflowCounterWidth = 38;
95
+ const computedStyle = window.getComputedStyle(this.buttonEl);
96
+ // there seems to be no quick way to get an elements width without padding, except for subtracting padding manually
97
+ const paddingLeft = parseInt(computedStyle.getPropertyValue("padding-left").slice(0, -2));
98
+ const paddingRight = parseInt(computedStyle.getPropertyValue("padding-right").slice(0, -2));
99
+ const availableSpace = this.buttonEl.clientWidth - paddingLeft - paddingRight - overflowCounterWidth;
100
+ this.overflowCount = 0;
101
+ this.measurementAreaEl.textContent = this.displayedOptions.map((x) => x.textContent).join(", ");
102
+ let optionsTotalWidth = this.measurementAreaEl.clientWidth;
103
+ while (optionsTotalWidth > availableSpace && this.displayedOptions.length > 1) {
104
+ this.overflowCount++;
105
+ this.displayedOptions.pop();
106
+ this.measurementAreaEl.textContent = this.displayedOptions.map((x) => x.textContent).join(", ");
107
+ optionsTotalWidth = this.measurementAreaEl.clientWidth;
108
+ }
109
+ }
110
+ }
111
+ countOptgroupSelected(optgroupEl) {
112
+ let selectedOptions = Array.from(optgroupEl.querySelectorAll("wm-option")).filter((option) => option.selected);
113
+ return selectedOptions.length;
114
+ }
115
+ handleOptionSelection() {
116
+ if (!this.multiple) {
117
+ this.close();
118
+ }
119
+ }
120
+ handleChildEnter() {
121
+ // only occurs for multiselects. handle the click, then close
122
+ this.close();
123
+ }
124
+ closePopupOnEscape() {
125
+ this.close();
126
+ }
127
+ close(returnFocus = true) {
128
+ if (this.isExpanded) {
129
+ this.isExpanded = false;
130
+ this.dropdownEl.classList.remove("open");
131
+ window.setTimeout(() => {
132
+ this.optgroupEls.forEach((optgroupEl) => (optgroupEl.isExpanded = false));
133
+ if (returnFocus) {
134
+ this.buttonEl.focus();
135
+ }
136
+ }, 150);
137
+ }
138
+ }
139
+ open() {
140
+ if (!this.isDisabled) {
141
+ this.showClearSelectionButton = this.childOptions.some((o) => o.selected);
142
+ this.isExpanded = true;
143
+ this.dropdownEl.classList.add("open");
144
+ const elHeight = this.el.clientHeight;
145
+ this.openUp = shouldOpenUp(this.el, this.dropdownEl.clientHeight, elHeight, 0);
146
+ window.requestAnimationFrame(() => {
147
+ this.focusFirstMenuitem();
148
+ });
149
+ }
150
+ }
151
+ focusFirstMenuitem() {
152
+ if (this.menuitemEls.length > 0) {
153
+ this.menuitemEls[0].focus();
154
+ }
155
+ }
156
+ moveDown(menuitemEl) {
157
+ const currentIndex = this.menuitemEls.indexOf(menuitemEl);
158
+ if (currentIndex == this.menuitemEls.length - 1) {
159
+ this.menuitemEls[0].focus();
160
+ }
161
+ else {
162
+ this.menuitemEls[currentIndex + 1].focus();
163
+ }
164
+ }
165
+ moveUp(menuitemEl) {
166
+ const currentIndex = this.menuitemEls.indexOf(menuitemEl);
167
+ if (currentIndex == 0) {
168
+ this.menuitemEls[this.menuitemEls.length - 1].focus();
169
+ }
170
+ else {
171
+ this.menuitemEls[currentIndex - 1].focus();
172
+ }
173
+ }
174
+ handleButtonBlur(ev) {
175
+ if (isElOrChild(this.el, ev.relatedTarget)) {
176
+ // do not emit a blur event when opening the dropdown and focusing the Options
177
+ ev.stopPropagation();
178
+ }
179
+ }
180
+ handleClick(ev) {
181
+ if (!isElOrChild(this.el, ev.target)) {
182
+ this.close();
183
+ }
184
+ }
185
+ handleMenuitemKeydown(ev) {
186
+ switch (ev.key) {
187
+ case "ArrowDown":
188
+ ev.preventDefault();
189
+ // focus next
190
+ this.moveDown(ev.target);
191
+ break;
192
+ case "ArrowUp":
193
+ ev.preventDefault();
194
+ this.moveUp(ev.target);
195
+ // focus previous
196
+ break;
197
+ case "ArrowRight":
198
+ if (ev.target.classList.contains("group-btn")) {
199
+ ev.preventDefault();
200
+ ev.target.click();
201
+ }
202
+ break;
203
+ case "Escape":
204
+ ev.preventDefault();
205
+ this.close();
206
+ break;
207
+ }
208
+ }
209
+ handleComponentBlur(ev) {
210
+ // Do not close or emit custom blur event when blurring to an element inside (wm-option)
211
+ if (!this.el.contains(ev.relatedTarget)) {
212
+ this.close(false);
213
+ this.wmNestedSelectBlurred.emit();
214
+ }
215
+ }
216
+ handleOptgroupExpanded() {
217
+ this.menuEl.classList.add("hidden");
218
+ this.optListWrapperEl.classList.remove("hidden");
219
+ }
220
+ handleOptgroupHidden(ev) {
221
+ this.showClearSelectionButton = this.childOptions.some((o) => o.selected);
222
+ this.menuEl.classList.remove("hidden");
223
+ this.optListWrapperEl.classList.add("hidden");
224
+ // focus back to nested select
225
+ const elToFocus = this.el.shadowRoot.querySelector(`button[data-label=${ev.detail}]`);
226
+ elToFocus.focus();
227
+ }
228
+ renderButtonText() {
229
+ if (this.displayedOptions.length < 1) {
230
+ return h("span", null, this.placeholder);
231
+ }
232
+ else if (this.multiple && this.allSelected && this.overflowCount > 0) {
233
+ return this.allSelectedMessage;
234
+ }
235
+ else {
236
+ return this.displayedOptions.map((x, idx) => (h("span", null, idx > 0 ? ", " : "", x.textContent)));
237
+ }
238
+ }
239
+ renderOverflowCount() {
240
+ if (this.overflowCount > 0) {
241
+ return (h("span", null, h("span", { class: "overflow-counter" }, "+", this.overflowCount)));
242
+ }
243
+ }
244
+ handleClearSelection() {
245
+ this.optgroupEls.forEach((optgroupEl) => optgroupEl.emitDeselection());
246
+ if (!this.multiple) {
247
+ this.close();
248
+ }
249
+ }
250
+ renderClearSelectionButton() {
251
+ if (this.showClearSelectionButton) {
252
+ return (h("button", { class: "menuitem", onClick: () => this.handleClearSelection(), tabindex: -1, onKeyDown: (ev) => this.handleMenuitemKeydown(ev) }, this.clearSelectionMessage));
253
+ }
254
+ }
255
+ renderSelectionCount(optgroupEl) {
256
+ const selectionCount = this.countOptgroupSelected(optgroupEl);
257
+ if (selectionCount) {
258
+ const singleSelectionCountMessage = intl.formatMessage({
259
+ id: "select.optgroupSingleSelectionCount",
260
+ defaultMessage: "Item Selected",
261
+ description: "Text indicating number of selected in a group, where only a single selection is possible.",
262
+ }, { numSelected: selectionCount });
263
+ const multipleSelectionCountMessage = intl.formatMessage({
264
+ id: "select.optgroupMultipleSelectionCount",
265
+ defaultMessage: "{numSelected} Selected",
266
+ description: "Text indicating number of selected in a group, where multiple selections are possible.",
267
+ }, { numSelected: selectionCount });
268
+ return (h("div", { class: "selection-count" }, h("span", null, this.multiple ? multipleSelectionCountMessage : singleSelectionCountMessage)));
269
+ }
270
+ }
271
+ render() {
272
+ const buttonProps = {
273
+ id: "selectbtn",
274
+ ["disabled"]: this.isDisabled,
275
+ ["aria-controls"]: "list",
276
+ ["aria-labelledby"]: "label selectbtn",
277
+ ["aria-describedby"]: "error",
278
+ ["aria-expanded"]: this.isExpanded ? "true" : "false",
279
+ onClick: () => {
280
+ this.isExpanded ? this.close() : this.open();
281
+ },
282
+ };
283
+ return (h(Host, { onBlur: (ev) => this.handleComponentBlur(ev) }, h("div", { class: `wrapper ${getTextDir()} label-${this.labelPosition} ${this.errorMessage ? "invalid" : ""}` }, h("div", { class: "label-wrapper" }, h("label", { class: "label", id: "label", htmlFor: "selectbtn" }, this.label,
284
+ // we can't use aria-required or required attributes because it's invalid on the elements we're using (button controlling a listbox)
285
+ this.requiredField ? (h("span", { class: "required" }, h("span", { class: "sr-only" }, globalMessages.requiredField), h("span", { "aria-hidden": "true" }, "*"))) : (""))), h("div", { class: "button-wrapper" }, h("button", Object.assign({}, buttonProps, { class: `displayedoption ${this.isExpanded ? "expanded" : ""}`, ref: (el) => (this.buttonEl = el), onBlur: (ev) => this.handleButtonBlur(ev), onFocus: () => this.close() }), h("span", { class: "overflowcontrol" }, h("span", { class: "button-text" }, this.renderButtonText())), this.renderOverflowCount(), h("div", { ref: (el) => (this.measurementAreaEl = el), class: "measurement-area", "aria-hidden": "true" })), h("div", { class: `dropdown ${this.openUp ? "upwards" : ""}`, ref: (el) => (this.dropdownEl = el) }, h("div", { ref: (el) => (this.menuEl = el), class: "menu" }, this.renderClearSelectionButton(), this.optgroupEls.map((optgroupEl) => {
286
+ return (h("button", { class: "menuitem group-btn", role: "menuitem", "data-label": optgroupEl.label, tabindex: -1, onClick: () => {
287
+ optgroupEl.isExpanded = !optgroupEl.isExpanded;
288
+ forceUpdate(this.el);
289
+ }, onKeyDown: (ev) => this.handleMenuitemKeydown(ev) }, h("span", null, optgroupEl.label), this.renderSelectionCount(optgroupEl)));
290
+ })), h("div", { ref: (el) => (this.optListWrapperEl = el), class: "option-list-wrapper hidden" }, h("slot", null))), h("div", { id: "error", class: this.errorMessage ? "error-message" : "" }, this.errorMessage)))));
291
+ }
292
+ static get is() { return "wm-nested-select"; }
293
+ static get encapsulation() { return "shadow"; }
294
+ static get delegatesFocus() { return true; }
295
+ static get originalStyleUrls() {
296
+ return {
297
+ "$": ["wm-nested-select.scss"]
298
+ };
299
+ }
300
+ static get styleUrls() {
301
+ return {
302
+ "$": ["wm-nested-select.css"]
303
+ };
304
+ }
305
+ static get properties() {
306
+ return {
307
+ "disabled": {
308
+ "type": "boolean",
309
+ "mutable": false,
310
+ "complexType": {
311
+ "original": "boolean",
312
+ "resolved": "boolean",
313
+ "references": {}
314
+ },
315
+ "required": false,
316
+ "optional": false,
317
+ "docs": {
318
+ "tags": [],
319
+ "text": ""
320
+ },
321
+ "attribute": "disabled",
322
+ "reflect": true,
323
+ "defaultValue": "false"
324
+ },
325
+ "maxHeight": {
326
+ "type": "string",
327
+ "mutable": false,
328
+ "complexType": {
329
+ "original": "string",
330
+ "resolved": "string | undefined",
331
+ "references": {}
332
+ },
333
+ "required": false,
334
+ "optional": true,
335
+ "docs": {
336
+ "tags": [],
337
+ "text": ""
338
+ },
339
+ "attribute": "max-height",
340
+ "reflect": false
341
+ },
342
+ "label": {
343
+ "type": "string",
344
+ "mutable": true,
345
+ "complexType": {
346
+ "original": "string",
347
+ "resolved": "string | undefined",
348
+ "references": {}
349
+ },
350
+ "required": false,
351
+ "optional": true,
352
+ "docs": {
353
+ "tags": [],
354
+ "text": ""
355
+ },
356
+ "attribute": "label",
357
+ "reflect": false
358
+ },
359
+ "labelPosition": {
360
+ "type": "string",
361
+ "mutable": false,
362
+ "complexType": {
363
+ "original": "\"top\" | \"left\" | \"none\"",
364
+ "resolved": "\"left\" | \"none\" | \"top\"",
365
+ "references": {}
366
+ },
367
+ "required": false,
368
+ "optional": false,
369
+ "docs": {
370
+ "tags": [],
371
+ "text": ""
372
+ },
373
+ "attribute": "label-position",
374
+ "reflect": false,
375
+ "defaultValue": "\"top\""
376
+ },
377
+ "requiredField": {
378
+ "type": "boolean",
379
+ "mutable": false,
380
+ "complexType": {
381
+ "original": "boolean",
382
+ "resolved": "boolean",
383
+ "references": {}
384
+ },
385
+ "required": false,
386
+ "optional": false,
387
+ "docs": {
388
+ "tags": [],
389
+ "text": ""
390
+ },
391
+ "attribute": "required-field",
392
+ "reflect": false,
393
+ "defaultValue": "false"
394
+ },
395
+ "errorMessage": {
396
+ "type": "string",
397
+ "mutable": true,
398
+ "complexType": {
399
+ "original": "string",
400
+ "resolved": "string | undefined",
401
+ "references": {}
402
+ },
403
+ "required": false,
404
+ "optional": true,
405
+ "docs": {
406
+ "tags": [],
407
+ "text": ""
408
+ },
409
+ "attribute": "error-message",
410
+ "reflect": false
411
+ },
412
+ "multiple": {
413
+ "type": "boolean",
414
+ "mutable": false,
415
+ "complexType": {
416
+ "original": "boolean",
417
+ "resolved": "boolean",
418
+ "references": {}
419
+ },
420
+ "required": false,
421
+ "optional": false,
422
+ "docs": {
423
+ "tags": [],
424
+ "text": ""
425
+ },
426
+ "attribute": "multiple",
427
+ "reflect": false,
428
+ "defaultValue": "false"
429
+ },
430
+ "search": {
431
+ "type": "boolean",
432
+ "mutable": false,
433
+ "complexType": {
434
+ "original": "boolean",
435
+ "resolved": "boolean",
436
+ "references": {}
437
+ },
438
+ "required": false,
439
+ "optional": false,
440
+ "docs": {
441
+ "tags": [],
442
+ "text": ""
443
+ },
444
+ "attribute": "search",
445
+ "reflect": false,
446
+ "defaultValue": "false"
447
+ },
448
+ "selectAll": {
449
+ "type": "boolean",
450
+ "mutable": false,
451
+ "complexType": {
452
+ "original": "boolean",
453
+ "resolved": "boolean",
454
+ "references": {}
455
+ },
456
+ "required": false,
457
+ "optional": false,
458
+ "docs": {
459
+ "tags": [],
460
+ "text": ""
461
+ },
462
+ "attribute": "select-all",
463
+ "reflect": false,
464
+ "defaultValue": "false"
465
+ },
466
+ "placeholder": {
467
+ "type": "string",
468
+ "mutable": false,
469
+ "complexType": {
470
+ "original": "string",
471
+ "resolved": "string",
472
+ "references": {}
473
+ },
474
+ "required": false,
475
+ "optional": false,
476
+ "docs": {
477
+ "tags": [],
478
+ "text": ""
479
+ },
480
+ "attribute": "placeholder",
481
+ "reflect": false,
482
+ "defaultValue": "this.multiple\n ? intl.formatMessage({\n id: \"select.multiPlaceholder\",\n defaultMessage: \"Make a selection\",\n description: \"Placeholder text for multiple select. Use imperative\",\n })\n : intl.formatMessage({\n id: \"select.singlePlaceholder\",\n defaultMessage: \"Select an Option\",\n description: \"Placeholder text for single select. Use imperative\",\n })"
483
+ },
484
+ "searchPlaceholder": {
485
+ "type": "string",
486
+ "mutable": false,
487
+ "complexType": {
488
+ "original": "string",
489
+ "resolved": "string",
490
+ "references": {}
491
+ },
492
+ "required": false,
493
+ "optional": false,
494
+ "docs": {
495
+ "tags": [],
496
+ "text": ""
497
+ },
498
+ "attribute": "search-placeholder",
499
+ "reflect": false,
500
+ "defaultValue": "intl.formatMessage({\n id: \"select.searchPlaceholder\",\n defaultMessage: \"Search\",\n description: \"Placeholder text. Use imperative\",\n })"
501
+ },
502
+ "allSelectedMessage": {
503
+ "type": "string",
504
+ "mutable": false,
505
+ "complexType": {
506
+ "original": "string",
507
+ "resolved": "string",
508
+ "references": {}
509
+ },
510
+ "required": false,
511
+ "optional": false,
512
+ "docs": {
513
+ "tags": [],
514
+ "text": ""
515
+ },
516
+ "attribute": "all-selected-message",
517
+ "reflect": false,
518
+ "defaultValue": "intl.formatMessage({\n id: \"select.allSelected\",\n defaultMessage: \"All selected\",\n description: \"Text displayed when all options are selected\",\n })"
519
+ }
520
+ };
521
+ }
522
+ static get states() {
523
+ return {
524
+ "isExpanded": {},
525
+ "showClearSelectionButton": {}
526
+ };
527
+ }
528
+ static get events() {
529
+ return [{
530
+ "method": "wmNestedSelectBlurred",
531
+ "name": "wmNestedSelectBlurred",
532
+ "bubbles": true,
533
+ "cancelable": true,
534
+ "composed": true,
535
+ "docs": {
536
+ "tags": [],
537
+ "text": ""
538
+ },
539
+ "complexType": {
540
+ "original": "void",
541
+ "resolved": "void",
542
+ "references": {}
543
+ }
544
+ }];
545
+ }
546
+ static get elementRef() { return "el"; }
547
+ static get listeners() {
548
+ return [{
549
+ "name": "wmOptionSelected",
550
+ "method": "handleOptionSelection",
551
+ "target": undefined,
552
+ "capture": false,
553
+ "passive": false
554
+ }, {
555
+ "name": "wmEnterKeyPressed",
556
+ "method": "handleChildEnter",
557
+ "target": undefined,
558
+ "capture": false,
559
+ "passive": false
560
+ }, {
561
+ "name": "wmEscKeyPressed",
562
+ "method": "closePopupOnEscape",
563
+ "target": undefined,
564
+ "capture": false,
565
+ "passive": false
566
+ }, {
567
+ "name": "click",
568
+ "method": "handleClick",
569
+ "target": "document",
570
+ "capture": true,
571
+ "passive": false
572
+ }, {
573
+ "name": "optgroupExpanded",
574
+ "method": "handleOptgroupExpanded",
575
+ "target": undefined,
576
+ "capture": false,
577
+ "passive": false
578
+ }, {
579
+ "name": "optgroupHidden",
580
+ "method": "handleOptgroupHidden",
581
+ "target": undefined,
582
+ "capture": false,
583
+ "passive": false
584
+ }];
585
+ }
586
+ }
@@ -0,0 +1,51 @@
1
+ /* --------------------------------------
2
+ 1. Box-shadow
3
+ -------------------------------------- */
4
+ /* --------------------------------------
5
+ 2. Border-radius
6
+ -------------------------------------- */
7
+ /* --------------------------------------
8
+ 3. Transforms
9
+ -------------------------------------- */
10
+ /* --------------------------------------
11
+ 4. Button Focus
12
+ -------------------------------------- */
13
+ /* --------------------------------------
14
+ 5. Flex
15
+ -------------------------------------- */
16
+ /* --------------------------------------
17
+ 7. Screen Reader Only
18
+ -------------------------------------- */
19
+ /* --------------------------------------
20
+ 8. Label styles
21
+ this mixin includes all the styles for the label
22
+ + flex rules on the parent container to switch between top and left position
23
+ + srOnly when label is hidden
24
+ Assumes the following markup:
25
+ div.wrapper[.label-left.invalid] > div.label-wrapper > label.label > span.required
26
+ .wrapper is for the flex rules
27
+ .label-wrapper is to set the height of the label when positioned left so it's the same height as
28
+ the input. It can't be done directly on .label because of possible line wrapping.
29
+ When the label is on top there's no line wrapping at all to ensure proper alignment of inlined elements
30
+ (they can't be aligned on the baseline because of possible description text and error message)
31
+ -------------------------------------- */
32
+ :host {
33
+ width: 100%;
34
+ display: none;
35
+ }
36
+ :host .sr-only {
37
+ position: absolute !important;
38
+ width: 1px !important;
39
+ height: 1px !important;
40
+ padding: 0 !important;
41
+ border: 0 !important;
42
+ overflow: hidden !important;
43
+ clip: rect(0, 0, 0, 0) !important;
44
+ clip-path: inset(50%) !important;
45
+ white-space: nowrap !important;
46
+ margin: -1px !important;
47
+ }
48
+
49
+ :host(.visible) {
50
+ display: unset;
51
+ }