@watermarkinsights/ripple 3.0.1-0 → 3.0.2-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 (224) hide show
  1. package/dist/{ripple/functions-316c1b23.js → cjs/functions-e3f5ae65.js} +188 -2391
  2. package/dist/cjs/global-1e540de6.js +38 -0
  3. package/dist/cjs/http-service-9e8c4dd5.js +57 -0
  4. package/dist/cjs/index-d930307d.js +1392 -0
  5. package/dist/cjs/index.cjs.js +2 -0
  6. package/dist/cjs/interfaces-30a74c1f.js +35 -0
  7. package/dist/cjs/loader.cjs.js +22 -0
  8. package/dist/cjs/priv-chart-popover.cjs.entry.js +89 -0
  9. package/dist/cjs/priv-datepicker.cjs.entry.js +672 -0
  10. package/dist/cjs/priv-navigator-button.cjs.entry.js +29 -0
  11. package/dist/cjs/priv-navigator-item.cjs.entry.js +34 -0
  12. package/dist/cjs/ripple.cjs.js +20 -0
  13. package/dist/cjs/wm-action-menu_2.cjs.entry.js +318 -0
  14. package/dist/cjs/wm-button.cjs.entry.js +152 -0
  15. package/dist/cjs/wm-chart-slice.cjs.entry.js +22 -0
  16. package/dist/cjs/wm-chart.cjs.entry.js +508 -0
  17. package/dist/cjs/wm-datepicker.cjs.entry.js +257 -0
  18. package/dist/cjs/wm-input.cjs.entry.js +110 -0
  19. package/dist/cjs/wm-modal-footer.cjs.entry.js +43 -0
  20. package/dist/cjs/wm-modal-header.cjs.entry.js +45 -0
  21. package/dist/cjs/wm-modal.cjs.entry.js +149 -0
  22. package/dist/cjs/wm-navigator.cjs.entry.js +279 -0
  23. package/dist/cjs/wm-network-uploader.cjs.entry.js +431 -0
  24. package/dist/cjs/wm-option_2.cjs.entry.js +483 -0
  25. package/dist/cjs/wm-pagination.cjs.entry.js +176 -0
  26. package/dist/cjs/wm-search.cjs.entry.js +231 -0
  27. package/dist/cjs/wm-snackbar.cjs.entry.js +160 -0
  28. package/dist/cjs/wm-tab-item_3.cjs.entry.js +316 -0
  29. package/dist/cjs/wm-tag-input.cjs.entry.js +538 -0
  30. package/dist/cjs/wm-timepicker.cjs.entry.js +386 -0
  31. package/dist/cjs/wm-toggletip.cjs.entry.js +128 -0
  32. package/dist/cjs/wm-uploader.cjs.entry.js +342 -0
  33. package/dist/cjs/wm-wrapper.cjs.entry.js +21 -0
  34. package/dist/collection/collection-manifest.json +131 -0
  35. package/dist/{ripple/ripple.css → collection/components/wm-action-menu/wm-action-menu.css} +80 -42
  36. package/dist/collection/components/wm-action-menu/wm-action-menu.js +392 -0
  37. package/dist/collection/components/wm-button/wm-button.css +572 -0
  38. package/dist/collection/components/wm-button/wm-button.js +365 -0
  39. package/dist/collection/components/wm-chart/priv-chart-popover/priv-chart-popover.css +132 -0
  40. package/dist/collection/components/wm-chart/priv-chart-popover/priv-chart-popover.js +232 -0
  41. package/dist/collection/components/wm-chart/wm-chart-slice.js +64 -0
  42. package/dist/collection/components/wm-chart/wm-chart.css +337 -0
  43. package/dist/collection/components/wm-chart/wm-chart.js +710 -0
  44. package/dist/collection/components/wm-datepicker/priv-datepicker/priv-datepicker.css +374 -0
  45. package/dist/collection/components/wm-datepicker/priv-datepicker/priv-datepicker.js +1003 -0
  46. package/dist/collection/components/wm-datepicker/wm-datepicker.css +211 -0
  47. package/dist/collection/components/wm-datepicker/wm-datepicker.js +439 -0
  48. package/dist/collection/components/wm-input/wm-input.css +220 -0
  49. package/dist/collection/components/wm-input/wm-input.js +302 -0
  50. package/dist/collection/components/wm-menuitem/wm-menuitem.css +118 -0
  51. package/dist/collection/components/wm-menuitem/wm-menuitem.js +411 -0
  52. package/dist/collection/components/wm-modal/wm-modal-footer.css +84 -0
  53. package/dist/collection/components/wm-modal/wm-modal-footer.js +159 -0
  54. package/dist/collection/components/wm-modal/wm-modal-header.css +78 -0
  55. package/dist/collection/components/wm-modal/wm-modal-header.js +109 -0
  56. package/dist/collection/components/wm-modal/wm-modal.css +155 -0
  57. package/dist/collection/components/wm-modal/wm-modal.js +356 -0
  58. package/dist/collection/components/wm-navigator/priv-navigator-button/priv-navigator-button.css +94 -0
  59. package/dist/collection/components/wm-navigator/priv-navigator-button/priv-navigator-button.js +97 -0
  60. package/dist/collection/components/wm-navigator/priv-navigator-item/priv-navigator-item.css +67 -0
  61. package/dist/collection/components/wm-navigator/priv-navigator-item/priv-navigator-item.js +114 -0
  62. package/dist/collection/components/wm-navigator/wm-navigator.css +137 -0
  63. package/dist/collection/components/wm-navigator/wm-navigator.js +468 -0
  64. package/dist/collection/components/wm-option/wm-option.css +162 -0
  65. package/dist/collection/components/wm-option/wm-option.js +394 -0
  66. package/dist/collection/components/wm-pagination/wm-pagination.css +217 -0
  67. package/dist/collection/components/wm-pagination/wm-pagination.js +348 -0
  68. package/dist/collection/components/wm-search/wm-search.css +155 -0
  69. package/dist/collection/components/wm-search/wm-search.js +439 -0
  70. package/dist/collection/components/wm-select/wm-select.css +315 -0
  71. package/dist/collection/components/wm-select/wm-select.js +676 -0
  72. package/dist/collection/components/wm-snackbar/wm-snackbar.css +331 -0
  73. package/dist/collection/components/wm-snackbar/wm-snackbar.js +240 -0
  74. package/dist/collection/components/wm-tabs/wm-tab-item/wm-tab-item.css +104 -0
  75. package/dist/collection/components/wm-tabs/wm-tab-item/wm-tab-item.js +202 -0
  76. package/dist/collection/components/wm-tabs/wm-tab-list/wm-tab-list.css +73 -0
  77. package/dist/{ripple/wm-tab-list.entry.js → collection/components/wm-tabs/wm-tab-list/wm-tab-list.js} +131 -17
  78. package/dist/collection/components/wm-tabs/wm-tab-panel/wm-tab-panel.css +57 -0
  79. package/dist/collection/components/wm-tabs/wm-tab-panel/wm-tab-panel.js +104 -0
  80. package/dist/collection/components/wm-tag-input/wm-tag-input.css +431 -0
  81. package/dist/collection/components/wm-tag-input/wm-tag-input.js +754 -0
  82. package/dist/collection/components/wm-timepicker/wm-timepicker.css +370 -0
  83. package/dist/collection/components/wm-timepicker/wm-timepicker.js +567 -0
  84. package/dist/collection/components/wm-toggletip/wm-toggletip.css +350 -0
  85. package/dist/collection/components/wm-toggletip/wm-toggletip.js +217 -0
  86. package/dist/collection/components/wm-uploader/wm-network-uploader/wm-network-uploader.css +642 -0
  87. package/dist/collection/components/wm-uploader/wm-network-uploader/wm-network-uploader.js +753 -0
  88. package/dist/collection/components/wm-uploader/wm-uploader.css +666 -0
  89. package/dist/collection/components/wm-uploader/wm-uploader.js +673 -0
  90. package/dist/collection/components/wm-wrapper/wm-wrapper.js +27 -0
  91. package/dist/collection/dev/scripts.js +20 -0
  92. package/dist/collection/global/__mocks__/functions.js +5 -0
  93. package/dist/collection/global/functions.js +420 -0
  94. package/dist/{ripple/app-globals-b5693c90.js → collection/global/global.js} +3 -8
  95. package/dist/{ripple/interfaces-50753346.js → collection/global/interfaces.js} +4 -6
  96. package/dist/collection/global/services/__mocks__/http-service.js +130 -0
  97. package/dist/collection/global/services/http-service.js +50 -0
  98. package/dist/collection/lang/lang.js +5 -0
  99. package/dist/collection/lang/piglatin.js +93 -0
  100. package/dist/esm/functions-0deb7f8e.js +6117 -0
  101. package/dist/esm/global-d6b49e98.js +36 -0
  102. package/dist/{ripple → esm}/http-service-5d037e16.js +0 -0
  103. package/dist/esm/index-5a842e48.js +1363 -0
  104. package/dist/esm/index.js +1 -0
  105. package/dist/esm/interfaces-61c6305b.js +32 -0
  106. package/dist/esm/loader.js +18 -0
  107. package/dist/esm/polyfills/core-js.js +11 -0
  108. package/dist/esm/polyfills/css-shim.js +1 -0
  109. package/dist/esm/polyfills/dom.js +79 -0
  110. package/dist/esm/polyfills/es5-html-element.js +1 -0
  111. package/dist/esm/polyfills/index.js +34 -0
  112. package/dist/esm/polyfills/system.js +6 -0
  113. package/dist/{ripple → esm}/priv-chart-popover.entry.js +2 -2
  114. package/dist/{ripple → esm}/priv-datepicker.entry.js +3 -3
  115. package/dist/{ripple → esm}/priv-navigator-button.entry.js +1 -1
  116. package/dist/{ripple → esm}/priv-navigator-item.entry.js +1 -1
  117. package/dist/esm/ripple.js +18 -0
  118. package/dist/{ripple/wm-action-menu.entry.js → esm/wm-action-menu_2.entry.js} +114 -3
  119. package/dist/{ripple → esm}/wm-button.entry.js +3 -3
  120. package/dist/{ripple → esm}/wm-chart-slice.entry.js +1 -1
  121. package/dist/{ripple → esm}/wm-chart.entry.js +2 -2
  122. package/dist/{ripple → esm}/wm-datepicker.entry.js +27 -32
  123. package/dist/{ripple → esm}/wm-input.entry.js +2 -2
  124. package/dist/{ripple → esm}/wm-modal-footer.entry.js +2 -2
  125. package/dist/{ripple → esm}/wm-modal-header.entry.js +2 -2
  126. package/dist/{ripple → esm}/wm-modal.entry.js +2 -2
  127. package/dist/{ripple → esm}/wm-navigator.entry.js +3 -3
  128. package/dist/{ripple → esm}/wm-network-uploader.entry.js +2 -2
  129. package/dist/{ripple/wm-select.entry.js → esm/wm-option_2.entry.js} +119 -3
  130. package/dist/{ripple → esm}/wm-pagination.entry.js +2 -2
  131. package/dist/{ripple → esm}/wm-search.entry.js +2 -2
  132. package/dist/{ripple → esm}/wm-snackbar.entry.js +2 -2
  133. package/dist/esm/wm-tab-item_3.entry.js +310 -0
  134. package/dist/{ripple → esm}/wm-tag-input.entry.js +2 -2
  135. package/dist/{ripple → esm}/wm-timepicker.entry.js +2 -2
  136. package/dist/{ripple → esm}/wm-toggletip.entry.js +2 -2
  137. package/dist/{ripple → esm}/wm-uploader.entry.js +2 -2
  138. package/dist/{ripple → esm}/wm-wrapper.entry.js +1 -1
  139. package/dist/index.cjs.js +1 -0
  140. package/dist/index.js +1 -0
  141. package/dist/loader/cdn.js +3 -0
  142. package/dist/loader/index.cjs.js +3 -0
  143. package/dist/loader/index.d.ts +13 -0
  144. package/dist/loader/index.es2017.js +3 -0
  145. package/dist/loader/index.js +4 -0
  146. package/dist/loader/package.json +10 -0
  147. package/dist/ripple/index.esm.js +0 -1
  148. package/dist/ripple/p-103f8cae.entry.js +1 -0
  149. package/dist/ripple/p-129d94fa.entry.js +1 -0
  150. package/dist/ripple/p-139fe143.entry.js +1 -0
  151. package/dist/ripple/p-16367805.entry.js +1 -0
  152. package/dist/ripple/p-1d334060.entry.js +1 -0
  153. package/dist/ripple/p-2562f330.entry.js +1 -0
  154. package/dist/ripple/p-278b26ef.entry.js +1 -0
  155. package/dist/ripple/p-2c21bb72.entry.js +1 -0
  156. package/dist/ripple/p-2f5fda71.entry.js +1 -0
  157. package/dist/ripple/p-3e6f04d5.entry.js +1 -0
  158. package/dist/ripple/p-7185de7f.entry.js +1 -0
  159. package/dist/ripple/p-770d0798.entry.js +1 -0
  160. package/dist/ripple/p-846b4c5f.entry.js +1 -0
  161. package/dist/ripple/p-888bec42.js +1 -0
  162. package/dist/ripple/p-90779d53.entry.js +1 -0
  163. package/dist/ripple/p-934543f2.js +1 -0
  164. package/dist/ripple/p-9a087fee.entry.js +1 -0
  165. package/dist/ripple/p-a6d6eae7.js +1 -0
  166. package/dist/ripple/p-a942ad10.entry.js +1 -0
  167. package/dist/ripple/p-bfb4652d.entry.js +1 -0
  168. package/dist/ripple/p-c0fe5201.entry.js +1 -0
  169. package/dist/ripple/p-c2e27acc.entry.js +1 -0
  170. package/dist/ripple/p-c2edda64.entry.js +1 -0
  171. package/dist/ripple/p-d1fdcbcf.entry.js +1 -0
  172. package/dist/ripple/p-d40b6afb.entry.js +1 -0
  173. package/dist/ripple/p-da73db1c.entry.js +1 -0
  174. package/dist/ripple/p-e3843249.js +1 -0
  175. package/dist/ripple/p-ea5cd8b8.js +16 -0
  176. package/dist/ripple/p-ed0f43f4.entry.js +1 -0
  177. package/dist/ripple/p-ffafd363.entry.js +1 -0
  178. package/dist/ripple/ripple.esm.js +1 -125
  179. package/dist/types/components/wm-action-menu/wm-action-menu.d.ts +43 -0
  180. package/dist/types/components/wm-button/wm-button.d.ts +36 -0
  181. package/dist/types/components/wm-chart/priv-chart-popover/priv-chart-popover.d.ts +23 -0
  182. package/dist/types/components/wm-chart/wm-chart-slice.d.ts +8 -0
  183. package/dist/types/components/wm-chart/wm-chart.d.ts +77 -0
  184. package/dist/types/components/wm-datepicker/priv-datepicker/priv-datepicker.d.ts +75 -0
  185. package/dist/types/components/wm-datepicker/wm-datepicker.d.ts +39 -0
  186. package/dist/types/components/wm-input/wm-input.d.ts +30 -0
  187. package/dist/types/components/wm-menuitem/wm-menuitem.d.ts +30 -0
  188. package/dist/types/components/wm-modal/wm-modal-footer.d.ts +15 -0
  189. package/dist/types/components/wm-modal/wm-modal-header.d.ts +12 -0
  190. package/dist/types/components/wm-modal/wm-modal.d.ts +34 -0
  191. package/dist/types/components/wm-navigator/priv-navigator-button/priv-navigator-button.d.ts +10 -0
  192. package/dist/types/components/wm-navigator/priv-navigator-item/priv-navigator-item.d.ts +13 -0
  193. package/dist/types/components/wm-navigator/wm-navigator.d.ts +61 -0
  194. package/dist/types/components/wm-option/wm-option.d.ts +28 -0
  195. package/dist/types/components/wm-pagination/wm-pagination.d.ts +31 -0
  196. package/dist/types/components/wm-search/wm-search.d.ts +78 -0
  197. package/dist/types/components/wm-select/wm-select.d.ts +63 -0
  198. package/dist/types/components/wm-snackbar/wm-snackbar.d.ts +32 -0
  199. package/dist/types/components/wm-tabs/wm-tab-item/wm-tab-item.d.ts +35 -0
  200. package/dist/types/components/wm-tabs/wm-tab-list/wm-tab-list.d.ts +50 -0
  201. package/dist/types/components/wm-tabs/wm-tab-panel/wm-tab-panel.d.ts +20 -0
  202. package/dist/types/components/wm-tag-input/{wm-tag-input.d.ts~ds312_tagInputMaxTags → wm-tag-input.d.ts} +1 -1
  203. package/dist/types/components/wm-timepicker/wm-timepicker.d.ts +59 -0
  204. package/dist/types/components/wm-toggletip/wm-toggletip.d.ts +25 -0
  205. package/dist/types/components/wm-uploader/wm-network-uploader/wm-network-uploader.d.ts +85 -0
  206. package/dist/types/components/wm-uploader/wm-uploader.d.ts +75 -0
  207. package/dist/types/components/wm-wrapper/wm-wrapper.d.ts +7 -0
  208. package/dist/types/{components.d.ts~ds312_tagInputMaxTags → components.d.ts} +0 -0
  209. package/dist/types/global/__mocks__/functions.d.ts +5 -0
  210. package/dist/types/global/global.d.ts +1 -0
  211. package/dist/types/global/interfaces.d.ts +33 -0
  212. package/dist/types/global/services/__mocks__/http-service.d.ts +6 -0
  213. package/dist/types/global/services/http-service.d.ts +4 -0
  214. package/dist/types/lang/lang.d.ts +5 -0
  215. package/dist/types/{stencil-public-runtime.d.ts~ds312_tagInputMaxTags → stencil-public-runtime.d.ts} +190 -182
  216. package/package.json +1 -1
  217. package/dist/ripple/css-shim-bbdf0cc6.js +0 -4
  218. package/dist/ripple/dom-1f98a75f.js +0 -73
  219. package/dist/ripple/index-20b65f86.js +0 -2938
  220. package/dist/ripple/shadow-css-67b66845.js +0 -389
  221. package/dist/ripple/wm-menuitem.entry.js +0 -114
  222. package/dist/ripple/wm-option.entry.js +0 -119
  223. package/dist/ripple/wm-tab-item.entry.js +0 -78
  224. package/dist/ripple/wm-tab-panel.entry.js +0 -38
@@ -0,0 +1,567 @@
1
+ import { h, Component, Host, Element, Prop, Watch, State, Listen, Event } from "@stencil/core";
2
+ import { intl, generateId, shouldOpenUp, isRelatedTarget } from "../../global/functions";
3
+ export class Timepicker {
4
+ constructor() {
5
+ this.disabled = false;
6
+ this.value = "";
7
+ this.label = "";
8
+ this.labelPosition = "top";
9
+ this.requiredField = false;
10
+ this.isExpanded = false;
11
+ this.isTabbing = false;
12
+ this.twelveHrValid = /^(0?[0-9]|1[0-2])\s*:?\s*([0-5][0-9])?\s?(a|p|am|pm)?$/i;
13
+ this.twentyFourHrValid = /^(0?[0-9]|1[0-9]|2[0-4])\s*:?\s*([0-5][0-9])?$/;
14
+ this.uid = "";
15
+ this.timeFormat = "hh:mm";
16
+ this.times = [];
17
+ this.openUp = false;
18
+ this.buttonAriaLabel = intl.formatMessage({
19
+ id: "time.selectTime",
20
+ defaultMessage: "Select time",
21
+ });
22
+ }
23
+ toggleTabbingOn() {
24
+ this.isTabbing = true;
25
+ }
26
+ toggleTabbingOff() {
27
+ this.isTabbing = false;
28
+ }
29
+ blurHandler(ev) {
30
+ if (ev.target !== this.el && this.isExpanded) {
31
+ this.close();
32
+ }
33
+ }
34
+ handleKey(ev) {
35
+ switch (ev.key) {
36
+ case "ArrowDown":
37
+ ev.preventDefault();
38
+ if (this.isExpanded === false) {
39
+ this.open("next");
40
+ }
41
+ else {
42
+ this.moveDown(this.selectedOption);
43
+ }
44
+ break;
45
+ case "ArrowUp":
46
+ ev.preventDefault();
47
+ if (this.isExpanded === false) {
48
+ this.open("previous");
49
+ }
50
+ else {
51
+ this.moveUp(this.selectedOption);
52
+ }
53
+ break;
54
+ case "Enter":
55
+ case " ":
56
+ if (this.isExpanded) {
57
+ ev.preventDefault();
58
+ this.handleOptionClick(this.selectedOption.textContent);
59
+ }
60
+ break;
61
+ case "Escape":
62
+ ev.preventDefault();
63
+ if (this.isExpanded) {
64
+ ev.stopPropagation(); // for instance if select is in a modal, esc should close the select but not the modal
65
+ this.close();
66
+ }
67
+ break;
68
+ case "Tab":
69
+ if (this.isExpanded) {
70
+ this.close();
71
+ }
72
+ break;
73
+ case "Home":
74
+ ev.preventDefault();
75
+ if (this.isExpanded) {
76
+ this.focusOption(this.optionsList[0]);
77
+ this.setDropdownPosition("first");
78
+ }
79
+ break;
80
+ case "End":
81
+ ev.preventDefault();
82
+ if (this.isExpanded) {
83
+ this.focusOption(this.optionsList[this.optionsList.length - 1]);
84
+ this.setDropdownPosition("last");
85
+ }
86
+ break;
87
+ }
88
+ }
89
+ updateErrorState() {
90
+ this.displayedErrorMessage = this.errorMessage;
91
+ }
92
+ componentWillLoad() {
93
+ if (this.label === "") {
94
+ throw new Error("You must include a label prop for the datepicker input (for accessibility requirements), even if the label position is none.");
95
+ }
96
+ this.el.focus = function () {
97
+ if (!this.disabled) {
98
+ this.shadowRoot.querySelector("input").focus();
99
+ }
100
+ };
101
+ this.uid = this.el.id ? this.el.id : generateId();
102
+ this.updateErrorState();
103
+ this.timeFormat = intl.formatMessage({
104
+ id: "time.timeFormat",
105
+ defaultMessage: "hh:mm",
106
+ });
107
+ this.times = this.generateTimes();
108
+ }
109
+ componentDidLoad() {
110
+ this.optionsEl.classList.add("hidden");
111
+ this.optionsList = Array.from(this.optionsEl.querySelectorAll("li"));
112
+ if (this.value) {
113
+ this.processInput();
114
+ }
115
+ }
116
+ isValidTime(input) {
117
+ return this.twelveHrValid.test(input) || this.twentyFourHrValid.test(input);
118
+ }
119
+ generateTimes() {
120
+ let times = [];
121
+ let startTime = 0;
122
+ for (let i = 0; startTime < 24 * 60; i++) {
123
+ const h = Math.floor(startTime / 60);
124
+ const hour = h.toString().padStart(2, "0");
125
+ const m = (startTime % 60).toString();
126
+ const min = m.padStart(2, "0");
127
+ times[i] = `${hour}:${min}`;
128
+ startTime = startTime + 15;
129
+ }
130
+ return times;
131
+ }
132
+ findNearestTimeInterval(time) {
133
+ let formattedTime = this.formatToStorage(time);
134
+ const minutes = parseInt(formattedTime.slice(3, 5));
135
+ // first find the closest 15 min increment
136
+ if (minutes % 15 !== 0) {
137
+ const hour = parseInt(formattedTime.slice(0, 2));
138
+ let roundedMinutes = (Math.round(minutes / 15) * 15).toString().padStart(2, "0");
139
+ if (roundedMinutes === "60") {
140
+ roundedMinutes = "00";
141
+ let roundedHour = hour + 1;
142
+ if (roundedHour === 24) {
143
+ roundedHour = 0;
144
+ }
145
+ formattedTime = formattedTime.replace(`${hour.toString().padStart(2, "0")}:`, `${roundedHour.toString().padStart(2, "0")}:`);
146
+ }
147
+ if (parseInt(roundedMinutes) < 8) {
148
+ roundedMinutes = "00";
149
+ }
150
+ time = formattedTime.replace(`:${minutes.toString().padStart(2, "0")}`, `:${roundedMinutes}`);
151
+ }
152
+ return time;
153
+ }
154
+ handleListSelection(time) {
155
+ time = this.findNearestTimeInterval(time);
156
+ const option = this.optionsList.filter((o) => o.textContent == this.formatToDisplay(time))[0];
157
+ // not DOM focus, just setting the proper ARIA attributes
158
+ option && this.focusOption(option);
159
+ }
160
+ setValue(time) {
161
+ this.inputEl.value = this.formatToDisplay(time);
162
+ this.value = this.formatToStorage(time);
163
+ // update the selection in the list
164
+ // so it opens on the closest item
165
+ this.handleListSelection(time);
166
+ this.wmTimepickerOnChange.emit({
167
+ value: this.value,
168
+ isValid: !!this.displayedErrorMessage,
169
+ });
170
+ }
171
+ processInput() {
172
+ if (this.isValidTime(this.value)) {
173
+ this.setValue(this.value);
174
+ }
175
+ const newErrorMessage = this.determineErrorMessage();
176
+ this.displayedErrorMessage = newErrorMessage;
177
+ }
178
+ determineErrorMessage() {
179
+ let message = this.errorMessage;
180
+ const requiredError = intl.formatMessage({
181
+ id: "time.requiredError",
182
+ defaultMessage: "A time is required.",
183
+ });
184
+ const invalidError = intl.formatMessage({
185
+ id: "time.invalidTime",
186
+ defaultMessage: "Please enter a valid time.",
187
+ });
188
+ const isValid = this.isValidTime(this.value);
189
+ if (isValid && !this.errorMessage) {
190
+ message = null;
191
+ }
192
+ else if (!isValid && !this.errorMessage) {
193
+ if (this.requiredField && !this.value) {
194
+ message = requiredError;
195
+ }
196
+ else if (this.value) {
197
+ message = invalidError;
198
+ }
199
+ else {
200
+ message = null;
201
+ }
202
+ }
203
+ return message;
204
+ }
205
+ splitTime(time) {
206
+ const splitTime = this.twelveHrValid.exec(time) || this.twentyFourHrValid.exec(time);
207
+ let hours = parseInt(splitTime[1]);
208
+ let minutes = splitTime[2] || "00";
209
+ let amPm = splitTime ? splitTime[3] : undefined;
210
+ // handles edge case uncaught by regex '0pm'
211
+ if (hours === 0 && (amPm === null || amPm === void 0 ? void 0 : amPm.toUpperCase().includes("P"))) {
212
+ // if user types '0pm' we change it to midnight
213
+ amPm = "AM";
214
+ }
215
+ return [hours, minutes, amPm];
216
+ }
217
+ formatToDisplay(time) {
218
+ let [hours, minutes, amPm] = this.splitTime(time);
219
+ // at the moment the component only displays in 12hr AM/PM
220
+ if (hours === 12 && !amPm) {
221
+ amPm = "PM";
222
+ }
223
+ if (hours === 0 || hours === 24) {
224
+ hours = 12;
225
+ }
226
+ if (hours > 12) {
227
+ hours -= 12;
228
+ amPm = "PM";
229
+ }
230
+ if (amPm && amPm.toUpperCase().includes("P")) {
231
+ amPm = "PM";
232
+ }
233
+ else {
234
+ amPm = "AM";
235
+ }
236
+ return `${hours.toString().padStart(2, "0")}:${minutes} ${amPm}`;
237
+ }
238
+ formatToStorage(time) {
239
+ let [hours, minutes, amPm] = this.splitTime(time);
240
+ if (hours === 24) {
241
+ hours = 0;
242
+ }
243
+ if (hours === 12 && amPm && amPm.toUpperCase().includes("A")) {
244
+ hours -= 12;
245
+ }
246
+ if (amPm && amPm.toUpperCase().includes("P") && hours !== 12) {
247
+ hours += 12;
248
+ }
249
+ return `${hours.toString().padStart(2, "0")}:${minutes}`;
250
+ }
251
+ open(itemToSelect) {
252
+ this.el.focus();
253
+ this.openUp = shouldOpenUp(this.el, this.optionsEl);
254
+ this.isExpanded = true;
255
+ this.optionsEl.classList.remove("hidden");
256
+ if (this.errorMessage || !this.value) {
257
+ this.handleListSelection("09:00");
258
+ }
259
+ this.setDropdownPosition("center", this.selectedOption);
260
+ window.requestAnimationFrame(() => {
261
+ if (itemToSelect === "next") {
262
+ this.moveDown(this.selectedOption);
263
+ }
264
+ else if (itemToSelect === "previous") {
265
+ this.moveUp(this.selectedOption);
266
+ }
267
+ });
268
+ }
269
+ close() {
270
+ this.isExpanded = false;
271
+ window.setTimeout(() => {
272
+ this.optionsEl.classList.add("hidden");
273
+ // Returns focus to button after popup closes (no need if user is tabbing)
274
+ // Delay is necessary for screenreader to get new expanded state before focus
275
+ // window.requestAnimationFrame is probably enough, but since we are already using setTimeout it may as well be here
276
+ // also UX wise, it makes sense for the button to only be focused after the animation is complete
277
+ this.buttonEl.focus();
278
+ }, 150);
279
+ }
280
+ focusOption(item) {
281
+ // not an actual focus, just accessibility stuff
282
+ this.optionsList.forEach((option) => {
283
+ option.removeAttribute("aria-selected");
284
+ });
285
+ this.inputEl.setAttribute("aria-activedescendant", item.id);
286
+ item.setAttribute("aria-selected", "true");
287
+ this.selectedOption = item;
288
+ }
289
+ setDropdownPosition(position, item) {
290
+ switch (position) {
291
+ case "top":
292
+ const prevItem = item === null || item === void 0 ? void 0 : item.previousElementSibling;
293
+ this.optionsEl.scrollTop =
294
+ prevItem.getBoundingClientRect().top - this.optionsEl.getBoundingClientRect().top + this.optionsEl.scrollTop;
295
+ break;
296
+ case "bottom":
297
+ const nextItem = item === null || item === void 0 ? void 0 : item.nextElementSibling;
298
+ this.optionsEl.scrollTop =
299
+ nextItem.getBoundingClientRect().bottom -
300
+ this.optionsEl.getBoundingClientRect().top +
301
+ this.optionsEl.scrollTop -
302
+ this.optionsEl.offsetHeight;
303
+ break;
304
+ case "center":
305
+ this.optionsEl.scrollTop =
306
+ (this.optionsList.findIndex((x) => x.textContent === (item === null || item === void 0 ? void 0 : item.textContent)) - 2) * item.offsetHeight;
307
+ break;
308
+ case "first":
309
+ this.optionsEl.scrollTop = 0;
310
+ break;
311
+ case "last":
312
+ this.optionsEl.scrollTop = this.optionsList[0].clientHeight * this.optionsList.length;
313
+ break;
314
+ }
315
+ }
316
+ moveUp(el) {
317
+ const prevEl = el.previousElementSibling;
318
+ if (prevEl) {
319
+ // scroll option to top of dropdown if partially obscured / out of view
320
+ if (prevEl.getBoundingClientRect().top < this.optionsEl.getBoundingClientRect().top) {
321
+ this.setDropdownPosition("top", el);
322
+ }
323
+ this.focusOption(prevEl);
324
+ }
325
+ else {
326
+ this.focusOption(this.optionsList[this.optionsList.length - 1]);
327
+ this.setDropdownPosition("last");
328
+ }
329
+ }
330
+ moveDown(el) {
331
+ const nextEl = el.nextElementSibling;
332
+ if (nextEl) {
333
+ // scroll option to bottom of dropdown if partially obscured / out of view
334
+ if (nextEl.getBoundingClientRect().bottom > this.optionsEl.getBoundingClientRect().bottom) {
335
+ this.setDropdownPosition("bottom", el);
336
+ }
337
+ this.focusOption(nextEl);
338
+ }
339
+ else {
340
+ this.focusOption(this.optionsList[0]);
341
+ this.setDropdownPosition("first");
342
+ }
343
+ }
344
+ handleOptionClick(time) {
345
+ this.close();
346
+ this.value = time;
347
+ this.processInput();
348
+ }
349
+ handleInput() {
350
+ this.value = this.inputEl.value;
351
+ if (this.isValidTime(this.value)) {
352
+ this.handleListSelection(this.findNearestTimeInterval(this.value));
353
+ this.setDropdownPosition("center", this.selectedOption);
354
+ }
355
+ }
356
+ handleBlur(ev) {
357
+ // do not validate if clicking to an element that should prevent validation (e.g. close button on modal)
358
+ const shouldPreventValidation = this.preventValidation && isRelatedTarget(ev, this.preventValidation);
359
+ if (!shouldPreventValidation) {
360
+ this.processInput();
361
+ }
362
+ this.tpWrapper.classList.remove("focus");
363
+ }
364
+ renderOptions() {
365
+ return this.times.map((time, index) => (h("li", { id: `option${index + 1}`, role: "option", "aria-selected": time === "09:00" ? "true" : false, onClick: () => this.handleOptionClick(time) }, this.formatToDisplay(time))));
366
+ }
367
+ render() {
368
+ return (h(Host, { id: this.uid, invalid: !!this.displayedErrorMessage ? "true" : null },
369
+ h("div", { class: `wrapper label-${this.labelPosition} ${!!this.displayedErrorMessage ? "invalid" : ""}`, ref: (t) => (this.tpWrapper = t) },
370
+ h("div", { class: "label-wrapper" }, this.labelPosition !== "none" && (h("label", { id: `label-${this.uid}`, class: "label", htmlFor: `time-input-${this.uid}` },
371
+ this.label,
372
+ this.requiredField && (h("span", { class: "required", "aria-hidden": "true" }, "*"))))),
373
+ h("div", null,
374
+ h("div", { class: "inner-wrapper" },
375
+ h("input", { id: `time-input-${this.uid}`, "aria-label": this.label, "aria-describedby": `error-${this.uid}`, ref: (el) => (this.inputEl = el), onBlur: (ev) => this.handleBlur(ev), onInput: () => this.handleInput(), disabled: this.disabled, required: this.requiredField, placeholder: this.timeFormat, autocomplete: "off", onFocus: () => this.tpWrapper.classList.add("focus") }),
376
+ h("button", { id: `btn-${this.uid}`, class: this.isTabbing ? "user-is-tabbing" : "", ref: (el) => (this.buttonEl = el), disabled: this.disabled, "aria-controls": `list-${this.uid}`, "aria-expanded": this.isExpanded ? "true" : "false", "aria-label": this.buttonAriaLabel, "aria-describedby": `time-input-${this.uid}`, onClick: () => (this.isExpanded ? this.close() : this.open()) },
377
+ h("span", { class: "clock" })),
378
+ h("ul", { class: `options ${this.isExpanded ? "open" : ""} ${this.openUp ? "upwards" : ""}`, id: `list-${this.uid}`, role: "listbox", "aria-labelledby": `label-${this.uid}`, "aria-describedby": this.isExpanded ? "collapsed" : null, ref: (el) => (this.optionsEl = el) }, this.renderOptions())),
379
+ h("div", { id: `error-${this.uid}`, class: "error", "aria-live": "assertive", "aria-atomic": "true" }, this.displayedErrorMessage)))));
380
+ }
381
+ static get is() { return "wm-timepicker"; }
382
+ static get encapsulation() { return "shadow"; }
383
+ static get originalStyleUrls() { return {
384
+ "$": ["wm-timepicker.scss"]
385
+ }; }
386
+ static get styleUrls() { return {
387
+ "$": ["wm-timepicker.css"]
388
+ }; }
389
+ static get properties() { return {
390
+ "disabled": {
391
+ "type": "boolean",
392
+ "mutable": false,
393
+ "complexType": {
394
+ "original": "boolean",
395
+ "resolved": "boolean",
396
+ "references": {}
397
+ },
398
+ "required": false,
399
+ "optional": false,
400
+ "docs": {
401
+ "tags": [],
402
+ "text": ""
403
+ },
404
+ "attribute": "disabled",
405
+ "reflect": false,
406
+ "defaultValue": "false"
407
+ },
408
+ "value": {
409
+ "type": "string",
410
+ "mutable": true,
411
+ "complexType": {
412
+ "original": "string",
413
+ "resolved": "string",
414
+ "references": {}
415
+ },
416
+ "required": false,
417
+ "optional": false,
418
+ "docs": {
419
+ "tags": [],
420
+ "text": ""
421
+ },
422
+ "attribute": "value",
423
+ "reflect": true,
424
+ "defaultValue": "\"\""
425
+ },
426
+ "errorMessage": {
427
+ "type": "string",
428
+ "mutable": false,
429
+ "complexType": {
430
+ "original": "string | null",
431
+ "resolved": "null | string | undefined",
432
+ "references": {}
433
+ },
434
+ "required": false,
435
+ "optional": true,
436
+ "docs": {
437
+ "tags": [],
438
+ "text": ""
439
+ },
440
+ "attribute": "error-message",
441
+ "reflect": false
442
+ },
443
+ "label": {
444
+ "type": "string",
445
+ "mutable": false,
446
+ "complexType": {
447
+ "original": "string",
448
+ "resolved": "string",
449
+ "references": {}
450
+ },
451
+ "required": false,
452
+ "optional": false,
453
+ "docs": {
454
+ "tags": [],
455
+ "text": ""
456
+ },
457
+ "attribute": "label",
458
+ "reflect": false,
459
+ "defaultValue": "\"\""
460
+ },
461
+ "labelPosition": {
462
+ "type": "string",
463
+ "mutable": false,
464
+ "complexType": {
465
+ "original": "\"top\" | \"left\" | \"none\"",
466
+ "resolved": "\"left\" | \"none\" | \"top\"",
467
+ "references": {}
468
+ },
469
+ "required": false,
470
+ "optional": false,
471
+ "docs": {
472
+ "tags": [],
473
+ "text": ""
474
+ },
475
+ "attribute": "label-position",
476
+ "reflect": false,
477
+ "defaultValue": "\"top\""
478
+ },
479
+ "requiredField": {
480
+ "type": "boolean",
481
+ "mutable": false,
482
+ "complexType": {
483
+ "original": "boolean",
484
+ "resolved": "boolean",
485
+ "references": {}
486
+ },
487
+ "required": false,
488
+ "optional": false,
489
+ "docs": {
490
+ "tags": [],
491
+ "text": ""
492
+ },
493
+ "attribute": "required-field",
494
+ "reflect": false,
495
+ "defaultValue": "false"
496
+ },
497
+ "preventValidation": {
498
+ "type": "string",
499
+ "mutable": false,
500
+ "complexType": {
501
+ "original": "string",
502
+ "resolved": "string | undefined",
503
+ "references": {}
504
+ },
505
+ "required": false,
506
+ "optional": true,
507
+ "docs": {
508
+ "tags": [],
509
+ "text": ""
510
+ },
511
+ "attribute": "prevent-validation",
512
+ "reflect": false
513
+ }
514
+ }; }
515
+ static get states() { return {
516
+ "selectedOption": {},
517
+ "isExpanded": {},
518
+ "isTabbing": {},
519
+ "displayedErrorMessage": {}
520
+ }; }
521
+ static get events() { return [{
522
+ "method": "wmTimepickerOnChange",
523
+ "name": "wmTimepickerOnChange",
524
+ "bubbles": true,
525
+ "cancelable": true,
526
+ "composed": true,
527
+ "docs": {
528
+ "tags": [],
529
+ "text": ""
530
+ },
531
+ "complexType": {
532
+ "original": "{\n value: string;\n isValid: boolean;\n }",
533
+ "resolved": "{ value: string; isValid: boolean; }",
534
+ "references": {}
535
+ }
536
+ }]; }
537
+ static get elementRef() { return "el"; }
538
+ static get watchers() { return [{
539
+ "propName": "errorMessage",
540
+ "methodName": "updateErrorState"
541
+ }]; }
542
+ static get listeners() { return [{
543
+ "name": "wmUserIsTabbing",
544
+ "method": "toggleTabbingOn",
545
+ "target": "window",
546
+ "capture": false,
547
+ "passive": false
548
+ }, {
549
+ "name": "wmUserIsNotTabbing",
550
+ "method": "toggleTabbingOff",
551
+ "target": "window",
552
+ "capture": false,
553
+ "passive": false
554
+ }, {
555
+ "name": "click",
556
+ "method": "blurHandler",
557
+ "target": "document",
558
+ "capture": false,
559
+ "passive": false
560
+ }, {
561
+ "name": "keydown",
562
+ "method": "handleKey",
563
+ "target": undefined,
564
+ "capture": false,
565
+ "passive": false
566
+ }]; }
567
+ }