@esri/calcite-components 1.0.0-next.319 → 1.0.0-next.322

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 (84) hide show
  1. package/dist/calcite/calcite.esm.js +1 -1
  2. package/dist/calcite/p-04bce033.entry.js +5 -0
  3. package/dist/calcite/p-1480eb2d.entry.js +5 -0
  4. package/dist/calcite/p-414ce3c1.system.entry.js +5 -0
  5. package/dist/calcite/p-4d4ba7df.entry.js +5 -0
  6. package/dist/calcite/{p-8b2d4eac.system.entry.js → p-4e95e13d.system.entry.js} +1 -1
  7. package/dist/calcite/p-58208234.system.entry.js +5 -0
  8. package/dist/calcite/{p-9be50494.entry.js → p-77600274.entry.js} +1 -1
  9. package/dist/calcite/p-8e252799.system.js +1 -1
  10. package/dist/calcite/{p-f97e1a2d.entry.js → p-a57aa5d0.entry.js} +1 -1
  11. package/dist/calcite/{p-6c5b849f.system.entry.js → p-ac417011.system.entry.js} +1 -1
  12. package/dist/calcite/p-ad617a5a.entry.js +5 -0
  13. package/dist/calcite/p-ed82600e.system.entry.js +5 -0
  14. package/dist/calcite/p-fa9a1d8f.system.entry.js +5 -0
  15. package/dist/cjs/calcite-button.cjs.entry.js +2 -2
  16. package/dist/cjs/calcite-combobox_3.cjs.entry.js +4 -1
  17. package/dist/cjs/calcite-input-time-picker_2.cjs.entry.js +349 -223
  18. package/dist/cjs/calcite-label.cjs.entry.js +1 -1
  19. package/dist/cjs/calcite-option_3.cjs.entry.js +3 -1
  20. package/dist/cjs/{calcite-radio_2.cjs.entry.js → calcite-radio-button.cjs.entry.js} +2 -43
  21. package/dist/cjs/calcite.cjs.js +1 -1
  22. package/dist/cjs/loader.cjs.js +1 -1
  23. package/dist/collection/collection-manifest.json +5 -7
  24. package/dist/collection/components/calcite-button/calcite-button.js +3 -2
  25. package/dist/collection/components/calcite-combobox/calcite-combobox.js +4 -1
  26. package/dist/collection/components/calcite-input-time-picker/calcite-input-time-picker.js +81 -76
  27. package/dist/collection/components/calcite-label/calcite-label.css +0 -1
  28. package/dist/collection/components/calcite-option/calcite-option.js +3 -1
  29. package/dist/collection/components/calcite-radio-button/calcite-radio-button.css +69 -0
  30. package/dist/collection/components/calcite-radio-button/calcite-radio-button.js +1 -1
  31. package/dist/collection/components/calcite-time-picker/calcite-time-picker.css +56 -91
  32. package/dist/collection/components/calcite-time-picker/calcite-time-picker.js +254 -289
  33. package/dist/collection/components/calcite-time-picker/resources.js +15 -9
  34. package/dist/collection/utils/time.js +144 -36
  35. package/dist/components/calcite-button2.js +2 -2
  36. package/dist/components/calcite-combobox.js +4 -1
  37. package/dist/components/calcite-input-time-picker.js +51 -48
  38. package/dist/components/calcite-label2.js +1 -1
  39. package/dist/components/calcite-option.js +3 -1
  40. package/dist/components/calcite-radio-button.js +3 -9
  41. package/dist/components/calcite-time-picker2.js +320 -187
  42. package/dist/custom-elements/index.d.ts +0 -6
  43. package/dist/custom-elements/index.js +364 -277
  44. package/dist/esm/calcite-button.entry.js +2 -2
  45. package/dist/esm/calcite-combobox_3.entry.js +4 -1
  46. package/dist/esm/calcite-input-time-picker_2.entry.js +349 -223
  47. package/dist/esm/calcite-label.entry.js +1 -1
  48. package/dist/esm/calcite-option_3.entry.js +3 -1
  49. package/dist/esm/{calcite-radio_2.entry.js → calcite-radio-button.entry.js} +4 -44
  50. package/dist/esm/calcite.js +1 -1
  51. package/dist/esm/loader.js +1 -1
  52. package/dist/esm-es5/calcite-button.entry.js +1 -1
  53. package/dist/esm-es5/calcite-combobox_3.entry.js +1 -1
  54. package/dist/esm-es5/calcite-input-time-picker_2.entry.js +2 -2
  55. package/dist/esm-es5/calcite-label.entry.js +1 -1
  56. package/dist/esm-es5/calcite-option_3.entry.js +1 -1
  57. package/dist/esm-es5/calcite-radio-button.entry.js +5 -0
  58. package/dist/esm-es5/calcite.js +1 -1
  59. package/dist/esm-es5/loader.js +1 -1
  60. package/dist/extras/docs-json.json +24 -211
  61. package/dist/types/components/calcite-input-time-picker/calcite-input-time-picker.d.ts +12 -4
  62. package/dist/types/components/calcite-time-picker/calcite-time-picker.d.ts +35 -23
  63. package/dist/types/components/calcite-time-picker/resources.d.ts +14 -8
  64. package/dist/types/components.d.ts +16 -93
  65. package/dist/types/preact.d.ts +0 -2
  66. package/dist/types/utils/time.d.ts +18 -5
  67. package/hydrate/index.js +381 -296
  68. package/package.json +1 -1
  69. package/readme.md +2 -2
  70. package/dist/calcite/p-12a9599d.system.entry.js +0 -5
  71. package/dist/calcite/p-1e4955d7.entry.js +0 -5
  72. package/dist/calcite/p-2b137143.system.entry.js +0 -5
  73. package/dist/calcite/p-35c5e6bd.entry.js +0 -5
  74. package/dist/calcite/p-4af85388.system.entry.js +0 -5
  75. package/dist/calcite/p-9634f89d.entry.js +0 -5
  76. package/dist/calcite/p-a98e5444.system.entry.js +0 -5
  77. package/dist/calcite/p-fccc1605.entry.js +0 -5
  78. package/dist/collection/components/calcite-radio/calcite-radio.css +0 -162
  79. package/dist/collection/components/calcite-radio/calcite-radio.js +0 -169
  80. package/dist/components/calcite-radio.d.ts +0 -11
  81. package/dist/components/calcite-radio.js +0 -10
  82. package/dist/components/calcite-radio2.js +0 -71
  83. package/dist/esm-es5/calcite-radio_2.entry.js +0 -5
  84. package/dist/types/components/calcite-radio/calcite-radio.d.ts +0 -22
@@ -10,6 +10,72 @@ import { c as connectForm, d as disconnectForm, H as HiddenFormInputSlot } from
10
10
  import './dom-dc012a45.js';
11
11
 
12
12
  const maxTenthForMinuteAndSecond = 5;
13
+ function createLocaleDateTimeFormatter(locale, includeSeconds = true) {
14
+ try {
15
+ const options = {
16
+ hour: "2-digit",
17
+ minute: "2-digit",
18
+ timeZone: "UTC"
19
+ };
20
+ if (includeSeconds) {
21
+ options.second = "2-digit";
22
+ }
23
+ return new Intl.DateTimeFormat(locale, options);
24
+ }
25
+ catch (e) {
26
+ throw new Error(`Invalid locale supplied while attempting to create a DateTime formatter: ${locale}`);
27
+ }
28
+ }
29
+ function formatTimePart(number) {
30
+ const numberAsString = number.toString();
31
+ return number >= 0 && number <= 9 ? numberAsString.padStart(2, "0") : numberAsString;
32
+ }
33
+ function formatTimeString(value) {
34
+ if (!isValidTime(value)) {
35
+ return null;
36
+ }
37
+ const [hourString, minuteString, secondString] = value.split(":");
38
+ const hour = formatTimePart(parseInt(hourString));
39
+ const minute = formatTimePart(parseInt(minuteString));
40
+ if (secondString) {
41
+ const second = formatTimePart(parseInt(secondString));
42
+ return `${hour}:${minute}:${second}`;
43
+ }
44
+ return `${hour}:${minute}`;
45
+ }
46
+ function getLocaleHourCycle(locale) {
47
+ const formatter = createLocaleDateTimeFormatter(locale);
48
+ const parts = formatter.formatToParts(new Date(Date.UTC(0, 0, 0, 0, 0, 0)));
49
+ return getLocalizedTimePart("meridiem", parts) ? "12" : "24";
50
+ }
51
+ function getLocalizedTimePart(part, parts) {
52
+ var _a, _b, _c, _d;
53
+ if (!part || !parts) {
54
+ return null;
55
+ }
56
+ if (part === "hourSuffix") {
57
+ const hourIndex = parts.indexOf(parts.find(({ type }) => type === "hour"));
58
+ const minuteIndex = parts.indexOf(parts.find(({ type }) => type === "minute"));
59
+ const hourSuffix = parts[hourIndex + 1];
60
+ return hourSuffix && hourSuffix.type === "literal" && minuteIndex - hourIndex === 2
61
+ ? ((_a = hourSuffix.value) === null || _a === void 0 ? void 0 : _a.trim()) || null
62
+ : null;
63
+ }
64
+ if (part === "minuteSuffix") {
65
+ const minuteIndex = parts.indexOf(parts.find(({ type }) => type === "minute"));
66
+ const secondIndex = parts.indexOf(parts.find(({ type }) => type === "second"));
67
+ const minuteSuffix = parts[minuteIndex + 1];
68
+ return minuteSuffix && minuteSuffix.type === "literal" && secondIndex - minuteIndex === 2
69
+ ? ((_b = minuteSuffix.value) === null || _b === void 0 ? void 0 : _b.trim()) || null
70
+ : null;
71
+ }
72
+ if (part === "secondSuffix") {
73
+ const secondIndex = parts.indexOf(parts.find(({ type }) => type === "second"));
74
+ const secondSuffix = parts[secondIndex + 1];
75
+ return secondSuffix && secondSuffix.type === "literal" ? ((_c = secondSuffix.value) === null || _c === void 0 ? void 0 : _c.trim()) || null : null;
76
+ }
77
+ return ((_d = parts.find(({ type }) => (part == "meridiem" ? type === "dayPeriod" : type === part))) === null || _d === void 0 ? void 0 : _d.value) || null;
78
+ }
13
79
  function getMeridiem(hour) {
14
80
  if (!isValidNumber(hour)) {
15
81
  return null;
@@ -17,51 +83,93 @@ function getMeridiem(hour) {
17
83
  const hourAsNumber = parseInt(hour);
18
84
  return hourAsNumber >= 0 && hourAsNumber <= 11 ? "AM" : "PM";
19
85
  }
20
- function getMeridiemHour(hour) {
21
- if (!isValidNumber(hour)) {
22
- return null;
86
+ function isValidTime(value) {
87
+ if (!value || value.startsWith(":") || value.endsWith(":")) {
88
+ return false;
23
89
  }
24
- const hourAsNumber = parseInt(hour);
25
- if (hourAsNumber === 0) {
26
- return "12";
90
+ const splitValue = value.split(":");
91
+ const validLength = splitValue.length > 1 && splitValue.length < 4;
92
+ if (!validLength) {
93
+ return false;
94
+ }
95
+ const [hour, minute, second] = splitValue;
96
+ const hourAsNumber = parseInt(splitValue[0]);
97
+ const minuteAsNumber = parseInt(splitValue[1]);
98
+ const secondAsNumber = parseInt(splitValue[2]);
99
+ const hourValid = isValidNumber(hour) && hourAsNumber >= 0 && hourAsNumber < 24;
100
+ const minuteValid = isValidNumber(minute) && minuteAsNumber >= 0 && minuteAsNumber < 60;
101
+ const secondValid = isValidNumber(second) && secondAsNumber >= 0 && secondAsNumber < 60;
102
+ if ((hourValid && minuteValid && !second) || (hourValid && minuteValid && secondValid)) {
103
+ return true;
27
104
  }
28
- return hourAsNumber > 12 ? formatTimePart(hourAsNumber - 12) : hour;
29
105
  }
30
- function parseTimeString(value) {
31
- const timeString = formatTimeString(value);
32
- const [hour, minute, second] = timeString ? timeString.split(":") : [null, null, null];
33
- return {
34
- hour,
35
- minute,
36
- second: second || (hour && minute ? "00" : null)
37
- };
106
+ function isValidTimePart(value, part) {
107
+ if (part === "meridiem") {
108
+ return value === "AM" || value === "PM";
109
+ }
110
+ if (!isValidNumber(value)) {
111
+ return false;
112
+ }
113
+ const valueAsNumber = Number(value);
114
+ return part === "hour" ? valueAsNumber >= 0 && valueAsNumber < 24 : valueAsNumber >= 0 && valueAsNumber < 60;
38
115
  }
39
- function formatTimeString(value) {
40
- if (!value || value.endsWith(":") || value.startsWith(":")) {
116
+ function localizeTimePart(value, part, locale) {
117
+ if (!isValidTimePart(value, part)) {
118
+ return;
119
+ }
120
+ const valueAsNumber = parseInt(value);
121
+ 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));
122
+ if (!date) {
123
+ return;
124
+ }
125
+ const formatter = createLocaleDateTimeFormatter(locale);
126
+ const parts = formatter.formatToParts(date);
127
+ return getLocalizedTimePart(part, parts);
128
+ }
129
+ function localizeTimeString(value, locale = "en", includeSeconds = true) {
130
+ if (!isValidTime(value)) {
41
131
  return null;
42
132
  }
43
- const splitValue = value.split(":");
44
- if (splitValue.length > 1) {
45
- const [hour, minute, second] = splitValue;
46
- const hourAsNumber = parseInt(splitValue[0]);
47
- const minuteAsNumber = parseInt(splitValue[1]);
48
- const secondAsNumber = parseInt(splitValue[2]);
49
- const hourValid = isValidNumber(hour) && hourAsNumber >= 0 && hourAsNumber < 24;
50
- const minuteValid = isValidNumber(minute) && minuteAsNumber >= 0 && minuteAsNumber < 60;
51
- const secondValid = isValidNumber(second) && secondAsNumber >= 0 && secondAsNumber < 60;
52
- if ((hourValid && minuteValid && !second) || (hourValid && minuteValid && secondValid)) {
53
- let newValue = `${formatTimePart(hourAsNumber)}:${formatTimePart(minuteAsNumber)}`;
54
- if (secondValid) {
55
- newValue = `${newValue}:${formatTimePart(secondAsNumber)}`;
56
- }
57
- return newValue;
58
- }
133
+ const { hour, minute, second = "0" } = parseTimeString(value);
134
+ const dateFromTimeString = new Date(Date.UTC(0, 0, 0, parseInt(hour), parseInt(minute), parseInt(second)));
135
+ const formatter = createLocaleDateTimeFormatter(locale, includeSeconds);
136
+ return (formatter === null || formatter === void 0 ? void 0 : formatter.format(dateFromTimeString)) || null;
137
+ }
138
+ function localizeTimeStringToParts(value, locale = "en") {
139
+ if (!isValidTime(value)) {
140
+ return null;
141
+ }
142
+ const { hour, minute, second = "0" } = parseTimeString(value);
143
+ const dateFromTimeString = new Date(Date.UTC(0, 0, 0, parseInt(hour), parseInt(minute), parseInt(second)));
144
+ if (dateFromTimeString) {
145
+ const formatter = createLocaleDateTimeFormatter(locale);
146
+ const parts = formatter.formatToParts(dateFromTimeString);
147
+ return {
148
+ localizedHour: getLocalizedTimePart("hour", parts),
149
+ localizedHourSuffix: getLocalizedTimePart("hourSuffix", parts),
150
+ localizedMinute: getLocalizedTimePart("minute", parts),
151
+ localizedMinuteSuffix: getLocalizedTimePart("minuteSuffix", parts),
152
+ localizedSecond: getLocalizedTimePart("second", parts),
153
+ localizedSecondSuffix: getLocalizedTimePart("secondSuffix", parts),
154
+ localizedMeridiem: getLocalizedTimePart("meridiem", parts)
155
+ };
59
156
  }
60
157
  return null;
61
158
  }
62
- function formatTimePart(number) {
63
- const numberAsString = number.toString();
64
- return number >= 0 && number <= 9 ? numberAsString.padStart(2, "0") : numberAsString;
159
+ function parseTimeString(value) {
160
+ if (isValidTime(value)) {
161
+ const [hour, minute, second] = value.split(":");
162
+ return {
163
+ hour,
164
+ minute,
165
+ second
166
+ };
167
+ }
168
+ return {
169
+ hour: null,
170
+ minute: null,
171
+ second: null
172
+ };
65
173
  }
66
174
 
67
175
  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}";
@@ -79,8 +187,11 @@ let CalciteInputTimePicker = class {
79
187
  this.active = false;
80
188
  /** The disabled state of the time input */
81
189
  this.disabled = false;
82
- /** Format of the hour value (12-hour or 24-hour) (this will be replaced by locale eventually) */
83
- this.hourDisplayFormat = "12";
190
+ /**
191
+ * BCP 47 language tag for desired language and country format
192
+ * @internal
193
+ */
194
+ this.locale = document.documentElement.lang || navigator.language || "en";
84
195
  /**
85
196
  * When true, makes the component required for form-submission.
86
197
  *
@@ -104,56 +215,60 @@ let CalciteInputTimePicker = class {
104
215
  //--------------------------------------------------------------------------
105
216
  this.calciteInputBlurHandler = () => {
106
217
  this.active = false;
107
- const newValue = formatTimeString(this.calciteInputEl.value) || formatTimeString(this.value);
108
- if (newValue !== this.calciteInputEl.value) {
109
- this.setInputValue(newValue);
110
- }
218
+ const shouldIncludeSeconds = this.shouldIncludeSeconds();
219
+ const localizedInputValue = localizeTimeString(this.calciteInputEl.value, this.locale, shouldIncludeSeconds);
220
+ this.setInputValue(localizedInputValue || localizeTimeString(this.value, this.locale, shouldIncludeSeconds));
111
221
  };
112
222
  this.calciteInputFocusHandler = () => {
113
223
  this.active = true;
114
224
  };
115
225
  this.calciteInputInputHandler = (event) => {
116
- this.setValue({ value: event.detail.value });
226
+ const target = event.target;
227
+ this.setValue({ value: target.value });
228
+ };
229
+ this.timePickerChangeHandler = (event) => {
230
+ event.stopPropagation();
231
+ const target = event.target;
232
+ const value = target.value;
233
+ this.setValue({ value, origin: "time-picker" });
117
234
  };
118
235
  this.setCalciteInputEl = (el) => {
119
236
  this.calciteInputEl = el;
120
237
  };
238
+ this.setCalciteTimePickerEl = (el) => {
239
+ this.calciteTimePickerEl = el;
240
+ };
121
241
  this.setInputValue = (newInputValue) => {
122
242
  if (!this.calciteInputEl) {
123
243
  return;
124
244
  }
125
- if (this.hourDisplayFormat === "12") {
126
- const { hour, minute, second } = parseTimeString(newInputValue);
127
- this.calciteInputEl.value = newInputValue
128
- ? `${getMeridiemHour(hour)}:${minute}${this.step !== 60 ? ":" + second : ""} ${getMeridiem(hour)}`
129
- : null;
130
- }
131
- else {
132
- this.calciteInputEl.value = newInputValue;
133
- }
245
+ this.calciteInputEl.value = newInputValue;
134
246
  };
135
247
  this.setValue = ({ value, origin = "input" }) => {
136
248
  const previousValue = this.value;
137
- const validatedNewValue = formatTimeString(value);
249
+ const newValue = formatTimeString(value);
250
+ const newLocalizedValue = localizeTimeString(newValue, this.locale, this.shouldIncludeSeconds());
138
251
  this.internalValueChange = origin !== "external" && origin !== "loading";
139
252
  const shouldEmit = origin !== "loading" &&
140
253
  origin !== "external" &&
141
254
  ((value !== this.previousValidValue && !value) ||
142
- !!(!this.previousValidValue && validatedNewValue) ||
143
- (validatedNewValue !== this.previousValidValue && validatedNewValue));
255
+ !!(!this.previousValidValue && newValue) ||
256
+ (newValue !== this.previousValidValue && newValue));
144
257
  if (value) {
145
258
  if (shouldEmit) {
146
- this.previousValidValue = validatedNewValue;
259
+ this.previousValidValue = newValue;
147
260
  }
148
- if (validatedNewValue && validatedNewValue !== this.value) {
149
- this.value = validatedNewValue;
261
+ if (newValue && newValue !== this.value) {
262
+ this.value = newValue;
150
263
  }
264
+ this.localizedValue = newLocalizedValue;
151
265
  }
152
266
  else {
153
267
  this.value = value;
268
+ this.localizedValue = null;
154
269
  }
155
270
  if (origin === "time-picker" || origin === "external") {
156
- this.setInputValue(validatedNewValue);
271
+ this.setInputValue(newLocalizedValue);
157
272
  }
158
273
  if (shouldEmit) {
159
274
  const changeEvent = this.calciteInputTimePickerChange.emit();
@@ -164,17 +279,26 @@ let CalciteInputTimePicker = class {
164
279
  this.previousValidValue = previousValue;
165
280
  }
166
281
  else {
167
- this.previousValidValue = validatedNewValue;
282
+ this.previousValidValue = newValue;
168
283
  }
169
284
  }
170
285
  };
171
286
  }
287
+ localeWatcher(newLocale) {
288
+ this.setInputValue(localizeTimeString(this.value, newLocale, this.shouldIncludeSeconds()));
289
+ }
172
290
  valueWatcher(newValue) {
173
291
  if (!this.internalValueChange) {
174
292
  this.setValue({ value: newValue, origin: "external" });
175
293
  }
176
294
  this.internalValueChange = false;
177
295
  }
296
+ clickHandler(event) {
297
+ if (event.composedPath().includes(this.calciteTimePickerEl)) {
298
+ return;
299
+ }
300
+ this.setFocus();
301
+ }
178
302
  keyUpHandler(event) {
179
303
  if (event.key === "Escape" && this.active) {
180
304
  this.active = false;
@@ -185,21 +309,6 @@ let CalciteInputTimePicker = class {
185
309
  event.stopPropagation();
186
310
  this.active = false;
187
311
  }
188
- timePickerChangeHandler(event) {
189
- event.preventDefault();
190
- event.stopPropagation();
191
- if (event.detail) {
192
- const { hour, minute, second } = event.detail;
193
- let value;
194
- if (hour && minute) {
195
- value = second && this.step !== 60 ? `${hour}:${minute}:${second}` : `${hour}:${minute}`;
196
- }
197
- else {
198
- value = "";
199
- }
200
- this.setValue({ value, origin: "time-picker" });
201
- }
202
- }
203
312
  timePickerFocusHandler(event) {
204
313
  event.preventDefault();
205
314
  event.stopPropagation();
@@ -222,6 +331,9 @@ let CalciteInputTimePicker = class {
222
331
  onLabelClick() {
223
332
  this.setFocus();
224
333
  }
334
+ shouldIncludeSeconds() {
335
+ return this.step < 60;
336
+ }
225
337
  //--------------------------------------------------------------------------
226
338
  //
227
339
  // Lifecycle
@@ -229,15 +341,13 @@ let CalciteInputTimePicker = class {
229
341
  //--------------------------------------------------------------------------
230
342
  connectedCallback() {
231
343
  if (this.value) {
232
- this.setValue({ value: this.value, origin: "loading" });
344
+ this.setValue({ value: isValidTime(this.value) ? this.value : undefined, origin: "loading" });
233
345
  }
234
346
  connectLabel(this);
235
347
  connectForm(this);
236
348
  }
237
349
  componentDidLoad() {
238
- if (this.calciteInputEl.value !== this.value) {
239
- this.setInputValue(this.value);
240
- }
350
+ this.setInputValue(this.localizedValue);
241
351
  }
242
352
  disconnectedCallback() {
243
353
  disconnectLabel(this);
@@ -249,38 +359,44 @@ let CalciteInputTimePicker = class {
249
359
  //
250
360
  // --------------------------------------------------------------------------
251
361
  render() {
252
- const { hour, minute, second } = parseTimeString(this.value);
253
362
  const popoverId = `${this.referenceElementId}-popover`;
254
- return (h(Host, null, h("div", { "aria-controls": popoverId, "aria-haspopup": "dialog", "aria-label": this.name, "aria-owns": popoverId, id: this.referenceElementId, role: "combobox" }, h("calcite-input", { disabled: this.disabled, icon: "clock", label: getLabelText(this), onCalciteInputBlur: this.calciteInputBlurHandler, onCalciteInputFocus: this.calciteInputFocusHandler, onCalciteInputInput: this.calciteInputInputHandler, ref: this.setCalciteInputEl, scale: this.scale, step: this.step })), h("calcite-popover", { id: popoverId, label: "Time Picker", open: this.active || false, referenceElement: this.referenceElementId }, 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 })), h(HiddenFormInputSlot, { component: this })));
363
+ return (h(Host, null, h("div", { "aria-controls": popoverId, "aria-haspopup": "dialog", "aria-label": this.name, "aria-owns": popoverId, id: this.referenceElementId, role: "combobox" }, h("calcite-input", { disabled: this.disabled, icon: "clock", label: getLabelText(this), onCalciteInputBlur: this.calciteInputBlurHandler, onCalciteInputFocus: this.calciteInputFocusHandler, onCalciteInputInput: this.calciteInputInputHandler, ref: this.setCalciteInputEl, scale: this.scale, step: this.step })), h("calcite-popover", { id: popoverId, label: "Time Picker", open: this.active || false, referenceElement: this.referenceElementId }, 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 })), h(HiddenFormInputSlot, { component: this })));
255
364
  }
256
365
  get el() { return getElement(this); }
257
366
  static get watchers() { return {
367
+ "locale": ["localeWatcher"],
258
368
  "value": ["valueWatcher"]
259
369
  }; }
260
370
  };
261
371
  CalciteInputTimePicker.style = calciteInputTimePickerCss;
262
372
 
263
373
  const CSS = {
374
+ button: "button",
264
375
  buttonBottomLeft: "button--bottom-left",
265
376
  buttonBottomRight: "button--bottom-right",
266
- button: "button",
267
- delimiter: "delimiter",
268
- hour: "hour",
269
377
  buttonHourDown: "button--hour-down",
270
378
  buttonHourUp: "button--hour-up",
271
- input: "input",
272
- meridiem: "meridiem",
273
379
  buttonMeridiemDown: "button--meridiem-down",
274
380
  buttonMeridiemUp: "button--meridiem-up",
275
- minute: "minute",
276
381
  buttonMinuteDown: "button--minute-down",
277
382
  buttonMinuteUp: "button--minute-up",
278
- second: "second",
279
383
  buttonSecondDown: "button--second-down",
280
384
  buttonSecondUp: "button--second-up",
281
- timePicker: "time-picker",
282
385
  buttonTopLeft: "button--top-left",
283
- buttonTopRight: "button--top-right"
386
+ buttonTopRight: "button--top-right",
387
+ column: "column",
388
+ delimiter: "delimiter",
389
+ hour: "hour",
390
+ input: "input",
391
+ meridiem: "meridiem",
392
+ minute: "minute",
393
+ second: "second",
394
+ showMeridiem: "show-meridiem",
395
+ showSecond: "show-second",
396
+ "scale-s": "scale-s",
397
+ "scale-m": "scale-m",
398
+ "scale-l": "scale-l",
399
+ timePicker: "time-picker"
284
400
  };
285
401
  const TEXT = {
286
402
  hour: "Hour",
@@ -297,8 +413,11 @@ const TEXT = {
297
413
  secondUp: "Increase second"
298
414
  };
299
415
 
300
- 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}";
416
+ 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}";
301
417
 
418
+ function capitalize(str) {
419
+ return str.charAt(0).toUpperCase() + str.slice(1);
420
+ }
302
421
  let CalciteTimePicker = class {
303
422
  constructor(hostRef) {
304
423
  registerInstance(this, hostRef);
@@ -310,10 +429,6 @@ let CalciteTimePicker = class {
310
429
  // Properties
311
430
  //
312
431
  //--------------------------------------------------------------------------
313
- /** The hour value (24-hour format) */
314
- this.hour = null;
315
- /** Format of the hour value (12-hour or 24-hour) (this will be replaced by locale eventually) */
316
- this.hourDisplayFormat = "12";
317
432
  /** aria-label for the hour input
318
433
  * @default "Hour"
319
434
  */
@@ -362,35 +477,25 @@ let CalciteTimePicker = class {
362
477
  * @default "Increase second"
363
478
  */
364
479
  this.intlSecondUp = TEXT.secondUp;
365
- /** The minute value */
366
- this.minute = null;
367
- /** The second value */
368
- this.second = null;
480
+ /**
481
+ * BCP 47 language tag for desired language and country format
482
+ * @internal
483
+ */
484
+ this.locale = document.documentElement.lang || navigator.language || "en";
369
485
  /** The scale (size) of the time picker */
370
486
  this.scale = "m";
371
487
  /** number that specifies the granularity that the value must adhere to */
372
488
  this.step = 60;
373
- this.timeChanged = false;
374
- // --------------------------------------------------------------------------
375
- //
376
- // State
377
- //
378
- // --------------------------------------------------------------------------
379
- /** The am/pm value */
380
- this.meridiem = null;
381
- this.displayHour = this.getDisplayHour();
382
- // --------------------------------------------------------------------------
383
- //
384
- // Private Methods
385
- //
386
- // --------------------------------------------------------------------------
489
+ /** The selected time in UTC */
490
+ this.value = null;
491
+ this.showSecond = this.step < 60;
387
492
  this.decrementHour = () => {
388
493
  const newHour = !this.hour ? 0 : this.hour === "00" ? 23 : parseInt(this.hour) - 1;
389
- this.setTime("hour", newHour);
494
+ this.setValuePart("hour", newHour);
390
495
  };
391
496
  this.decrementMeridiem = () => {
392
497
  const newMeridiem = this.meridiem === "PM" ? "AM" : "PM";
393
- this.setTime("meridiem", newMeridiem);
498
+ this.setValuePart("meridiem", newMeridiem);
394
499
  };
395
500
  this.decrementMinuteOrSecond = (key) => {
396
501
  let newValue;
@@ -401,7 +506,7 @@ let CalciteTimePicker = class {
401
506
  else {
402
507
  newValue = 59;
403
508
  }
404
- this.setTime(key, newValue);
509
+ this.setValuePart(key, newValue);
405
510
  };
406
511
  this.decrementMinute = () => {
407
512
  this.decrementMinuteOrSecond("minute");
@@ -423,7 +528,7 @@ let CalciteTimePicker = class {
423
528
  const keyAsNumber = parseInt(key);
424
529
  let newHour;
425
530
  if (isValidNumber(this.hour)) {
426
- switch (this.hourDisplayFormat) {
531
+ switch (this.hourCycle) {
427
532
  case "12":
428
533
  newHour =
429
534
  this.hour === "01" && keyAsNumber >= 0 && keyAsNumber <= 2
@@ -446,13 +551,13 @@ let CalciteTimePicker = class {
446
551
  else {
447
552
  newHour = keyAsNumber;
448
553
  }
449
- this.setTime("hour", newHour);
554
+ this.setValuePart("hour", newHour);
450
555
  }
451
556
  else {
452
557
  switch (key) {
453
558
  case "Backspace":
454
559
  case "Delete":
455
- this.setTime("hour", null);
560
+ this.setValuePart("hour", null);
456
561
  break;
457
562
  case "ArrowDown":
458
563
  event.preventDefault();
@@ -476,7 +581,7 @@ let CalciteTimePicker = class {
476
581
  };
477
582
  this.incrementMeridiem = () => {
478
583
  const newMeridiem = this.meridiem === "AM" ? "PM" : "AM";
479
- this.setTime("meridiem", newMeridiem);
584
+ this.setValuePart("meridiem", newMeridiem);
480
585
  };
481
586
  this.incrementHour = () => {
482
587
  const newHour = isValidNumber(this.hour)
@@ -484,7 +589,7 @@ let CalciteTimePicker = class {
484
589
  ? 0
485
590
  : parseInt(this.hour) + 1
486
591
  : 1;
487
- this.setTime("hour", newHour);
592
+ this.setValuePart("hour", newHour);
488
593
  };
489
594
  this.incrementMinuteOrSecond = (key) => {
490
595
  const newValue = isValidNumber(this[key])
@@ -492,7 +597,7 @@ let CalciteTimePicker = class {
492
597
  ? 0
493
598
  : parseInt(this[key]) + 1
494
599
  : 0;
495
- this.setTime(key, newValue);
600
+ this.setValuePart(key, newValue);
496
601
  };
497
602
  this.incrementMinute = () => {
498
603
  this.incrementMinuteOrSecond("minute");
@@ -508,14 +613,14 @@ let CalciteTimePicker = class {
508
613
  this.meridiemKeyDownHandler = (event) => {
509
614
  switch (event.key) {
510
615
  case "a":
511
- this.setTime("meridiem", "AM");
616
+ this.setValuePart("meridiem", "AM");
512
617
  break;
513
618
  case "p":
514
- this.setTime("meridiem", "PM");
619
+ this.setValuePart("meridiem", "PM");
515
620
  break;
516
621
  case "Backspace":
517
622
  case "Delete":
518
- this.setTime("meridiem", null);
623
+ this.setValuePart("meridiem", null);
519
624
  break;
520
625
  case "ArrowUp":
521
626
  event.preventDefault();
@@ -556,13 +661,13 @@ let CalciteTimePicker = class {
556
661
  else {
557
662
  newMinute = keyAsNumber;
558
663
  }
559
- this.setTime("minute", newMinute);
664
+ this.setValuePart("minute", newMinute);
560
665
  }
561
666
  else {
562
667
  switch (key) {
563
668
  case "Backspace":
564
669
  case "Delete":
565
- this.setTime("minute", null);
670
+ this.setValuePart("minute", null);
566
671
  break;
567
672
  case "ArrowDown":
568
673
  event.preventDefault();
@@ -604,13 +709,13 @@ let CalciteTimePicker = class {
604
709
  else {
605
710
  newSecond = keyAsNumber;
606
711
  }
607
- this.setTime("second", newSecond);
712
+ this.setValuePart("second", newSecond);
608
713
  }
609
714
  else {
610
715
  switch (key) {
611
716
  case "Backspace":
612
717
  case "Delete":
613
- this.setTime("second", null);
718
+ this.setValuePart("second", null);
614
719
  break;
615
720
  case "ArrowDown":
616
721
  event.preventDefault();
@@ -632,59 +737,96 @@ let CalciteTimePicker = class {
632
737
  this.incrementSecond();
633
738
  }
634
739
  };
635
- this.setTime = (key, value, emit = true) => {
636
- switch (key) {
637
- default:
638
- return;
639
- case "hour":
640
- this.hour = typeof value === "number" ? formatTimePart(value) : value;
641
- break;
642
- case "minute":
643
- this.minute = typeof value === "number" ? formatTimePart(value) : value;
644
- break;
645
- case "second":
646
- this.second = typeof value === "number" ? formatTimePart(value) : value;
647
- break;
648
- case "meridiem":
649
- if (isValidNumber(this.hour)) {
650
- const hourAsNumber = parseInt(this.hour);
651
- switch (value) {
652
- case "AM":
653
- if (hourAsNumber >= 12) {
654
- this.hour = formatTimePart(hourAsNumber - 12);
655
- }
656
- break;
657
- case "PM":
658
- if (hourAsNumber < 12) {
659
- this.hour = formatTimePart(hourAsNumber + 12);
660
- }
661
- break;
662
- }
663
- this.meridiem = value;
664
- }
665
- else {
666
- this.meridiem = value;
740
+ this.setHourEl = (el) => (this.hourEl = el);
741
+ this.setMeridiemEl = (el) => (this.meridiemEl = el);
742
+ this.setMinuteEl = (el) => (this.minuteEl = el);
743
+ this.setSecondEl = (el) => (this.secondEl = el);
744
+ this.setValue = (value, emit = true) => {
745
+ if (isValidTime(value)) {
746
+ const { hour, minute, second } = parseTimeString(value);
747
+ const { localizedHour, localizedHourSuffix, localizedMinute, localizedMinuteSuffix, localizedSecond, localizedSecondSuffix, localizedMeridiem } = localizeTimeStringToParts(value, this.locale);
748
+ this.localizedHour = localizedHour;
749
+ this.localizedHourSuffix = localizedHourSuffix;
750
+ this.localizedMinute = localizedMinute;
751
+ this.localizedMinuteSuffix = localizedMinuteSuffix;
752
+ this.localizedSecond = localizedSecond;
753
+ this.localizedSecondSuffix = localizedSecondSuffix;
754
+ this.hour = hour;
755
+ this.minute = minute;
756
+ this.second = second;
757
+ if (localizedMeridiem) {
758
+ this.localizedMeridiem = localizedMeridiem;
759
+ this.meridiem = getMeridiem(this.hour);
760
+ }
761
+ }
762
+ else {
763
+ this.hour = null;
764
+ this.localizedHour = null;
765
+ this.localizedHourSuffix = null;
766
+ this.localizedMeridiem = null;
767
+ this.localizedMinute = null;
768
+ this.localizedMinuteSuffix = null;
769
+ this.localizedSecond = null;
770
+ this.localizedSecondSuffix = null;
771
+ this.meridiem = null;
772
+ this.minute = null;
773
+ this.second = null;
774
+ this.value = null;
775
+ }
776
+ if (emit) {
777
+ this.calciteTimePickerChange.emit();
778
+ }
779
+ };
780
+ this.setValuePart = (key, value, emit = true) => {
781
+ var _a;
782
+ if (key === "meridiem") {
783
+ this.meridiem = value;
784
+ if (isValidNumber(this.hour)) {
785
+ const hourAsNumber = parseInt(this.hour);
786
+ switch (value) {
787
+ case "AM":
788
+ if (hourAsNumber >= 12) {
789
+ this.hour = formatTimePart(hourAsNumber - 12);
790
+ }
791
+ break;
792
+ case "PM":
793
+ if (hourAsNumber < 12) {
794
+ this.hour = formatTimePart(hourAsNumber + 12);
795
+ }
796
+ break;
667
797
  }
668
- break;
798
+ this.localizedHour = localizeTimePart(this.hour, "hour", this.locale);
799
+ }
800
+ }
801
+ else {
802
+ this[key] = typeof value === "number" ? formatTimePart(value) : value;
803
+ this[`localized${capitalize(key)}`] = localizeTimePart(this[key], key, this.locale);
804
+ }
805
+ if (this.hour && this.minute) {
806
+ const showSeconds = this.second && this.showSecond;
807
+ this.value = `${this.hour}:${this.minute}:${showSeconds ? this.second : "00"}`;
669
808
  }
670
- this.timeChanged = true;
809
+ else {
810
+ this.value = null;
811
+ }
812
+ this.localizedMeridiem = this.value
813
+ ? ((_a = localizeTimeStringToParts(this.value, this.locale)) === null || _a === void 0 ? void 0 : _a.localizedMeridiem) || null
814
+ : localizeTimePart(this.meridiem, "meridiem", this.locale);
671
815
  if (emit) {
672
- this.calciteTimePickerChange.emit(this.getTime());
816
+ this.calciteTimePickerChange.emit();
673
817
  }
674
818
  };
675
819
  }
676
- hourChanged(newHour) {
677
- if (this.hourDisplayFormat === "12" && isValidNumber(newHour)) {
678
- this.meridiem = getMeridiem(newHour);
679
- }
820
+ localeWatcher(newLocale) {
821
+ this.hourCycle = getLocaleHourCycle(newLocale);
822
+ this.setValue(this.value, false);
680
823
  }
681
- timeChangeHandler() {
682
- const { hour, minute } = this.getTime();
683
- if (!hour && !minute) {
684
- this.setTime("meridiem", null, false);
685
- }
686
- if (this.timeChanged) {
687
- this.timeChanged = false;
824
+ valueWatcher(newValue) {
825
+ this.setValue(newValue, false);
826
+ }
827
+ hourChanged(newHour) {
828
+ if (this.meridiem && isValidNumber(newHour)) {
829
+ this.setValuePart("meridiem", getMeridiem(newHour));
688
830
  }
689
831
  }
690
832
  //--------------------------------------------------------------------------
@@ -715,7 +857,7 @@ let CalciteTimePicker = class {
715
857
  if (this.step !== 60) {
716
858
  this.setFocus("second");
717
859
  }
718
- else if (this.hourDisplayFormat === "12") {
860
+ else if (this.hourCycle === "12") {
719
861
  this.setFocus("meridiem");
720
862
  }
721
863
  break;
@@ -727,7 +869,7 @@ let CalciteTimePicker = class {
727
869
  this.setFocus("minute");
728
870
  break;
729
871
  case "ArrowRight":
730
- if (this.hourDisplayFormat === "12") {
872
+ if (this.hourCycle === "12") {
731
873
  this.setFocus("meridiem");
732
874
  }
733
875
  break;
@@ -757,6 +899,11 @@ let CalciteTimePicker = class {
757
899
  var _a;
758
900
  (_a = this[`${target || "hour"}El`]) === null || _a === void 0 ? void 0 : _a.focus();
759
901
  }
902
+ // --------------------------------------------------------------------------
903
+ //
904
+ // Private Methods
905
+ //
906
+ // --------------------------------------------------------------------------
760
907
  buttonActivated(event) {
761
908
  const key = event.key;
762
909
  if (key === " ") {
@@ -764,40 +911,14 @@ let CalciteTimePicker = class {
764
911
  }
765
912
  return isActivationKey(key);
766
913
  }
767
- getDisplayHour() {
768
- if (!this.hour) {
769
- return "--";
770
- }
771
- if (this.hourDisplayFormat === "12") {
772
- return getMeridiemHour(this.hour);
773
- }
774
- return this.hour;
775
- }
776
- getTime() {
777
- return {
778
- hour: this.hour,
779
- minute: this.minute,
780
- second: this.second
781
- };
782
- }
783
914
  // --------------------------------------------------------------------------
784
915
  //
785
916
  // Lifecycle
786
917
  //
787
918
  // --------------------------------------------------------------------------
788
919
  connectedCallback() {
789
- if (this.hourDisplayFormat === "12") {
790
- this.meridiem = getMeridiem(this.hour);
791
- }
792
- if (isValidNumber(this.hour)) {
793
- this.hour = formatTimePart(parseInt(this.hour));
794
- }
795
- if (isValidNumber(this.minute)) {
796
- this.minute = formatTimePart(parseInt(this.minute));
797
- }
798
- if (isValidNumber(this.second)) {
799
- this.second = formatTimePart(parseInt(this.second));
800
- }
920
+ this.setValue(this.value, false);
921
+ this.hourCycle = getLocaleHourCycle(this.locale);
801
922
  }
802
923
  // --------------------------------------------------------------------------
803
924
  //
@@ -805,58 +926,63 @@ let CalciteTimePicker = class {
805
926
  //
806
927
  // --------------------------------------------------------------------------
807
928
  render() {
808
- const iconScale = this.scale === "s" || this.scale === "m" ? "s" : "m";
809
- const includeSeconds = this.step !== 60;
810
929
  const hourIsNumber = isValidNumber(this.hour);
930
+ const iconScale = this.scale === "s" || this.scale === "m" ? "s" : "m";
811
931
  const minuteIsNumber = isValidNumber(this.minute);
812
932
  const secondIsNumber = isValidNumber(this.second);
813
- return (h(Host, null, h("div", { class: CSS.timePicker }, h("div", { role: "group" }, h("span", { "aria-label": this.intlHourUp, class: {
933
+ const showMeridiem = this.hourCycle === "12";
934
+ return (h("div", { class: {
935
+ [CSS.timePicker]: true,
936
+ [CSS.showMeridiem]: showMeridiem,
937
+ [CSS.showSecond]: this.showSecond,
938
+ [CSS[`scale-${this.scale}`]]: true
939
+ } }, h("div", { class: CSS.column, role: "group" }, h("span", { "aria-label": this.intlHourUp, class: {
814
940
  [CSS.button]: true,
815
941
  [CSS.buttonHourUp]: true,
816
942
  [CSS.buttonTopLeft]: true
817
- }, onClick: this.incrementHour, onKeyDown: this.hourUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-up", scale: iconScale })), h("span", { "aria-label": this.intlHour, "aria-valuemax": "23", "aria-valuemin": "1", "aria-valuenow": hourIsNumber && parseInt(this.hour), "aria-valuetext": this.hour, class: {
943
+ }, onClick: this.incrementHour, onKeyDown: this.hourUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-up", scale: iconScale })), h("span", { "aria-label": this.intlHour, "aria-valuemax": "23", "aria-valuemin": "1", "aria-valuenow": (hourIsNumber && parseInt(this.hour)) || "0", "aria-valuetext": this.hour, class: {
818
944
  [CSS.input]: true,
819
945
  [CSS.hour]: true
820
- }, onFocus: this.focusHandler, onKeyDown: this.hourKeyDownHandler, ref: (el) => (this.hourEl = el), role: "spinbutton", tabIndex: 0 }, this.getDisplayHour()), h("span", { "aria-label": this.intlHourDown, class: {
946
+ }, onFocus: this.focusHandler, onKeyDown: this.hourKeyDownHandler, ref: this.setHourEl, role: "spinbutton", tabIndex: 0 }, this.localizedHour || "--"), h("span", { "aria-label": this.intlHourDown, class: {
821
947
  [CSS.button]: true,
822
948
  [CSS.buttonHourDown]: true,
823
949
  [CSS.buttonBottomLeft]: true
824
- }, onClick: this.decrementHour, onKeyDown: this.hourDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-down", scale: iconScale }))), h("span", { class: CSS.delimiter }, ":"), h("div", { role: "group" }, h("span", { "aria-label": this.intlMinuteUp, class: {
950
+ }, onClick: this.decrementHour, onKeyDown: this.hourDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-down", scale: iconScale }))), h("span", { class: CSS.delimiter }, this.localizedHourSuffix), h("div", { class: CSS.column, role: "group" }, h("span", { "aria-label": this.intlMinuteUp, class: {
825
951
  [CSS.button]: true,
826
952
  [CSS.buttonMinuteUp]: true
827
- }, onClick: this.incrementMinute, onKeyDown: this.minuteUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-up", scale: iconScale })), h("span", { "aria-label": this.intlMinute, "aria-valuemax": "12", "aria-valuemin": "1", "aria-valuenow": minuteIsNumber && parseInt(this.minute), "aria-valuetext": this.minute, class: {
953
+ }, onClick: this.incrementMinute, onKeyDown: this.minuteUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-up", scale: iconScale })), h("span", { "aria-label": this.intlMinute, "aria-valuemax": "12", "aria-valuemin": "1", "aria-valuenow": (minuteIsNumber && parseInt(this.minute)) || "0", "aria-valuetext": this.minute, class: {
828
954
  [CSS.input]: true,
829
955
  [CSS.minute]: true
830
- }, onFocus: this.focusHandler, onKeyDown: this.minuteKeyDownHandler, ref: (el) => (this.minuteEl = el), role: "spinbutton", tabIndex: 0 }, this.minute ? this.minute : "--"), h("span", { "aria-label": this.intlMinuteDown, class: {
956
+ }, onFocus: this.focusHandler, onKeyDown: this.minuteKeyDownHandler, ref: this.setMinuteEl, role: "spinbutton", tabIndex: 0 }, this.localizedMinute || "--"), h("span", { "aria-label": this.intlMinuteDown, class: {
831
957
  [CSS.button]: true,
832
958
  [CSS.buttonMinuteDown]: true
833
- }, onClick: this.decrementMinute, onKeyDown: this.minuteDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-down", scale: iconScale }))), includeSeconds && h("span", { class: CSS.delimiter }, ":"), includeSeconds && (h("div", { role: "group" }, h("span", { "aria-label": this.intlSecondUp, class: {
959
+ }, onClick: this.decrementMinute, onKeyDown: this.minuteDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-down", scale: iconScale }))), this.showSecond && h("span", { class: CSS.delimiter }, this.localizedMinuteSuffix), this.showSecond && (h("div", { class: CSS.column, role: "group" }, h("span", { "aria-label": this.intlSecondUp, class: {
834
960
  [CSS.button]: true,
835
961
  [CSS.buttonSecondUp]: true
836
- }, onClick: this.incrementSecond, onKeyDown: this.secondUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-up", scale: iconScale })), h("span", { "aria-label": this.intlSecond, "aria-valuemax": "59", "aria-valuemin": "0", "aria-valuenow": secondIsNumber && parseInt(this.second), "aria-valuetext": this.second, class: {
962
+ }, onClick: this.incrementSecond, onKeyDown: this.secondUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-up", scale: iconScale })), h("span", { "aria-label": this.intlSecond, "aria-valuemax": "59", "aria-valuemin": "0", "aria-valuenow": (secondIsNumber && parseInt(this.second)) || "0", "aria-valuetext": this.second, class: {
837
963
  [CSS.input]: true,
838
964
  [CSS.second]: true
839
- }, onFocus: this.focusHandler, onKeyDown: this.secondKeyDownHandler, ref: (el) => (this.secondEl = el), role: "spinbutton", tabIndex: 0 }, this.second ? this.second : "--"), h("span", { "aria-label": this.intlSecondDown, class: {
965
+ }, onFocus: this.focusHandler, onKeyDown: this.secondKeyDownHandler, ref: this.setSecondEl, role: "spinbutton", tabIndex: 0 }, this.localizedSecond || "--"), h("span", { "aria-label": this.intlSecondDown, class: {
840
966
  [CSS.button]: true,
841
967
  [CSS.buttonSecondDown]: true
842
- }, onClick: this.decrementSecond, onKeyDown: this.secondDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-down", scale: iconScale })))), this.hourDisplayFormat === "12" && (h("div", { role: "group" }, h("span", { "aria-label": this.intlMeridiemUp, class: {
968
+ }, onClick: this.decrementSecond, onKeyDown: this.secondDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-down", scale: iconScale })))), this.localizedSecondSuffix && (h("span", { class: CSS.delimiter }, this.localizedSecondSuffix)), showMeridiem && (h("div", { class: CSS.column, role: "group" }, h("span", { "aria-label": this.intlMeridiemUp, class: {
843
969
  [CSS.button]: true,
844
970
  [CSS.buttonMeridiemUp]: true,
845
971
  [CSS.buttonTopRight]: true
846
- }, onClick: this.incrementMeridiem, onKeyDown: this.meridiemUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-up", scale: iconScale })), 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: {
972
+ }, onClick: this.incrementMeridiem, onKeyDown: this.meridiemUpButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-up", scale: iconScale })), h("span", { "aria-label": this.intlMeridiem, "aria-valuemax": "2", "aria-valuemin": "1", "aria-valuenow": (this.meridiem === "PM" && "2") || "1", "aria-valuetext": this.meridiem, class: {
847
973
  [CSS.input]: true,
848
974
  [CSS.meridiem]: true
849
- }, onFocus: this.focusHandler, onKeyDown: this.meridiemKeyDownHandler, ref: (el) => (this.meridiemEl = el), role: "spinbutton", tabIndex: 0 }, this.meridiem ? this.meridiem : "--"), h("span", { "aria-label": this.intlMeridiemDown, class: {
975
+ }, onFocus: this.focusHandler, onKeyDown: this.meridiemKeyDownHandler, ref: this.setMeridiemEl, role: "spinbutton", tabIndex: 0 }, this.localizedMeridiem || "--"), h("span", { "aria-label": this.intlMeridiemDown, class: {
850
976
  [CSS.button]: true,
851
977
  [CSS.buttonMeridiemDown]: true,
852
978
  [CSS.buttonBottomRight]: true
853
- }, onClick: this.decrementMeridiem, onKeyDown: this.meridiemDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-down", scale: iconScale })))))));
979
+ }, onClick: this.decrementMeridiem, onKeyDown: this.meridiemDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-down", scale: iconScale }))))));
854
980
  }
855
981
  get el() { return getElement(this); }
856
982
  static get watchers() { return {
857
- "hour": ["hourChanged", "timeChangeHandler"],
858
- "minute": ["timeChangeHandler"],
859
- "second": ["timeChangeHandler"]
983
+ "locale": ["localeWatcher"],
984
+ "value": ["valueWatcher"],
985
+ "hour": ["hourChanged"]
860
986
  }; }
861
987
  };
862
988
  CalciteTimePicker.style = calciteTimePickerCss;