@esri/calcite-components 1.0.0-next.317 → 1.0.0-next.320

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 (110) hide show
  1. package/dist/calcite/assets/calcite-icon/centerAlign16.json +1 -0
  2. package/dist/calcite/assets/calcite-icon/centerAlign24.json +1 -0
  3. package/dist/calcite/assets/calcite-icon/centerAlign32.json +1 -0
  4. package/dist/calcite/assets/calcite-icon/convert16.json +1 -0
  5. package/dist/calcite/assets/calcite-icon/convert24.json +1 -0
  6. package/dist/calcite/assets/calcite-icon/convert32.json +1 -0
  7. package/dist/calcite/assets/calcite-icon/formDropdown16.json +1 -0
  8. package/dist/calcite/assets/calcite-icon/formDropdown24.json +1 -0
  9. package/dist/calcite/assets/calcite-icon/formDropdown32.json +1 -0
  10. package/dist/calcite/assets/calcite-icon/language16.json +1 -0
  11. package/dist/calcite/assets/calcite-icon/language24.json +1 -0
  12. package/dist/calcite/assets/calcite-icon/language32.json +1 -0
  13. package/dist/calcite/assets/calcite-icon/languageTranslate16.json +1 -0
  14. package/dist/calcite/assets/calcite-icon/languageTranslate24.json +1 -0
  15. package/dist/calcite/assets/calcite-icon/languageTranslate32.json +1 -0
  16. package/dist/calcite/assets/calcite-icon/leftAlign16.json +1 -0
  17. package/dist/calcite/assets/calcite-icon/leftAlign24.json +1 -0
  18. package/dist/calcite/assets/calcite-icon/leftAlign32.json +1 -0
  19. package/dist/calcite/assets/calcite-icon/terminal16.json +1 -0
  20. package/dist/calcite/assets/calcite-icon/terminal24.json +1 -0
  21. package/dist/calcite/assets/calcite-icon/terminal32.json +1 -0
  22. package/dist/calcite/assets/calcite-icon/touch16.json +1 -0
  23. package/dist/calcite/assets/calcite-icon/touch24.json +1 -0
  24. package/dist/calcite/assets/calcite-icon/touch32.json +1 -0
  25. package/dist/calcite/calcite.esm.js +1 -1
  26. package/dist/calcite/p-1480eb2d.entry.js +5 -0
  27. package/dist/calcite/p-2cd9d307.entry.js +5 -0
  28. package/dist/calcite/p-6e050609.entry.js +5 -0
  29. package/dist/calcite/p-8e252799.system.js +1 -1
  30. package/dist/calcite/p-96bbc815.system.entry.js +5 -0
  31. package/dist/calcite/p-cb55c32c.system.entry.js +5 -0
  32. package/dist/calcite/p-e817ded0.entry.js +5 -0
  33. package/dist/calcite/{p-44a07313.system.entry.js → p-f7b5dd98.system.entry.js} +1 -1
  34. package/dist/calcite/p-fa9a1d8f.system.entry.js +5 -0
  35. package/dist/cjs/calcite-action-bar.cjs.entry.js +24 -0
  36. package/dist/cjs/calcite-color-picker_3.cjs.entry.js +3 -3
  37. package/dist/cjs/calcite-input-time-picker_2.cjs.entry.js +349 -223
  38. package/dist/cjs/calcite-panel.cjs.entry.js +3 -3
  39. package/dist/cjs/calcite.cjs.js +1 -1
  40. package/dist/cjs/loader.cjs.js +1 -1
  41. package/dist/collection/components/calcite-action-bar/calcite-action-bar.js +3 -0
  42. package/dist/collection/components/calcite-filter/calcite-filter.js +1 -1
  43. package/dist/collection/components/calcite-icon/assets/calcite-icon/centerAlign16.json +1 -0
  44. package/dist/collection/components/calcite-icon/assets/calcite-icon/centerAlign24.json +1 -0
  45. package/dist/collection/components/calcite-icon/assets/calcite-icon/centerAlign32.json +1 -0
  46. package/dist/collection/components/calcite-icon/assets/calcite-icon/convert16.json +1 -0
  47. package/dist/collection/components/calcite-icon/assets/calcite-icon/convert24.json +1 -0
  48. package/dist/collection/components/calcite-icon/assets/calcite-icon/convert32.json +1 -0
  49. package/dist/collection/components/calcite-icon/assets/calcite-icon/formDropdown16.json +1 -0
  50. package/dist/collection/components/calcite-icon/assets/calcite-icon/formDropdown24.json +1 -0
  51. package/dist/collection/components/calcite-icon/assets/calcite-icon/formDropdown32.json +1 -0
  52. package/dist/collection/components/calcite-icon/assets/calcite-icon/language16.json +1 -0
  53. package/dist/collection/components/calcite-icon/assets/calcite-icon/language24.json +1 -0
  54. package/dist/collection/components/calcite-icon/assets/calcite-icon/language32.json +1 -0
  55. package/dist/collection/components/calcite-icon/assets/calcite-icon/languageTranslate16.json +1 -0
  56. package/dist/collection/components/calcite-icon/assets/calcite-icon/languageTranslate24.json +1 -0
  57. package/dist/collection/components/calcite-icon/assets/calcite-icon/languageTranslate32.json +1 -0
  58. package/dist/collection/components/calcite-icon/assets/calcite-icon/leftAlign16.json +1 -0
  59. package/dist/collection/components/calcite-icon/assets/calcite-icon/leftAlign24.json +1 -0
  60. package/dist/collection/components/calcite-icon/assets/calcite-icon/leftAlign32.json +1 -0
  61. package/dist/collection/components/calcite-icon/assets/calcite-icon/terminal16.json +1 -0
  62. package/dist/collection/components/calcite-icon/assets/calcite-icon/terminal24.json +1 -0
  63. package/dist/collection/components/calcite-icon/assets/calcite-icon/terminal32.json +1 -0
  64. package/dist/collection/components/calcite-icon/assets/calcite-icon/touch16.json +1 -0
  65. package/dist/collection/components/calcite-icon/assets/calcite-icon/touch24.json +1 -0
  66. package/dist/collection/components/calcite-icon/assets/calcite-icon/touch32.json +1 -0
  67. package/dist/collection/components/calcite-input-time-picker/calcite-input-time-picker.js +81 -76
  68. package/dist/collection/components/calcite-panel/calcite-panel.js +3 -3
  69. package/dist/collection/components/calcite-time-picker/calcite-time-picker.css +56 -91
  70. package/dist/collection/components/calcite-time-picker/calcite-time-picker.js +254 -289
  71. package/dist/collection/components/calcite-time-picker/resources.js +15 -9
  72. package/dist/collection/utils/conditionalSlot.js +26 -0
  73. package/dist/collection/utils/time.js +144 -36
  74. package/dist/components/calcite-action-bar.js +25 -1
  75. package/dist/components/calcite-color-picker-swatch2.js +3 -3
  76. package/dist/components/calcite-input-time-picker.js +51 -48
  77. package/dist/components/calcite-panel.js +3 -3
  78. package/dist/components/calcite-time-picker2.js +320 -187
  79. package/dist/custom-elements/index.js +381 -231
  80. package/dist/esm/calcite-action-bar.entry.js +25 -1
  81. package/dist/esm/calcite-color-picker_3.entry.js +3 -3
  82. package/dist/esm/calcite-input-time-picker_2.entry.js +349 -223
  83. package/dist/esm/calcite-panel.entry.js +3 -3
  84. package/dist/esm/calcite.js +1 -1
  85. package/dist/esm/loader.js +1 -1
  86. package/dist/esm-es5/calcite-action-bar.entry.js +1 -1
  87. package/dist/esm-es5/calcite-color-picker_3.entry.js +1 -1
  88. package/dist/esm-es5/calcite-input-time-picker_2.entry.js +2 -2
  89. package/dist/esm-es5/calcite-panel.entry.js +1 -1
  90. package/dist/esm-es5/calcite.js +1 -1
  91. package/dist/esm-es5/loader.js +1 -1
  92. package/dist/extras/docs-json.json +23 -101
  93. package/dist/types/components/calcite-action-bar/calcite-action-bar.d.ts +2 -1
  94. package/dist/types/components/calcite-input-time-picker/calcite-input-time-picker.d.ts +12 -4
  95. package/dist/types/components/calcite-panel/calcite-panel.d.ts +1 -1
  96. package/dist/types/components/calcite-time-picker/calcite-time-picker.d.ts +35 -23
  97. package/dist/types/components/calcite-time-picker/resources.d.ts +14 -8
  98. package/dist/types/components.d.ts +17 -41
  99. package/dist/types/utils/conditionalSlot.d.ts +17 -0
  100. package/dist/types/utils/time.d.ts +18 -5
  101. package/hydrate/index.js +399 -239
  102. package/package.json +11 -11
  103. package/readme.md +2 -2
  104. package/dist/calcite/p-12a9599d.system.entry.js +0 -5
  105. package/dist/calcite/p-88784777.system.entry.js +0 -5
  106. package/dist/calcite/p-9634f89d.entry.js +0 -5
  107. package/dist/calcite/p-b37b7b9e.system.entry.js +0 -5
  108. package/dist/calcite/p-e1da1646.entry.js +0 -5
  109. package/dist/calcite/p-e78e743b.entry.js +0 -5
  110. package/dist/calcite/p-f333e31b.entry.js +0 -5
@@ -14,6 +14,72 @@ const form = require('./form-7f276aa5.js');
14
14
  require('./dom-41ce6029.js');
15
15
 
16
16
  const maxTenthForMinuteAndSecond = 5;
17
+ function createLocaleDateTimeFormatter(locale, includeSeconds = true) {
18
+ try {
19
+ const options = {
20
+ hour: "2-digit",
21
+ minute: "2-digit",
22
+ timeZone: "UTC"
23
+ };
24
+ if (includeSeconds) {
25
+ options.second = "2-digit";
26
+ }
27
+ return new Intl.DateTimeFormat(locale, options);
28
+ }
29
+ catch (e) {
30
+ throw new Error(`Invalid locale supplied while attempting to create a DateTime formatter: ${locale}`);
31
+ }
32
+ }
33
+ function formatTimePart(number) {
34
+ const numberAsString = number.toString();
35
+ return number >= 0 && number <= 9 ? numberAsString.padStart(2, "0") : numberAsString;
36
+ }
37
+ function formatTimeString(value) {
38
+ if (!isValidTime(value)) {
39
+ return null;
40
+ }
41
+ const [hourString, minuteString, secondString] = value.split(":");
42
+ const hour = formatTimePart(parseInt(hourString));
43
+ const minute = formatTimePart(parseInt(minuteString));
44
+ if (secondString) {
45
+ const second = formatTimePart(parseInt(secondString));
46
+ return `${hour}:${minute}:${second}`;
47
+ }
48
+ return `${hour}:${minute}`;
49
+ }
50
+ function getLocaleHourCycle(locale) {
51
+ const formatter = createLocaleDateTimeFormatter(locale);
52
+ const parts = formatter.formatToParts(new Date(Date.UTC(0, 0, 0, 0, 0, 0)));
53
+ return getLocalizedTimePart("meridiem", parts) ? "12" : "24";
54
+ }
55
+ function getLocalizedTimePart(part, parts) {
56
+ var _a, _b, _c, _d;
57
+ if (!part || !parts) {
58
+ return null;
59
+ }
60
+ if (part === "hourSuffix") {
61
+ const hourIndex = parts.indexOf(parts.find(({ type }) => type === "hour"));
62
+ const minuteIndex = parts.indexOf(parts.find(({ type }) => type === "minute"));
63
+ const hourSuffix = parts[hourIndex + 1];
64
+ return hourSuffix && hourSuffix.type === "literal" && minuteIndex - hourIndex === 2
65
+ ? ((_a = hourSuffix.value) === null || _a === void 0 ? void 0 : _a.trim()) || null
66
+ : null;
67
+ }
68
+ if (part === "minuteSuffix") {
69
+ const minuteIndex = parts.indexOf(parts.find(({ type }) => type === "minute"));
70
+ const secondIndex = parts.indexOf(parts.find(({ type }) => type === "second"));
71
+ const minuteSuffix = parts[minuteIndex + 1];
72
+ return minuteSuffix && minuteSuffix.type === "literal" && secondIndex - minuteIndex === 2
73
+ ? ((_b = minuteSuffix.value) === null || _b === void 0 ? void 0 : _b.trim()) || null
74
+ : null;
75
+ }
76
+ if (part === "secondSuffix") {
77
+ const secondIndex = parts.indexOf(parts.find(({ type }) => type === "second"));
78
+ const secondSuffix = parts[secondIndex + 1];
79
+ return secondSuffix && secondSuffix.type === "literal" ? ((_c = secondSuffix.value) === null || _c === void 0 ? void 0 : _c.trim()) || null : null;
80
+ }
81
+ return ((_d = parts.find(({ type }) => (part == "meridiem" ? type === "dayPeriod" : type === part))) === null || _d === void 0 ? void 0 : _d.value) || null;
82
+ }
17
83
  function getMeridiem(hour) {
18
84
  if (!number.isValidNumber(hour)) {
19
85
  return null;
@@ -21,51 +87,93 @@ function getMeridiem(hour) {
21
87
  const hourAsNumber = parseInt(hour);
22
88
  return hourAsNumber >= 0 && hourAsNumber <= 11 ? "AM" : "PM";
23
89
  }
24
- function getMeridiemHour(hour) {
25
- if (!number.isValidNumber(hour)) {
26
- return null;
90
+ function isValidTime(value) {
91
+ if (!value || value.startsWith(":") || value.endsWith(":")) {
92
+ return false;
27
93
  }
28
- const hourAsNumber = parseInt(hour);
29
- if (hourAsNumber === 0) {
30
- return "12";
94
+ const splitValue = value.split(":");
95
+ const validLength = splitValue.length > 1 && splitValue.length < 4;
96
+ if (!validLength) {
97
+ return false;
98
+ }
99
+ const [hour, minute, second] = splitValue;
100
+ const hourAsNumber = parseInt(splitValue[0]);
101
+ const minuteAsNumber = parseInt(splitValue[1]);
102
+ const secondAsNumber = parseInt(splitValue[2]);
103
+ const hourValid = number.isValidNumber(hour) && hourAsNumber >= 0 && hourAsNumber < 24;
104
+ const minuteValid = number.isValidNumber(minute) && minuteAsNumber >= 0 && minuteAsNumber < 60;
105
+ const secondValid = number.isValidNumber(second) && secondAsNumber >= 0 && secondAsNumber < 60;
106
+ if ((hourValid && minuteValid && !second) || (hourValid && minuteValid && secondValid)) {
107
+ return true;
31
108
  }
32
- return hourAsNumber > 12 ? formatTimePart(hourAsNumber - 12) : hour;
33
109
  }
34
- function parseTimeString(value) {
35
- const timeString = formatTimeString(value);
36
- const [hour, minute, second] = timeString ? timeString.split(":") : [null, null, null];
37
- return {
38
- hour,
39
- minute,
40
- second: second || (hour && minute ? "00" : null)
41
- };
110
+ function isValidTimePart(value, part) {
111
+ if (part === "meridiem") {
112
+ return value === "AM" || value === "PM";
113
+ }
114
+ if (!number.isValidNumber(value)) {
115
+ return false;
116
+ }
117
+ const valueAsNumber = Number(value);
118
+ return part === "hour" ? valueAsNumber >= 0 && valueAsNumber < 24 : valueAsNumber >= 0 && valueAsNumber < 60;
42
119
  }
43
- function formatTimeString(value) {
44
- if (!value || value.endsWith(":") || value.startsWith(":")) {
120
+ function localizeTimePart(value, part, locale) {
121
+ if (!isValidTimePart(value, part)) {
122
+ return;
123
+ }
124
+ const valueAsNumber = parseInt(value);
125
+ const date = new Date(Date.UTC(0, 0, 0, part === "hour" ? valueAsNumber : part === "meridiem" ? (value === "AM" ? 0 : 12) : 0, part === "minute" ? valueAsNumber : 0, part === "second" ? valueAsNumber : 0));
126
+ if (!date) {
127
+ return;
128
+ }
129
+ const formatter = createLocaleDateTimeFormatter(locale);
130
+ const parts = formatter.formatToParts(date);
131
+ return getLocalizedTimePart(part, parts);
132
+ }
133
+ function localizeTimeString(value, locale = "en", includeSeconds = true) {
134
+ if (!isValidTime(value)) {
45
135
  return null;
46
136
  }
47
- const splitValue = value.split(":");
48
- if (splitValue.length > 1) {
49
- const [hour, minute, second] = splitValue;
50
- const hourAsNumber = parseInt(splitValue[0]);
51
- const minuteAsNumber = parseInt(splitValue[1]);
52
- const secondAsNumber = parseInt(splitValue[2]);
53
- const hourValid = number.isValidNumber(hour) && hourAsNumber >= 0 && hourAsNumber < 24;
54
- const minuteValid = number.isValidNumber(minute) && minuteAsNumber >= 0 && minuteAsNumber < 60;
55
- const secondValid = number.isValidNumber(second) && secondAsNumber >= 0 && secondAsNumber < 60;
56
- if ((hourValid && minuteValid && !second) || (hourValid && minuteValid && secondValid)) {
57
- let newValue = `${formatTimePart(hourAsNumber)}:${formatTimePart(minuteAsNumber)}`;
58
- if (secondValid) {
59
- newValue = `${newValue}:${formatTimePart(secondAsNumber)}`;
60
- }
61
- return newValue;
62
- }
137
+ const { hour, minute, second = "0" } = parseTimeString(value);
138
+ const dateFromTimeString = new Date(Date.UTC(0, 0, 0, parseInt(hour), parseInt(minute), parseInt(second)));
139
+ const formatter = createLocaleDateTimeFormatter(locale, includeSeconds);
140
+ return (formatter === null || formatter === void 0 ? void 0 : formatter.format(dateFromTimeString)) || null;
141
+ }
142
+ function localizeTimeStringToParts(value, locale = "en") {
143
+ if (!isValidTime(value)) {
144
+ return null;
145
+ }
146
+ const { hour, minute, second = "0" } = parseTimeString(value);
147
+ const dateFromTimeString = new Date(Date.UTC(0, 0, 0, parseInt(hour), parseInt(minute), parseInt(second)));
148
+ if (dateFromTimeString) {
149
+ const formatter = createLocaleDateTimeFormatter(locale);
150
+ const parts = formatter.formatToParts(dateFromTimeString);
151
+ return {
152
+ localizedHour: getLocalizedTimePart("hour", parts),
153
+ localizedHourSuffix: getLocalizedTimePart("hourSuffix", parts),
154
+ localizedMinute: getLocalizedTimePart("minute", parts),
155
+ localizedMinuteSuffix: getLocalizedTimePart("minuteSuffix", parts),
156
+ localizedSecond: getLocalizedTimePart("second", parts),
157
+ localizedSecondSuffix: getLocalizedTimePart("secondSuffix", parts),
158
+ localizedMeridiem: getLocalizedTimePart("meridiem", parts)
159
+ };
63
160
  }
64
161
  return null;
65
162
  }
66
- function formatTimePart(number) {
67
- const numberAsString = number.toString();
68
- return number >= 0 && number <= 9 ? numberAsString.padStart(2, "0") : numberAsString;
163
+ function parseTimeString(value) {
164
+ if (isValidTime(value)) {
165
+ const [hour, minute, second] = value.split(":");
166
+ return {
167
+ hour,
168
+ minute,
169
+ second
170
+ };
171
+ }
172
+ return {
173
+ hour: null,
174
+ minute: null,
175
+ second: null
176
+ };
69
177
  }
70
178
 
71
179
  const calciteInputTimePickerCss = "@-webkit-keyframes in{0%{opacity:0}100%{opacity:1}}@keyframes in{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}@keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}:root{--calcite-animation-timing:300ms}.calcite-animate{opacity:0;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:var(--calcite-animation-timing);animation-duration:var(--calcite-animation-timing)}.calcite-animate__in{-webkit-animation-name:in;animation-name:in}.calcite-animate__in-down{-webkit-animation-name:in-down;animation-name:in-down}.calcite-animate__in-up{-webkit-animation-name:in-up;animation-name:in-up}.calcite-animate__in-scale{-webkit-animation-name:in-scale;animation-name:in-scale}:root{--calcite-popper-transition:150ms ease-in-out}:host([hidden]){display:none}:host{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}::slotted(input[slot=hidden-form-input]){bottom:0 !important;left:0 !important;margin:0 !important;opacity:0 !important;outline:none !important;padding:0 !important;position:absolute !important;right:0 !important;top:0 !important;-webkit-transform:none !important;transform:none !important;-webkit-appearance:none !important;z-index:-1 !important}";
@@ -83,8 +191,11 @@ let CalciteInputTimePicker = class {
83
191
  this.active = false;
84
192
  /** The disabled state of the time input */
85
193
  this.disabled = false;
86
- /** Format of the hour value (12-hour or 24-hour) (this will be replaced by locale eventually) */
87
- this.hourDisplayFormat = "12";
194
+ /**
195
+ * BCP 47 language tag for desired language and country format
196
+ * @internal
197
+ */
198
+ this.locale = document.documentElement.lang || navigator.language || "en";
88
199
  /**
89
200
  * When true, makes the component required for form-submission.
90
201
  *
@@ -108,56 +219,60 @@ let CalciteInputTimePicker = class {
108
219
  //--------------------------------------------------------------------------
109
220
  this.calciteInputBlurHandler = () => {
110
221
  this.active = false;
111
- const newValue = formatTimeString(this.calciteInputEl.value) || formatTimeString(this.value);
112
- if (newValue !== this.calciteInputEl.value) {
113
- this.setInputValue(newValue);
114
- }
222
+ const shouldIncludeSeconds = this.shouldIncludeSeconds();
223
+ const localizedInputValue = localizeTimeString(this.calciteInputEl.value, this.locale, shouldIncludeSeconds);
224
+ this.setInputValue(localizedInputValue || localizeTimeString(this.value, this.locale, shouldIncludeSeconds));
115
225
  };
116
226
  this.calciteInputFocusHandler = () => {
117
227
  this.active = true;
118
228
  };
119
229
  this.calciteInputInputHandler = (event) => {
120
- this.setValue({ value: event.detail.value });
230
+ const target = event.target;
231
+ this.setValue({ value: target.value });
232
+ };
233
+ this.timePickerChangeHandler = (event) => {
234
+ event.stopPropagation();
235
+ const target = event.target;
236
+ const value = target.value;
237
+ this.setValue({ value, origin: "time-picker" });
121
238
  };
122
239
  this.setCalciteInputEl = (el) => {
123
240
  this.calciteInputEl = el;
124
241
  };
242
+ this.setCalciteTimePickerEl = (el) => {
243
+ this.calciteTimePickerEl = el;
244
+ };
125
245
  this.setInputValue = (newInputValue) => {
126
246
  if (!this.calciteInputEl) {
127
247
  return;
128
248
  }
129
- if (this.hourDisplayFormat === "12") {
130
- const { hour, minute, second } = parseTimeString(newInputValue);
131
- this.calciteInputEl.value = newInputValue
132
- ? `${getMeridiemHour(hour)}:${minute}${this.step !== 60 ? ":" + second : ""} ${getMeridiem(hour)}`
133
- : null;
134
- }
135
- else {
136
- this.calciteInputEl.value = newInputValue;
137
- }
249
+ this.calciteInputEl.value = newInputValue;
138
250
  };
139
251
  this.setValue = ({ value, origin = "input" }) => {
140
252
  const previousValue = this.value;
141
- const validatedNewValue = formatTimeString(value);
253
+ const newValue = formatTimeString(value);
254
+ const newLocalizedValue = localizeTimeString(newValue, this.locale, this.shouldIncludeSeconds());
142
255
  this.internalValueChange = origin !== "external" && origin !== "loading";
143
256
  const shouldEmit = origin !== "loading" &&
144
257
  origin !== "external" &&
145
258
  ((value !== this.previousValidValue && !value) ||
146
- !!(!this.previousValidValue && validatedNewValue) ||
147
- (validatedNewValue !== this.previousValidValue && validatedNewValue));
259
+ !!(!this.previousValidValue && newValue) ||
260
+ (newValue !== this.previousValidValue && newValue));
148
261
  if (value) {
149
262
  if (shouldEmit) {
150
- this.previousValidValue = validatedNewValue;
263
+ this.previousValidValue = newValue;
151
264
  }
152
- if (validatedNewValue && validatedNewValue !== this.value) {
153
- this.value = validatedNewValue;
265
+ if (newValue && newValue !== this.value) {
266
+ this.value = newValue;
154
267
  }
268
+ this.localizedValue = newLocalizedValue;
155
269
  }
156
270
  else {
157
271
  this.value = value;
272
+ this.localizedValue = null;
158
273
  }
159
274
  if (origin === "time-picker" || origin === "external") {
160
- this.setInputValue(validatedNewValue);
275
+ this.setInputValue(newLocalizedValue);
161
276
  }
162
277
  if (shouldEmit) {
163
278
  const changeEvent = this.calciteInputTimePickerChange.emit();
@@ -168,17 +283,26 @@ let CalciteInputTimePicker = class {
168
283
  this.previousValidValue = previousValue;
169
284
  }
170
285
  else {
171
- this.previousValidValue = validatedNewValue;
286
+ this.previousValidValue = newValue;
172
287
  }
173
288
  }
174
289
  };
175
290
  }
291
+ localeWatcher(newLocale) {
292
+ this.setInputValue(localizeTimeString(this.value, newLocale, this.shouldIncludeSeconds()));
293
+ }
176
294
  valueWatcher(newValue) {
177
295
  if (!this.internalValueChange) {
178
296
  this.setValue({ value: newValue, origin: "external" });
179
297
  }
180
298
  this.internalValueChange = false;
181
299
  }
300
+ clickHandler(event) {
301
+ if (event.composedPath().includes(this.calciteTimePickerEl)) {
302
+ return;
303
+ }
304
+ this.setFocus();
305
+ }
182
306
  keyUpHandler(event) {
183
307
  if (event.key === "Escape" && this.active) {
184
308
  this.active = false;
@@ -189,21 +313,6 @@ let CalciteInputTimePicker = class {
189
313
  event.stopPropagation();
190
314
  this.active = false;
191
315
  }
192
- timePickerChangeHandler(event) {
193
- event.preventDefault();
194
- event.stopPropagation();
195
- if (event.detail) {
196
- const { hour, minute, second } = event.detail;
197
- let value;
198
- if (hour && minute) {
199
- value = second && this.step !== 60 ? `${hour}:${minute}:${second}` : `${hour}:${minute}`;
200
- }
201
- else {
202
- value = "";
203
- }
204
- this.setValue({ value, origin: "time-picker" });
205
- }
206
- }
207
316
  timePickerFocusHandler(event) {
208
317
  event.preventDefault();
209
318
  event.stopPropagation();
@@ -226,6 +335,9 @@ let CalciteInputTimePicker = class {
226
335
  onLabelClick() {
227
336
  this.setFocus();
228
337
  }
338
+ shouldIncludeSeconds() {
339
+ return this.step < 60;
340
+ }
229
341
  //--------------------------------------------------------------------------
230
342
  //
231
343
  // Lifecycle
@@ -233,15 +345,13 @@ let CalciteInputTimePicker = class {
233
345
  //--------------------------------------------------------------------------
234
346
  connectedCallback() {
235
347
  if (this.value) {
236
- this.setValue({ value: this.value, origin: "loading" });
348
+ this.setValue({ value: isValidTime(this.value) ? this.value : undefined, origin: "loading" });
237
349
  }
238
350
  label.connectLabel(this);
239
351
  form.connectForm(this);
240
352
  }
241
353
  componentDidLoad() {
242
- if (this.calciteInputEl.value !== this.value) {
243
- this.setInputValue(this.value);
244
- }
354
+ this.setInputValue(this.localizedValue);
245
355
  }
246
356
  disconnectedCallback() {
247
357
  label.disconnectLabel(this);
@@ -253,38 +363,44 @@ let CalciteInputTimePicker = class {
253
363
  //
254
364
  // --------------------------------------------------------------------------
255
365
  render() {
256
- const { hour, minute, second } = parseTimeString(this.value);
257
366
  const popoverId = `${this.referenceElementId}-popover`;
258
- return (index.h(index.Host, null, index.h("div", { "aria-controls": popoverId, "aria-haspopup": "dialog", "aria-label": this.name, "aria-owns": popoverId, id: this.referenceElementId, role: "combobox" }, index.h("calcite-input", { disabled: this.disabled, icon: "clock", label: label.getLabelText(this), onCalciteInputBlur: this.calciteInputBlurHandler, onCalciteInputFocus: this.calciteInputFocusHandler, onCalciteInputInput: this.calciteInputInputHandler, ref: this.setCalciteInputEl, scale: this.scale, step: this.step })), index.h("calcite-popover", { id: popoverId, label: "Time Picker", open: this.active || false, referenceElement: this.referenceElementId }, index.h("calcite-time-picker", { hour: hour, "hour-display-format": this.hourDisplayFormat, intlHour: this.intlHour, intlHourDown: this.intlHourDown, intlHourUp: this.intlHourUp, intlMeridiem: this.intlMeridiem, intlMeridiemDown: this.intlMeridiemDown, intlMeridiemUp: this.intlMeridiemUp, intlMinute: this.intlMinute, intlMinuteDown: this.intlMinuteDown, intlMinuteUp: this.intlMinuteUp, intlSecond: this.intlSecond, intlSecondDown: this.intlSecondDown, intlSecondUp: this.intlSecondUp, minute: minute, scale: this.scale, second: second, step: this.step })), index.h(form.HiddenFormInputSlot, { component: this })));
367
+ return (index.h(index.Host, null, index.h("div", { "aria-controls": popoverId, "aria-haspopup": "dialog", "aria-label": this.name, "aria-owns": popoverId, id: this.referenceElementId, role: "combobox" }, index.h("calcite-input", { disabled: this.disabled, icon: "clock", label: label.getLabelText(this), onCalciteInputBlur: this.calciteInputBlurHandler, onCalciteInputFocus: this.calciteInputFocusHandler, onCalciteInputInput: this.calciteInputInputHandler, ref: this.setCalciteInputEl, scale: this.scale, step: this.step })), index.h("calcite-popover", { id: popoverId, label: "Time Picker", open: this.active || false, referenceElement: this.referenceElementId }, index.h("calcite-time-picker", { intlHour: this.intlHour, intlHourDown: this.intlHourDown, intlHourUp: this.intlHourUp, intlMeridiem: this.intlMeridiem, intlMeridiemDown: this.intlMeridiemDown, intlMeridiemUp: this.intlMeridiemUp, intlMinute: this.intlMinute, intlMinuteDown: this.intlMinuteDown, intlMinuteUp: this.intlMinuteUp, intlSecond: this.intlSecond, intlSecondDown: this.intlSecondDown, intlSecondUp: this.intlSecondUp, lang: this.locale, onCalciteTimePickerChange: this.timePickerChangeHandler, ref: this.setCalciteTimePickerEl, scale: this.scale, step: this.step, value: this.value })), index.h(form.HiddenFormInputSlot, { component: this })));
259
368
  }
260
369
  get el() { return index.getElement(this); }
261
370
  static get watchers() { return {
371
+ "locale": ["localeWatcher"],
262
372
  "value": ["valueWatcher"]
263
373
  }; }
264
374
  };
265
375
  CalciteInputTimePicker.style = calciteInputTimePickerCss;
266
376
 
267
377
  const CSS = {
378
+ button: "button",
268
379
  buttonBottomLeft: "button--bottom-left",
269
380
  buttonBottomRight: "button--bottom-right",
270
- button: "button",
271
- delimiter: "delimiter",
272
- hour: "hour",
273
381
  buttonHourDown: "button--hour-down",
274
382
  buttonHourUp: "button--hour-up",
275
- input: "input",
276
- meridiem: "meridiem",
277
383
  buttonMeridiemDown: "button--meridiem-down",
278
384
  buttonMeridiemUp: "button--meridiem-up",
279
- minute: "minute",
280
385
  buttonMinuteDown: "button--minute-down",
281
386
  buttonMinuteUp: "button--minute-up",
282
- second: "second",
283
387
  buttonSecondDown: "button--second-down",
284
388
  buttonSecondUp: "button--second-up",
285
- timePicker: "time-picker",
286
389
  buttonTopLeft: "button--top-left",
287
- buttonTopRight: "button--top-right"
390
+ buttonTopRight: "button--top-right",
391
+ column: "column",
392
+ delimiter: "delimiter",
393
+ hour: "hour",
394
+ input: "input",
395
+ meridiem: "meridiem",
396
+ minute: "minute",
397
+ second: "second",
398
+ showMeridiem: "show-meridiem",
399
+ showSecond: "show-second",
400
+ "scale-s": "scale-s",
401
+ "scale-m": "scale-m",
402
+ "scale-l": "scale-l",
403
+ timePicker: "time-picker"
288
404
  };
289
405
  const TEXT = {
290
406
  hour: "Hour",
@@ -301,8 +417,11 @@ const TEXT = {
301
417
  secondUp: "Increase second"
302
418
  };
303
419
 
304
- const calciteTimePickerCss = "@-webkit-keyframes in{0%{opacity:0}100%{opacity:1}}@keyframes in{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}@keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}:root{--calcite-animation-timing:300ms}.calcite-animate{opacity:0;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:var(--calcite-animation-timing);animation-duration:var(--calcite-animation-timing)}.calcite-animate__in{-webkit-animation-name:in;animation-name:in}.calcite-animate__in-down{-webkit-animation-name:in-down;animation-name:in-down}.calcite-animate__in-up{-webkit-animation-name:in-up;animation-name:in-up}.calcite-animate__in-scale{-webkit-animation-name:in-scale;animation-name:in-scale}:root{--calcite-popper-transition:150ms ease-in-out}:host([hidden]){display:none}:host{color:var(--calcite-ui-text-1);display:inline-block;font-weight:var(--calcite-font-weight-medium);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.time-picker{-webkit-box-shadow:0 6px 20px -4px rgba(0, 0, 0, 0.1), 0 4px 12px -2px rgba(0, 0, 0, 0.08);box-shadow:0 6px 20px -4px rgba(0, 0, 0, 0.1), 0 4px 12px -2px rgba(0, 0, 0, 0.08);-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;border-radius:var(--calcite-border-radius)}span{-ms-flex-align:center;align-items:center;background-color:var(--calcite-ui-foreground-1);display:-ms-inline-flexbox;display:inline-flex;-ms-flex-pack:center;justify-content:center}span.button{cursor:pointer}span.button:hover,span.button:focus{background-color:var(--calcite-ui-foreground-2)}span.button:focus{outline:2px solid transparent;outline-offset:2px}span.button:active{background-color:var(--calcite-ui-foreground-3)}span.button.top-left{border-top-left-radius:var(--calcite-border-radius)}span.button.bottom-left{border-bottom-left-radius:var(--calcite-border-radius)}span.button.top-right{border-top-right-radius:var(--calcite-border-radius)}span.button.bottom-right{border-bottom-right-radius:var(--calcite-border-radius)}span.button calcite-icon{color:var(--calcite-ui-text-3)}span.input{font-weight:var(--calcite-font-weight-medium);position:relative}span.input:hover{-webkit-box-shadow:inset 0 0 0 2px var(--calcite-ui-foreground-2);box-shadow:inset 0 0 0 2px var(--calcite-ui-foreground-2)}span.input:focus,span.input:hover:focus{outline:2px solid transparent;outline-offset:2px;-webkit-box-shadow:inset 0 0 0 2px var(--calcite-ui-brand);box-shadow:inset 0 0 0 2px var(--calcite-ui-brand)}:host([scale=s]){font-size:var(--calcite-font-size--1)}:host([scale=s]) span{height:24px;width:40px}:host([scale=s]) .delimiter{height:72px}:host([scale=s][hour-display-format=\"12\"]) .time-picker{width:124.2px}:host([scale=s][hour-display-format=\"12\"]:not([step=\"60\"])) .time-picker{width:168px}:host([scale=s][hour-display-format=\"24\"]) .time-picker{width:84.2px}:host([scale=s][hour-display-format=\"24\"]:not([step=\"60\"])) .time-picker{width:128.4px}:host([scale=m]){font-size:var(--calcite-font-size-0)}:host([scale=m]) span{height:32px;width:44px}:host([scale=m]) .delimiter{height:96px}:host([scale=m][hour-display-format=\"12\"]) .time-picker{width:136.8px}:host([scale=m][hour-display-format=\"12\"]:not([step=\"60\"])) .time-picker{width:186px}:host([scale=m][hour-display-format=\"24\"]) .time-picker{width:92.8px}:host([scale=m][hour-display-format=\"24\"]:not([step=\"60\"])) .time-picker{width:141.6px}:host([scale=l]){font-size:var(--calcite-font-size-1)}:host([scale=l]) span{height:48px;width:64px}:host([scale=l]) .delimiter{height:144px}:host([scale=l][hour-display-format=\"12\"]) .time-picker{width:198px}:host([scale=l][hour-display-format=\"12\"]:not([step=\"60\"])) .time-picker{width:268px}:host([scale=l][hour-display-format=\"24\"]) .time-picker{width:134px}:host([scale=l][hour-display-format=\"24\"]:not([step=\"60\"])) .time-picker{width:204px}";
420
+ const calciteTimePickerCss = "@-webkit-keyframes in{0%{opacity:0}100%{opacity:1}}@keyframes in{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}@keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}:root{--calcite-animation-timing:300ms}.calcite-animate{opacity:0;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:var(--calcite-animation-timing);animation-duration:var(--calcite-animation-timing)}.calcite-animate__in{-webkit-animation-name:in;animation-name:in}.calcite-animate__in-down{-webkit-animation-name:in-down;animation-name:in-down}.calcite-animate__in-up{-webkit-animation-name:in-up;animation-name:in-up}.calcite-animate__in-scale{-webkit-animation-name:in-scale;animation-name:in-scale}:root{--calcite-popper-transition:150ms ease-in-out}:host([hidden]){display:none}:host{display:inline-block}.time-picker{background-color:var(--calcite-ui-foreground-1);display:-ms-flexbox;display:flex;font-weight:var(--calcite-font-weight-medium);-ms-flex-align:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-box-shadow:0 6px 20px -4px rgba(0, 0, 0, 0.1), 0 4px 12px -2px rgba(0, 0, 0, 0.08);box-shadow:0 6px 20px -4px rgba(0, 0, 0, 0.1), 0 4px 12px -2px rgba(0, 0, 0, 0.08);color:var(--calcite-ui-text-1);border-radius:var(--calcite-border-radius)}.time-picker .column{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.time-picker .button{background-color:var(--calcite-ui-foreground-1);cursor:pointer;display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.time-picker .button:hover,.time-picker .button:focus{background-color:var(--calcite-ui-foreground-2);outline:2px solid transparent;outline-offset:2px}.time-picker .button:active{background-color:var(--calcite-ui-foreground-3)}.time-picker .button.top-left{border-top-left-radius:var(--calcite-border-radius)}.time-picker .button.bottom-left{border-bottom-left-radius:var(--calcite-border-radius)}.time-picker .button.top-right{border-top-right-radius:var(--calcite-border-radius)}.time-picker .button.bottom-right{border-bottom-right-radius:var(--calcite-border-radius)}.time-picker .button calcite-icon{color:var(--calcite-ui-text-3)}.time-picker .input{background-color:var(--calcite-ui-foreground-1);cursor:pointer;font-weight:var(--calcite-font-weight-medium);display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.time-picker .input:hover{-webkit-box-shadow:inset 0 0 0 2px var(--calcite-ui-foreground-2);box-shadow:inset 0 0 0 2px var(--calcite-ui-foreground-2)}.time-picker .input:focus,.time-picker .input:hover:focus{outline:2px solid transparent;outline-offset:2px;-webkit-box-shadow:inset 0 0 0 2px var(--calcite-ui-brand);box-shadow:inset 0 0 0 2px var(--calcite-ui-brand)}.time-picker.scale-s{font-size:var(--calcite-font-size--1)}.time-picker.scale-s .button,.time-picker.scale-s .input{padding-left:0.75rem;padding-right:0.75rem;padding-top:0.25rem;padding-bottom:0.25rem}.time-picker.scale-s:not(.show-meridiem) .delimiter:last-child{-webkit-padding-end:0.75rem;padding-inline-end:0.75rem}.time-picker.scale-m{font-size:var(--calcite-font-size-0)}.time-picker.scale-m .button,.time-picker.scale-m .input{padding-left:1rem;padding-right:1rem;padding-top:0.5rem;padding-bottom:0.5rem}.time-picker.scale-m:not(.show-meridiem) .delimiter:last-child{-webkit-padding-end:1rem;padding-inline-end:1rem}.time-picker.scale-l{font-size:var(--calcite-font-size-1)}.time-picker.scale-l .button,.time-picker.scale-l .input{padding-left:1.25rem;padding-right:1.25rem;padding-top:0.75rem;padding-bottom:0.75rem}.time-picker.scale-l:not(.show-meridiem) .delimiter:last-child{-webkit-padding-end:1.25rem;padding-inline-end:1.25rem}";
305
421
 
422
+ function capitalize(str) {
423
+ return str.charAt(0).toUpperCase() + str.slice(1);
424
+ }
306
425
  let CalciteTimePicker = class {
307
426
  constructor(hostRef) {
308
427
  index.registerInstance(this, hostRef);
@@ -314,10 +433,6 @@ let CalciteTimePicker = class {
314
433
  // Properties
315
434
  //
316
435
  //--------------------------------------------------------------------------
317
- /** The hour value (24-hour format) */
318
- this.hour = null;
319
- /** Format of the hour value (12-hour or 24-hour) (this will be replaced by locale eventually) */
320
- this.hourDisplayFormat = "12";
321
436
  /** aria-label for the hour input
322
437
  * @default "Hour"
323
438
  */
@@ -366,35 +481,25 @@ let CalciteTimePicker = class {
366
481
  * @default "Increase second"
367
482
  */
368
483
  this.intlSecondUp = TEXT.secondUp;
369
- /** The minute value */
370
- this.minute = null;
371
- /** The second value */
372
- this.second = null;
484
+ /**
485
+ * BCP 47 language tag for desired language and country format
486
+ * @internal
487
+ */
488
+ this.locale = document.documentElement.lang || navigator.language || "en";
373
489
  /** The scale (size) of the time picker */
374
490
  this.scale = "m";
375
491
  /** number that specifies the granularity that the value must adhere to */
376
492
  this.step = 60;
377
- this.timeChanged = false;
378
- // --------------------------------------------------------------------------
379
- //
380
- // State
381
- //
382
- // --------------------------------------------------------------------------
383
- /** The am/pm value */
384
- this.meridiem = null;
385
- this.displayHour = this.getDisplayHour();
386
- // --------------------------------------------------------------------------
387
- //
388
- // Private Methods
389
- //
390
- // --------------------------------------------------------------------------
493
+ /** The selected time in UTC */
494
+ this.value = null;
495
+ this.showSecond = this.step < 60;
391
496
  this.decrementHour = () => {
392
497
  const newHour = !this.hour ? 0 : this.hour === "00" ? 23 : parseInt(this.hour) - 1;
393
- this.setTime("hour", newHour);
498
+ this.setValuePart("hour", newHour);
394
499
  };
395
500
  this.decrementMeridiem = () => {
396
501
  const newMeridiem = this.meridiem === "PM" ? "AM" : "PM";
397
- this.setTime("meridiem", newMeridiem);
502
+ this.setValuePart("meridiem", newMeridiem);
398
503
  };
399
504
  this.decrementMinuteOrSecond = (key) => {
400
505
  let newValue;
@@ -405,7 +510,7 @@ let CalciteTimePicker = class {
405
510
  else {
406
511
  newValue = 59;
407
512
  }
408
- this.setTime(key, newValue);
513
+ this.setValuePart(key, newValue);
409
514
  };
410
515
  this.decrementMinute = () => {
411
516
  this.decrementMinuteOrSecond("minute");
@@ -427,7 +532,7 @@ let CalciteTimePicker = class {
427
532
  const keyAsNumber = parseInt(key);
428
533
  let newHour;
429
534
  if (number.isValidNumber(this.hour)) {
430
- switch (this.hourDisplayFormat) {
535
+ switch (this.hourCycle) {
431
536
  case "12":
432
537
  newHour =
433
538
  this.hour === "01" && keyAsNumber >= 0 && keyAsNumber <= 2
@@ -450,13 +555,13 @@ let CalciteTimePicker = class {
450
555
  else {
451
556
  newHour = keyAsNumber;
452
557
  }
453
- this.setTime("hour", newHour);
558
+ this.setValuePart("hour", newHour);
454
559
  }
455
560
  else {
456
561
  switch (key) {
457
562
  case "Backspace":
458
563
  case "Delete":
459
- this.setTime("hour", null);
564
+ this.setValuePart("hour", null);
460
565
  break;
461
566
  case "ArrowDown":
462
567
  event.preventDefault();
@@ -480,7 +585,7 @@ let CalciteTimePicker = class {
480
585
  };
481
586
  this.incrementMeridiem = () => {
482
587
  const newMeridiem = this.meridiem === "AM" ? "PM" : "AM";
483
- this.setTime("meridiem", newMeridiem);
588
+ this.setValuePart("meridiem", newMeridiem);
484
589
  };
485
590
  this.incrementHour = () => {
486
591
  const newHour = number.isValidNumber(this.hour)
@@ -488,7 +593,7 @@ let CalciteTimePicker = class {
488
593
  ? 0
489
594
  : parseInt(this.hour) + 1
490
595
  : 1;
491
- this.setTime("hour", newHour);
596
+ this.setValuePart("hour", newHour);
492
597
  };
493
598
  this.incrementMinuteOrSecond = (key) => {
494
599
  const newValue = number.isValidNumber(this[key])
@@ -496,7 +601,7 @@ let CalciteTimePicker = class {
496
601
  ? 0
497
602
  : parseInt(this[key]) + 1
498
603
  : 0;
499
- this.setTime(key, newValue);
604
+ this.setValuePart(key, newValue);
500
605
  };
501
606
  this.incrementMinute = () => {
502
607
  this.incrementMinuteOrSecond("minute");
@@ -512,14 +617,14 @@ let CalciteTimePicker = class {
512
617
  this.meridiemKeyDownHandler = (event) => {
513
618
  switch (event.key) {
514
619
  case "a":
515
- this.setTime("meridiem", "AM");
620
+ this.setValuePart("meridiem", "AM");
516
621
  break;
517
622
  case "p":
518
- this.setTime("meridiem", "PM");
623
+ this.setValuePart("meridiem", "PM");
519
624
  break;
520
625
  case "Backspace":
521
626
  case "Delete":
522
- this.setTime("meridiem", null);
627
+ this.setValuePart("meridiem", null);
523
628
  break;
524
629
  case "ArrowUp":
525
630
  event.preventDefault();
@@ -560,13 +665,13 @@ let CalciteTimePicker = class {
560
665
  else {
561
666
  newMinute = keyAsNumber;
562
667
  }
563
- this.setTime("minute", newMinute);
668
+ this.setValuePart("minute", newMinute);
564
669
  }
565
670
  else {
566
671
  switch (key) {
567
672
  case "Backspace":
568
673
  case "Delete":
569
- this.setTime("minute", null);
674
+ this.setValuePart("minute", null);
570
675
  break;
571
676
  case "ArrowDown":
572
677
  event.preventDefault();
@@ -608,13 +713,13 @@ let CalciteTimePicker = class {
608
713
  else {
609
714
  newSecond = keyAsNumber;
610
715
  }
611
- this.setTime("second", newSecond);
716
+ this.setValuePart("second", newSecond);
612
717
  }
613
718
  else {
614
719
  switch (key) {
615
720
  case "Backspace":
616
721
  case "Delete":
617
- this.setTime("second", null);
722
+ this.setValuePart("second", null);
618
723
  break;
619
724
  case "ArrowDown":
620
725
  event.preventDefault();
@@ -636,59 +741,96 @@ let CalciteTimePicker = class {
636
741
  this.incrementSecond();
637
742
  }
638
743
  };
639
- this.setTime = (key, value, emit = true) => {
640
- switch (key) {
641
- default:
642
- return;
643
- case "hour":
644
- this.hour = typeof value === "number" ? formatTimePart(value) : value;
645
- break;
646
- case "minute":
647
- this.minute = typeof value === "number" ? formatTimePart(value) : value;
648
- break;
649
- case "second":
650
- this.second = typeof value === "number" ? formatTimePart(value) : value;
651
- break;
652
- case "meridiem":
653
- if (number.isValidNumber(this.hour)) {
654
- const hourAsNumber = parseInt(this.hour);
655
- switch (value) {
656
- case "AM":
657
- if (hourAsNumber >= 12) {
658
- this.hour = formatTimePart(hourAsNumber - 12);
659
- }
660
- break;
661
- case "PM":
662
- if (hourAsNumber < 12) {
663
- this.hour = formatTimePart(hourAsNumber + 12);
664
- }
665
- break;
666
- }
667
- this.meridiem = value;
668
- }
669
- else {
670
- this.meridiem = value;
744
+ this.setHourEl = (el) => (this.hourEl = el);
745
+ this.setMeridiemEl = (el) => (this.meridiemEl = el);
746
+ this.setMinuteEl = (el) => (this.minuteEl = el);
747
+ this.setSecondEl = (el) => (this.secondEl = el);
748
+ this.setValue = (value, emit = true) => {
749
+ if (isValidTime(value)) {
750
+ const { hour, minute, second } = parseTimeString(value);
751
+ const { localizedHour, localizedHourSuffix, localizedMinute, localizedMinuteSuffix, localizedSecond, localizedSecondSuffix, localizedMeridiem } = localizeTimeStringToParts(value, this.locale);
752
+ this.localizedHour = localizedHour;
753
+ this.localizedHourSuffix = localizedHourSuffix;
754
+ this.localizedMinute = localizedMinute;
755
+ this.localizedMinuteSuffix = localizedMinuteSuffix;
756
+ this.localizedSecond = localizedSecond;
757
+ this.localizedSecondSuffix = localizedSecondSuffix;
758
+ this.hour = hour;
759
+ this.minute = minute;
760
+ this.second = second;
761
+ if (localizedMeridiem) {
762
+ this.localizedMeridiem = localizedMeridiem;
763
+ this.meridiem = getMeridiem(this.hour);
764
+ }
765
+ }
766
+ else {
767
+ this.hour = null;
768
+ this.localizedHour = null;
769
+ this.localizedHourSuffix = null;
770
+ this.localizedMeridiem = null;
771
+ this.localizedMinute = null;
772
+ this.localizedMinuteSuffix = null;
773
+ this.localizedSecond = null;
774
+ this.localizedSecondSuffix = null;
775
+ this.meridiem = null;
776
+ this.minute = null;
777
+ this.second = null;
778
+ this.value = null;
779
+ }
780
+ if (emit) {
781
+ this.calciteTimePickerChange.emit();
782
+ }
783
+ };
784
+ this.setValuePart = (key, value, emit = true) => {
785
+ var _a;
786
+ if (key === "meridiem") {
787
+ this.meridiem = value;
788
+ if (number.isValidNumber(this.hour)) {
789
+ const hourAsNumber = parseInt(this.hour);
790
+ switch (value) {
791
+ case "AM":
792
+ if (hourAsNumber >= 12) {
793
+ this.hour = formatTimePart(hourAsNumber - 12);
794
+ }
795
+ break;
796
+ case "PM":
797
+ if (hourAsNumber < 12) {
798
+ this.hour = formatTimePart(hourAsNumber + 12);
799
+ }
800
+ break;
671
801
  }
672
- break;
802
+ this.localizedHour = localizeTimePart(this.hour, "hour", this.locale);
803
+ }
804
+ }
805
+ else {
806
+ this[key] = typeof value === "number" ? formatTimePart(value) : value;
807
+ this[`localized${capitalize(key)}`] = localizeTimePart(this[key], key, this.locale);
808
+ }
809
+ if (this.hour && this.minute) {
810
+ const showSeconds = this.second && this.showSecond;
811
+ this.value = `${this.hour}:${this.minute}:${showSeconds ? this.second : "00"}`;
673
812
  }
674
- this.timeChanged = true;
813
+ else {
814
+ this.value = null;
815
+ }
816
+ this.localizedMeridiem = this.value
817
+ ? ((_a = localizeTimeStringToParts(this.value, this.locale)) === null || _a === void 0 ? void 0 : _a.localizedMeridiem) || null
818
+ : localizeTimePart(this.meridiem, "meridiem", this.locale);
675
819
  if (emit) {
676
- this.calciteTimePickerChange.emit(this.getTime());
820
+ this.calciteTimePickerChange.emit();
677
821
  }
678
822
  };
679
823
  }
680
- hourChanged(newHour) {
681
- if (this.hourDisplayFormat === "12" && number.isValidNumber(newHour)) {
682
- this.meridiem = getMeridiem(newHour);
683
- }
824
+ localeWatcher(newLocale) {
825
+ this.hourCycle = getLocaleHourCycle(newLocale);
826
+ this.setValue(this.value, false);
684
827
  }
685
- timeChangeHandler() {
686
- const { hour, minute } = this.getTime();
687
- if (!hour && !minute) {
688
- this.setTime("meridiem", null, false);
689
- }
690
- if (this.timeChanged) {
691
- this.timeChanged = false;
828
+ valueWatcher(newValue) {
829
+ this.setValue(newValue, false);
830
+ }
831
+ hourChanged(newHour) {
832
+ if (this.meridiem && number.isValidNumber(newHour)) {
833
+ this.setValuePart("meridiem", getMeridiem(newHour));
692
834
  }
693
835
  }
694
836
  //--------------------------------------------------------------------------
@@ -719,7 +861,7 @@ let CalciteTimePicker = class {
719
861
  if (this.step !== 60) {
720
862
  this.setFocus("second");
721
863
  }
722
- else if (this.hourDisplayFormat === "12") {
864
+ else if (this.hourCycle === "12") {
723
865
  this.setFocus("meridiem");
724
866
  }
725
867
  break;
@@ -731,7 +873,7 @@ let CalciteTimePicker = class {
731
873
  this.setFocus("minute");
732
874
  break;
733
875
  case "ArrowRight":
734
- if (this.hourDisplayFormat === "12") {
876
+ if (this.hourCycle === "12") {
735
877
  this.setFocus("meridiem");
736
878
  }
737
879
  break;
@@ -761,6 +903,11 @@ let CalciteTimePicker = class {
761
903
  var _a;
762
904
  (_a = this[`${target || "hour"}El`]) === null || _a === void 0 ? void 0 : _a.focus();
763
905
  }
906
+ // --------------------------------------------------------------------------
907
+ //
908
+ // Private Methods
909
+ //
910
+ // --------------------------------------------------------------------------
764
911
  buttonActivated(event) {
765
912
  const key = event.key;
766
913
  if (key === " ") {
@@ -768,40 +915,14 @@ let CalciteTimePicker = class {
768
915
  }
769
916
  return number.isActivationKey(key);
770
917
  }
771
- getDisplayHour() {
772
- if (!this.hour) {
773
- return "--";
774
- }
775
- if (this.hourDisplayFormat === "12") {
776
- return getMeridiemHour(this.hour);
777
- }
778
- return this.hour;
779
- }
780
- getTime() {
781
- return {
782
- hour: this.hour,
783
- minute: this.minute,
784
- second: this.second
785
- };
786
- }
787
918
  // --------------------------------------------------------------------------
788
919
  //
789
920
  // Lifecycle
790
921
  //
791
922
  // --------------------------------------------------------------------------
792
923
  connectedCallback() {
793
- if (this.hourDisplayFormat === "12") {
794
- this.meridiem = getMeridiem(this.hour);
795
- }
796
- if (number.isValidNumber(this.hour)) {
797
- this.hour = formatTimePart(parseInt(this.hour));
798
- }
799
- if (number.isValidNumber(this.minute)) {
800
- this.minute = formatTimePart(parseInt(this.minute));
801
- }
802
- if (number.isValidNumber(this.second)) {
803
- this.second = formatTimePart(parseInt(this.second));
804
- }
924
+ this.setValue(this.value, false);
925
+ this.hourCycle = getLocaleHourCycle(this.locale);
805
926
  }
806
927
  // --------------------------------------------------------------------------
807
928
  //
@@ -809,58 +930,63 @@ let CalciteTimePicker = class {
809
930
  //
810
931
  // --------------------------------------------------------------------------
811
932
  render() {
812
- const iconScale = this.scale === "s" || this.scale === "m" ? "s" : "m";
813
- const includeSeconds = this.step !== 60;
814
933
  const hourIsNumber = number.isValidNumber(this.hour);
934
+ const iconScale = this.scale === "s" || this.scale === "m" ? "s" : "m";
815
935
  const minuteIsNumber = number.isValidNumber(this.minute);
816
936
  const secondIsNumber = number.isValidNumber(this.second);
817
- return (index.h(index.Host, null, index.h("div", { class: CSS.timePicker }, index.h("div", { role: "group" }, index.h("span", { "aria-label": this.intlHourUp, class: {
937
+ const showMeridiem = this.hourCycle === "12";
938
+ return (index.h("div", { class: {
939
+ [CSS.timePicker]: true,
940
+ [CSS.showMeridiem]: showMeridiem,
941
+ [CSS.showSecond]: this.showSecond,
942
+ [CSS[`scale-${this.scale}`]]: true
943
+ } }, index.h("div", { class: CSS.column, role: "group" }, index.h("span", { "aria-label": this.intlHourUp, class: {
818
944
  [CSS.button]: true,
819
945
  [CSS.buttonHourUp]: true,
820
946
  [CSS.buttonTopLeft]: true
821
- }, onClick: this.incrementHour, onKeyDown: this.hourUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-up", scale: iconScale })), index.h("span", { "aria-label": this.intlHour, "aria-valuemax": "23", "aria-valuemin": "1", "aria-valuenow": hourIsNumber && parseInt(this.hour), "aria-valuetext": this.hour, class: {
947
+ }, onClick: this.incrementHour, onKeyDown: this.hourUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-up", scale: iconScale })), index.h("span", { "aria-label": this.intlHour, "aria-valuemax": "23", "aria-valuemin": "1", "aria-valuenow": (hourIsNumber && parseInt(this.hour)) || "0", "aria-valuetext": this.hour, class: {
822
948
  [CSS.input]: true,
823
949
  [CSS.hour]: true
824
- }, onFocus: this.focusHandler, onKeyDown: this.hourKeyDownHandler, ref: (el) => (this.hourEl = el), role: "spinbutton", tabIndex: 0 }, this.getDisplayHour()), index.h("span", { "aria-label": this.intlHourDown, class: {
950
+ }, onFocus: this.focusHandler, onKeyDown: this.hourKeyDownHandler, ref: this.setHourEl, role: "spinbutton", tabIndex: 0 }, this.localizedHour || "--"), index.h("span", { "aria-label": this.intlHourDown, class: {
825
951
  [CSS.button]: true,
826
952
  [CSS.buttonHourDown]: true,
827
953
  [CSS.buttonBottomLeft]: true
828
- }, onClick: this.decrementHour, onKeyDown: this.hourDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-down", scale: iconScale }))), index.h("span", { class: CSS.delimiter }, ":"), index.h("div", { role: "group" }, index.h("span", { "aria-label": this.intlMinuteUp, class: {
954
+ }, onClick: this.decrementHour, onKeyDown: this.hourDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-down", scale: iconScale }))), index.h("span", { class: CSS.delimiter }, this.localizedHourSuffix), index.h("div", { class: CSS.column, role: "group" }, index.h("span", { "aria-label": this.intlMinuteUp, class: {
829
955
  [CSS.button]: true,
830
956
  [CSS.buttonMinuteUp]: true
831
- }, onClick: this.incrementMinute, onKeyDown: this.minuteUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-up", scale: iconScale })), index.h("span", { "aria-label": this.intlMinute, "aria-valuemax": "12", "aria-valuemin": "1", "aria-valuenow": minuteIsNumber && parseInt(this.minute), "aria-valuetext": this.minute, class: {
957
+ }, onClick: this.incrementMinute, onKeyDown: this.minuteUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-up", scale: iconScale })), index.h("span", { "aria-label": this.intlMinute, "aria-valuemax": "12", "aria-valuemin": "1", "aria-valuenow": (minuteIsNumber && parseInt(this.minute)) || "0", "aria-valuetext": this.minute, class: {
832
958
  [CSS.input]: true,
833
959
  [CSS.minute]: true
834
- }, onFocus: this.focusHandler, onKeyDown: this.minuteKeyDownHandler, ref: (el) => (this.minuteEl = el), role: "spinbutton", tabIndex: 0 }, this.minute ? this.minute : "--"), index.h("span", { "aria-label": this.intlMinuteDown, class: {
960
+ }, onFocus: this.focusHandler, onKeyDown: this.minuteKeyDownHandler, ref: this.setMinuteEl, role: "spinbutton", tabIndex: 0 }, this.localizedMinute || "--"), index.h("span", { "aria-label": this.intlMinuteDown, class: {
835
961
  [CSS.button]: true,
836
962
  [CSS.buttonMinuteDown]: true
837
- }, onClick: this.decrementMinute, onKeyDown: this.minuteDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-down", scale: iconScale }))), includeSeconds && index.h("span", { class: CSS.delimiter }, ":"), includeSeconds && (index.h("div", { role: "group" }, index.h("span", { "aria-label": this.intlSecondUp, class: {
963
+ }, onClick: this.decrementMinute, onKeyDown: this.minuteDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-down", scale: iconScale }))), this.showSecond && index.h("span", { class: CSS.delimiter }, this.localizedMinuteSuffix), this.showSecond && (index.h("div", { class: CSS.column, role: "group" }, index.h("span", { "aria-label": this.intlSecondUp, class: {
838
964
  [CSS.button]: true,
839
965
  [CSS.buttonSecondUp]: true
840
- }, onClick: this.incrementSecond, onKeyDown: this.secondUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-up", scale: iconScale })), index.h("span", { "aria-label": this.intlSecond, "aria-valuemax": "59", "aria-valuemin": "0", "aria-valuenow": secondIsNumber && parseInt(this.second), "aria-valuetext": this.second, class: {
966
+ }, onClick: this.incrementSecond, onKeyDown: this.secondUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-up", scale: iconScale })), index.h("span", { "aria-label": this.intlSecond, "aria-valuemax": "59", "aria-valuemin": "0", "aria-valuenow": (secondIsNumber && parseInt(this.second)) || "0", "aria-valuetext": this.second, class: {
841
967
  [CSS.input]: true,
842
968
  [CSS.second]: true
843
- }, onFocus: this.focusHandler, onKeyDown: this.secondKeyDownHandler, ref: (el) => (this.secondEl = el), role: "spinbutton", tabIndex: 0 }, this.second ? this.second : "--"), index.h("span", { "aria-label": this.intlSecondDown, class: {
969
+ }, onFocus: this.focusHandler, onKeyDown: this.secondKeyDownHandler, ref: this.setSecondEl, role: "spinbutton", tabIndex: 0 }, this.localizedSecond || "--"), index.h("span", { "aria-label": this.intlSecondDown, class: {
844
970
  [CSS.button]: true,
845
971
  [CSS.buttonSecondDown]: true
846
- }, onClick: this.decrementSecond, onKeyDown: this.secondDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-down", scale: iconScale })))), this.hourDisplayFormat === "12" && (index.h("div", { role: "group" }, index.h("span", { "aria-label": this.intlMeridiemUp, class: {
972
+ }, onClick: this.decrementSecond, onKeyDown: this.secondDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-down", scale: iconScale })))), this.localizedSecondSuffix && (index.h("span", { class: CSS.delimiter }, this.localizedSecondSuffix)), showMeridiem && (index.h("div", { class: CSS.column, role: "group" }, index.h("span", { "aria-label": this.intlMeridiemUp, class: {
847
973
  [CSS.button]: true,
848
974
  [CSS.buttonMeridiemUp]: true,
849
975
  [CSS.buttonTopRight]: true
850
- }, onClick: this.incrementMeridiem, onKeyDown: this.meridiemUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-up", scale: iconScale })), index.h("span", { "aria-label": this.intlMeridiem, "aria-valuemax": "2", "aria-valuemin": "1", "aria-valuenow": this.meridiem === "AM" ? "1" : this.meridiem === "PM" ? "2" : undefined, "aria-valuetext": this.meridiem, class: {
976
+ }, onClick: this.incrementMeridiem, onKeyDown: this.meridiemUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-up", scale: iconScale })), index.h("span", { "aria-label": this.intlMeridiem, "aria-valuemax": "2", "aria-valuemin": "1", "aria-valuenow": (this.meridiem === "PM" && "2") || "1", "aria-valuetext": this.meridiem, class: {
851
977
  [CSS.input]: true,
852
978
  [CSS.meridiem]: true
853
- }, onFocus: this.focusHandler, onKeyDown: this.meridiemKeyDownHandler, ref: (el) => (this.meridiemEl = el), role: "spinbutton", tabIndex: 0 }, this.meridiem ? this.meridiem : "--"), index.h("span", { "aria-label": this.intlMeridiemDown, class: {
979
+ }, onFocus: this.focusHandler, onKeyDown: this.meridiemKeyDownHandler, ref: this.setMeridiemEl, role: "spinbutton", tabIndex: 0 }, this.localizedMeridiem || "--"), index.h("span", { "aria-label": this.intlMeridiemDown, class: {
854
980
  [CSS.button]: true,
855
981
  [CSS.buttonMeridiemDown]: true,
856
982
  [CSS.buttonBottomRight]: true
857
- }, onClick: this.decrementMeridiem, onKeyDown: this.meridiemDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-down", scale: iconScale })))))));
983
+ }, onClick: this.decrementMeridiem, onKeyDown: this.meridiemDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, index.h("calcite-icon", { icon: "chevron-down", scale: iconScale }))))));
858
984
  }
859
985
  get el() { return index.getElement(this); }
860
986
  static get watchers() { return {
861
- "hour": ["hourChanged", "timeChangeHandler"],
862
- "minute": ["timeChangeHandler"],
863
- "second": ["timeChangeHandler"]
987
+ "locale": ["localeWatcher"],
988
+ "value": ["valueWatcher"],
989
+ "hour": ["hourChanged"]
864
990
  }; }
865
991
  };
866
992
  CalciteTimePicker.style = calciteTimePickerCss;