calcite-input-time-picker_2.entry.js 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
  1. /*!
  2. * All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
  4. * v1.0.0-beta.82
  5. */
  6. import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-8ece2564.js';
  7. import { g as guid } from './guid-b4461004.js';
  8. import { i as isValidNumber, n as numberKeys, c as isActivationKey } from './number-237e74a9.js';
  9. import { c as connectLabel, d as disconnectLabel, g as getLabelText } from './label-50132b90.js';
  10. import { s as submitForm, c as connectForm, d as disconnectForm, H as HiddenFormInputSlot } from './form-bca481e1.js';
  11. import { u as updateHostInteraction } from './interactive-cb5bf285.js';
  12. import './dom-da697a3f.js';
  13. const maxTenthForMinuteAndSecond = 5;
  14. function createLocaleDateTimeFormatter(locale, includeSeconds = true) {
  15. try {
  16. const options = {
  17. hour: "2-digit",
  18. minute: "2-digit",
  19. timeZone: "UTC"
  20. };
  21. if (includeSeconds) {
  22. options.second = "2-digit";
  23. }
  24. return new Intl.DateTimeFormat(locale, options);
  25. }
  26. catch (e) {
  27. throw new Error(`Invalid locale supplied while attempting to create a DateTime formatter: ${locale}`);
  28. }
  29. }
  30. function formatTimePart(number) {
  31. const numberAsString = number.toString();
  32. return number >= 0 && number <= 9 ? numberAsString.padStart(2, "0") : numberAsString;
  33. }
  34. function formatTimeString(value) {
  35. if (!isValidTime(value)) {
  36. return null;
  37. }
  38. const [hourString, minuteString, secondString] = value.split(":");
  39. const hour = formatTimePart(parseInt(hourString));
  40. const minute = formatTimePart(parseInt(minuteString));
  41. if (secondString) {
  42. const second = formatTimePart(parseInt(secondString));
  43. return `${hour}:${minute}:${second}`;
  44. }
  45. return `${hour}:${minute}`;
  46. }
  47. function getLocaleHourCycle(locale) {
  48. const formatter = createLocaleDateTimeFormatter(locale);
  49. const parts = formatter.formatToParts(new Date(Date.UTC(0, 0, 0, 0, 0, 0)));
  50. return getLocalizedTimePart("meridiem", parts) ? "12" : "24";
  51. }
  52. function getLocalizedTimePart(part, parts) {
  53. var _a, _b, _c, _d;
  54. if (!part || !parts) {
  55. return null;
  56. }
  57. if (part === "hourSuffix") {
  58. const hourIndex = parts.indexOf(parts.find(({ type }) => type === "hour"));
  59. const minuteIndex = parts.indexOf(parts.find(({ type }) => type === "minute"));
  60. const hourSuffix = parts[hourIndex + 1];
  61. return hourSuffix && hourSuffix.type === "literal" && minuteIndex - hourIndex === 2
  62. ? ((_a = hourSuffix.value) === null || _a === void 0 ? void 0 : _a.trim()) || null
  63. : null;
  64. }
  65. if (part === "minuteSuffix") {
  66. const minuteIndex = parts.indexOf(parts.find(({ type }) => type === "minute"));
  67. const secondIndex = parts.indexOf(parts.find(({ type }) => type === "second"));
  68. const minuteSuffix = parts[minuteIndex + 1];
  69. return minuteSuffix && minuteSuffix.type === "literal" && secondIndex - minuteIndex === 2
  70. ? ((_b = minuteSuffix.value) === null || _b === void 0 ? void 0 : _b.trim()) || null
  71. : null;
  72. }
  73. if (part === "secondSuffix") {
  74. const secondIndex = parts.indexOf(parts.find(({ type }) => type === "second"));
  75. const secondSuffix = parts[secondIndex + 1];
  76. return secondSuffix && secondSuffix.type === "literal" ? ((_c = secondSuffix.value) === null || _c === void 0 ? void 0 : _c.trim()) || null : null;
  77. }
  78. return ((_d = parts.find(({ type }) => (part == "meridiem" ? type === "dayPeriod" : type === part))) === null || _d === void 0 ? void 0 : _d.value) || null;
  79. }
  80. function getMeridiem(hour) {
  81. if (!isValidNumber(hour)) {
  82. return null;
  83. }
  84. const hourAsNumber = parseInt(hour);
  85. return hourAsNumber >= 0 && hourAsNumber <= 11 ? "AM" : "PM";
  86. }
  87. function isValidTime(value) {
  88. if (!value || value.startsWith(":") || value.endsWith(":")) {
  89. return false;
  90. }
  91. const splitValue = value.split(":");
  92. const validLength = splitValue.length > 1 && splitValue.length < 4;
  93. if (!validLength) {
  94. return false;
  95. }
  96. const [hour, minute, second] = splitValue;
  97. const hourAsNumber = parseInt(splitValue[0]);
  98. const minuteAsNumber = parseInt(splitValue[1]);
  99. const secondAsNumber = parseInt(splitValue[2]);
  100. const hourValid = isValidNumber(hour) && hourAsNumber >= 0 && hourAsNumber < 24;
  101. const minuteValid = isValidNumber(minute) && minuteAsNumber >= 0 && minuteAsNumber < 60;
  102. const secondValid = isValidNumber(second) && secondAsNumber >= 0 && secondAsNumber < 60;
  103. if ((hourValid && minuteValid && !second) || (hourValid && minuteValid && secondValid)) {
  104. return true;
  105. }
  106. }
  107. function isValidTimePart(value, part) {
  108. if (part === "meridiem") {
  109. return value === "AM" || value === "PM";
  110. }
  111. if (!isValidNumber(value)) {
  112. return false;
  113. }
  114. const valueAsNumber = Number(value);
  115. return part === "hour" ? valueAsNumber >= 0 && valueAsNumber < 24 : valueAsNumber >= 0 && valueAsNumber < 60;
  116. }
  117. function localizeTimePart(value, part, locale) {
  118. if (!isValidTimePart(value, part)) {
  119. return;
  120. }
  121. const valueAsNumber = parseInt(value);
  122. 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));
  123. if (!date) {
  124. return;
  125. }
  126. const formatter = createLocaleDateTimeFormatter(locale);
  127. const parts = formatter.formatToParts(date);
  128. return getLocalizedTimePart(part, parts);
  129. }
  130. function localizeTimeString(value, locale = "en", includeSeconds = true) {
  131. if (!isValidTime(value)) {
  132. return null;
  133. }
  134. const { hour, minute, second = "0" } = parseTimeString(value);
  135. const dateFromTimeString = new Date(Date.UTC(0, 0, 0, parseInt(hour), parseInt(minute), parseInt(second)));
  136. const formatter = createLocaleDateTimeFormatter(locale, includeSeconds);
  137. return (formatter === null || formatter === void 0 ? void 0 : formatter.format(dateFromTimeString)) || null;
  138. }
  139. function localizeTimeStringToParts(value, locale = "en") {
  140. if (!isValidTime(value)) {
  141. return null;
  142. }
  143. const { hour, minute, second = "0" } = parseTimeString(value);
  144. const dateFromTimeString = new Date(Date.UTC(0, 0, 0, parseInt(hour), parseInt(minute), parseInt(second)));
  145. if (dateFromTimeString) {
  146. const formatter = createLocaleDateTimeFormatter(locale);
  147. const parts = formatter.formatToParts(dateFromTimeString);
  148. return {
  149. localizedHour: getLocalizedTimePart("hour", parts),
  150. localizedHourSuffix: getLocalizedTimePart("hourSuffix", parts),
  151. localizedMinute: getLocalizedTimePart("minute", parts),
  152. localizedMinuteSuffix: getLocalizedTimePart("minuteSuffix", parts),
  153. localizedSecond: getLocalizedTimePart("second", parts),
  154. localizedSecondSuffix: getLocalizedTimePart("secondSuffix", parts),
  155. localizedMeridiem: getLocalizedTimePart("meridiem", parts)
  156. };
  157. }
  158. return null;
  159. }
  160. function getTimeParts(value, locale = "en") {
  161. if (!isValidTime(value)) {
  162. return null;
  163. }
  164. const { hour, minute, second = "0" } = parseTimeString(value);
  165. const dateFromTimeString = new Date(Date.UTC(0, 0, 0, parseInt(hour), parseInt(minute), parseInt(second)));
  166. if (dateFromTimeString) {
  167. const formatter = createLocaleDateTimeFormatter(locale);
  168. const parts = formatter.formatToParts(dateFromTimeString);
  169. return parts;
  170. }
  171. return null;
  172. }
  173. function parseTimeString(value) {
  174. if (isValidTime(value)) {
  175. const [hour, minute, second] = value.split(":");
  176. return {
  177. hour,
  178. minute,
  179. second
  180. };
  181. }
  182. return {
  183. hour: null,
  184. minute: null,
  185. second: null
  186. };
  187. }
  188. const inputTimePickerCss = "@-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:calc(150ms * var(--calcite-internal-duration-factor));--calcite-internal-duration-factor:var(--calcite-duration-factor, 1);--calcite-internal-animation-timing-fast:calc(100ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-medium:calc(200ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-slow:calc(300ms * var(--calcite-internal-duration-factor))}.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:var(--calcite-animation-timing)}:host([hidden]){display:none}:host{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}:host([disabled]){pointer-events:none;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;opacity:var(--calcite-ui-opacity-disabled)}:host([disabled]) ::slotted([calcite-hydrated][disabled]),:host([disabled]) [calcite-hydrated][disabled]{opacity:1}::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}";
  189. const InputTimePicker = class {
  190. constructor(hostRef) {
  191. registerInstance(this, hostRef);
  192. this.calciteInputTimePickerChange = createEvent(this, "calciteInputTimePickerChange", 7);
  193. //--------------------------------------------------------------------------
  194. //
  195. // Properties
  196. //
  197. //--------------------------------------------------------------------------
  198. /** The active state of the time input */
  199. this.active = false;
  200. /** The disabled state of the time input */
  201. this.disabled = false;
  202. /**
  203. * BCP 47 language tag for desired language and country format
  204. * @internal
  205. */
  206. this.locale = document.documentElement.lang || navigator.language || "en";
  207. /**
  208. * When true, makes the component required for form-submission.
  209. *
  210. * @internal
  211. */
  212. this.required = false;
  213. /** The scale (size) of the time input */
  214. this.scale = "m";
  215. /**
  216. * Determines where the popover will be positioned relative to the input.
  217. * @see [PopperPlacement](https://github.com/Esri/calcite-components/blob/master/src/utils/popper.ts#L25)
  218. */
  219. this.placement = "auto";
  220. /** number (seconds) that specifies the granularity that the value must adhere to */
  221. this.step = 60;
  222. /** The selected time in UTC (always 24-hour format) */
  223. this.value = null;
  224. /** whether the value of the input was changed as a result of user typing or not */
  225. this.internalValueChange = false;
  226. this.previousValidValue = null;
  227. this.referenceElementId = `input-time-picker-${guid()}`;
  228. //--------------------------------------------------------------------------
  229. //
  230. // Event Listeners
  231. //
  232. //--------------------------------------------------------------------------
  233. this.calciteInputBlurHandler = () => {
  234. this.active = false;
  235. const shouldIncludeSeconds = this.shouldIncludeSeconds();
  236. const localizedInputValue = localizeTimeString(this.calciteInputEl.value, this.locale, shouldIncludeSeconds);
  237. this.setInputValue(localizedInputValue || localizeTimeString(this.value, this.locale, shouldIncludeSeconds));
  238. };
  239. this.calciteInputFocusHandler = () => {
  240. this.active = true;
  241. };
  242. this.calciteInputInputHandler = (event) => {
  243. const target = event.target;
  244. this.setValue({ value: target.value });
  245. };
  246. this.timePickerChangeHandler = (event) => {
  247. event.stopPropagation();
  248. const target = event.target;
  249. const value = target.value;
  250. this.setValue({ value, origin: "time-picker" });
  251. };
  252. // --------------------------------------------------------------------------
  253. //
  254. // Private Methods
  255. //
  256. // --------------------------------------------------------------------------
  257. this.keyDownHandler = (event) => {
  258. if (event.key === "Enter" && !event.defaultPrevented) {
  259. submitForm(this);
  260. }
  261. };
  262. this.setCalcitePopoverEl = (el) => {
  263. this.popoverEl = el;
  264. };
  265. this.setCalciteInputEl = (el) => {
  266. this.calciteInputEl = el;
  267. };
  268. this.setCalciteTimePickerEl = (el) => {
  269. this.calciteTimePickerEl = el;
  270. };
  271. this.setInputValue = (newInputValue) => {
  272. if (!this.calciteInputEl) {
  273. return;
  274. }
  275. this.calciteInputEl.value = newInputValue;
  276. };
  277. this.setValue = ({ value, origin = "input" }) => {
  278. const previousValue = this.value;
  279. const newValue = formatTimeString(value);
  280. const newLocalizedValue = localizeTimeString(newValue, this.locale, this.shouldIncludeSeconds());
  281. this.internalValueChange = origin !== "external" && origin !== "loading";
  282. const shouldEmit = origin !== "loading" &&
  283. origin !== "external" &&
  284. ((value !== this.previousValidValue && !value) ||
  285. !!(!this.previousValidValue && newValue) ||
  286. (newValue !== this.previousValidValue && newValue));
  287. if (value) {
  288. if (shouldEmit) {
  289. this.previousValidValue = newValue;
  290. }
  291. if (newValue && newValue !== this.value) {
  292. this.value = newValue;
  293. }
  294. this.localizedValue = newLocalizedValue;
  295. }
  296. else {
  297. this.value = value;
  298. this.localizedValue = null;
  299. }
  300. if (origin === "time-picker" || origin === "external") {
  301. this.setInputValue(newLocalizedValue);
  302. }
  303. if (shouldEmit) {
  304. const changeEvent = this.calciteInputTimePickerChange.emit();
  305. if (changeEvent.defaultPrevented) {
  306. this.internalValueChange = false;
  307. this.value = previousValue;
  308. this.setInputValue(previousValue);
  309. this.previousValidValue = previousValue;
  310. }
  311. else {
  312. this.previousValidValue = newValue;
  313. }
  314. }
  315. };
  316. }
  317. activeHandler() {
  318. if (this.disabled) {
  319. this.active = false;
  320. return;
  321. }
  322. this.reposition();
  323. }
  324. handleDisabledChange(value) {
  325. if (!value) {
  326. this.active = false;
  327. }
  328. }
  329. localeWatcher(newLocale) {
  330. this.setInputValue(localizeTimeString(this.value, newLocale, this.shouldIncludeSeconds()));
  331. }
  332. valueWatcher(newValue) {
  333. if (!this.internalValueChange) {
  334. this.setValue({ value: newValue, origin: "external" });
  335. }
  336. this.internalValueChange = false;
  337. }
  338. clickHandler(event) {
  339. if (event.composedPath().includes(this.calciteTimePickerEl)) {
  340. return;
  341. }
  342. this.setFocus();
  343. }
  344. keyUpHandler(event) {
  345. if (event.key === "Escape" && this.active) {
  346. this.active = false;
  347. }
  348. }
  349. timePickerBlurHandler(event) {
  350. event.preventDefault();
  351. event.stopPropagation();
  352. this.active = false;
  353. }
  354. timePickerFocusHandler(event) {
  355. event.preventDefault();
  356. event.stopPropagation();
  357. this.active = true;
  358. }
  359. // --------------------------------------------------------------------------
  360. //
  361. // Public Methods
  362. //
  363. // --------------------------------------------------------------------------
  364. /** Sets focus on the component. */
  365. async setFocus() {
  366. this.calciteInputEl.setFocus();
  367. }
  368. /** Updates the position of the component. */
  369. async reposition() {
  370. var _a;
  371. (_a = this.popoverEl) === null || _a === void 0 ? void 0 : _a.reposition();
  372. }
  373. onLabelClick() {
  374. this.setFocus();
  375. }
  376. shouldIncludeSeconds() {
  377. return this.step < 60;
  378. }
  379. //--------------------------------------------------------------------------
  380. //
  381. // Lifecycle
  382. //
  383. //--------------------------------------------------------------------------
  384. connectedCallback() {
  385. if (this.value) {
  386. this.setValue({ value: isValidTime(this.value) ? this.value : undefined, origin: "loading" });
  387. }
  388. connectLabel(this);
  389. connectForm(this);
  390. }
  391. componentDidLoad() {
  392. this.setInputValue(this.localizedValue);
  393. }
  394. disconnectedCallback() {
  395. disconnectLabel(this);
  396. disconnectForm(this);
  397. }
  398. componentDidRender() {
  399. updateHostInteraction(this);
  400. }
  401. // --------------------------------------------------------------------------
  402. //
  403. // Render Methods
  404. //
  405. // --------------------------------------------------------------------------
  406. render() {
  407. const popoverId = `${this.referenceElementId}-popover`;
  408. return (h(Host, { onKeyDown: this.keyDownHandler }, 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, placement: this.placement, ref: this.setCalcitePopoverEl, 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 })));
  409. }
  410. get el() { return getElement(this); }
  411. static get watchers() { return {
  412. "active": ["activeHandler"],
  413. "disabled": ["handleDisabledChange"],
  414. "locale": ["localeWatcher"],
  415. "value": ["valueWatcher"]
  416. }; }
  417. };
  418. InputTimePicker.style = inputTimePickerCss;
  419. const CSS = {
  420. button: "button",
  421. buttonBottomLeft: "button--bottom-left",
  422. buttonBottomRight: "button--bottom-right",
  423. buttonHourDown: "button--hour-down",
  424. buttonHourUp: "button--hour-up",
  425. buttonMeridiemDown: "button--meridiem-down",
  426. buttonMeridiemUp: "button--meridiem-up",
  427. buttonMinuteDown: "button--minute-down",
  428. buttonMinuteUp: "button--minute-up",
  429. buttonSecondDown: "button--second-down",
  430. buttonSecondUp: "button--second-up",
  431. buttonTopLeft: "button--top-left",
  432. buttonTopRight: "button--top-right",
  433. column: "column",
  434. delimiter: "delimiter",
  435. hour: "hour",
  436. input: "input",
  437. meridiem: "meridiem",
  438. minute: "minute",
  439. second: "second",
  440. showMeridiem: "show-meridiem",
  441. showSecond: "show-second",
  442. "scale-s": "scale-s",
  443. "scale-m": "scale-m",
  444. "scale-l": "scale-l",
  445. timePicker: "time-picker",
  446. meridiemStart: "meridiem--start"
  447. };
  448. const TEXT = {
  449. hour: "Hour",
  450. hourDown: "Decrease hour",
  451. hourUp: "Increase hour",
  452. meridiem: "AM/PM",
  453. meridiemDown: "Decrease AM/PM",
  454. meridiemUp: "Increase AM/PM",
  455. minute: "Minute",
  456. minuteDown: "Decrease minute",
  457. minuteUp: "Increase minute",
  458. second: "Second",
  459. secondDown: "Decrease second",
  460. secondUp: "Increase second"
  461. };
  462. const timePickerCss = "@-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:calc(150ms * var(--calcite-internal-duration-factor));--calcite-internal-duration-factor:var(--calcite-duration-factor, 1);--calcite-internal-animation-timing-fast:calc(100ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-medium:calc(200ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-slow:calc(300ms * var(--calcite-internal-duration-factor))}.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:var(--calcite-animation-timing)}:host([hidden]){display:none}:host{display:inline-block}.time-picker{display:-ms-flexbox;display:flex;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-flex-align:center;align-items:center;background-color:var(--calcite-ui-foreground-1);font-weight:var(--calcite-font-weight-medium);color:var(--calcite-ui-text-1);--tw-shadow:0 6px 20px -4px rgba(0, 0, 0, 0.1), 0 4px 12px -2px rgba(0, 0, 0, 0.08);--tw-shadow-colored:0 6px 20px -4px var(--tw-shadow-color), 0 4px 12px -2px var(--tw-shadow-color);-webkit-box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);border-radius:var(--calcite-border-radius)}.time-picker .column{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.time-picker .meridiem--start{-ms-flex-order:-1;order:-1}.time-picker .button{display:-ms-inline-flexbox;display:inline-flex;cursor:pointer;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;background-color:var(--calcite-ui-foreground-1)}.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{display:-ms-inline-flexbox;display:inline-flex;cursor:pointer;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;background-color:var(--calcite-ui-foreground-1);font-weight:var(--calcite-font-weight-medium)}.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}";
  463. function capitalize(str) {
  464. return str.charAt(0).toUpperCase() + str.slice(1);
  465. }
  466. const TimePicker = class {
  467. constructor(hostRef) {
  468. registerInstance(this, hostRef);
  469. this.calciteTimePickerBlur = createEvent(this, "calciteTimePickerBlur", 7);
  470. this.calciteTimePickerChange = createEvent(this, "calciteTimePickerChange", 7);
  471. this.calciteTimePickerFocus = createEvent(this, "calciteTimePickerFocus", 7);
  472. //--------------------------------------------------------------------------
  473. //
  474. // Properties
  475. //
  476. //--------------------------------------------------------------------------
  477. /** aria-label for the hour input
  478. * @default "Hour"
  479. */
  480. this.intlHour = TEXT.hour;
  481. /** aria-label for the hour down button
  482. * @default "Decrease hour"
  483. */
  484. this.intlHourDown = TEXT.hourDown;
  485. /** aria-label for the hour up button
  486. * @default "Increase hour"
  487. */
  488. this.intlHourUp = TEXT.hourUp;
  489. /** aria-label for the meridiem (am/pm) input
  490. * @default "AM/PM"
  491. */
  492. this.intlMeridiem = TEXT.meridiem;
  493. /** aria-label for the meridiem (am/pm) down button
  494. * @default "Decrease AM/PM"
  495. */
  496. this.intlMeridiemDown = TEXT.meridiemDown;
  497. /** aria-label for the meridiem (am/pm) up button
  498. * @default "Increase AM/PM"
  499. */
  500. this.intlMeridiemUp = TEXT.meridiemUp;
  501. /** aria-label for the minute input
  502. * @default "Minute"
  503. */
  504. this.intlMinute = TEXT.minute;
  505. /** aria-label for the minute down button
  506. * @default "Decrease minute"
  507. */
  508. this.intlMinuteDown = TEXT.minuteDown;
  509. /** aria-label for the minute up button
  510. * @default "Increase minute"
  511. */
  512. this.intlMinuteUp = TEXT.minuteUp;
  513. /** aria-label for the second input
  514. * @default "Second"
  515. */
  516. this.intlSecond = TEXT.second;
  517. /** aria-label for the second down button
  518. * @default "Decrease second"
  519. */
  520. this.intlSecondDown = TEXT.secondDown;
  521. /** aria-label for the second up button
  522. * @default "Increase second"
  523. */
  524. this.intlSecondUp = TEXT.secondUp;
  525. /**
  526. * BCP 47 language tag for desired language and country format
  527. * @internal
  528. */
  529. this.locale = document.documentElement.lang || navigator.language || "en";
  530. /** The scale (size) of the time picker */
  531. this.scale = "m";
  532. /** number (seconds) that specifies the granularity that the value must adhere to */
  533. this.step = 60;
  534. /** The selected time in UTC (always 24-hour format) */
  535. this.value = null;
  536. this.showSecond = this.step < 60;
  537. this.decrementHour = () => {
  538. const newHour = !this.hour ? 0 : this.hour === "00" ? 23 : parseInt(this.hour) - 1;
  539. this.setValuePart("hour", newHour);
  540. };
  541. this.decrementMeridiem = () => {
  542. const newMeridiem = this.meridiem === "PM" ? "AM" : "PM";
  543. this.setValuePart("meridiem", newMeridiem);
  544. };
  545. this.decrementMinuteOrSecond = (key) => {
  546. let newValue;
  547. if (isValidNumber(this[key])) {
  548. const valueAsNumber = parseInt(this[key]);
  549. newValue = valueAsNumber === 0 ? 59 : valueAsNumber - 1;
  550. }
  551. else {
  552. newValue = 59;
  553. }
  554. this.setValuePart(key, newValue);
  555. };
  556. this.decrementMinute = () => {
  557. this.decrementMinuteOrSecond("minute");
  558. };
  559. this.decrementSecond = () => {
  560. this.decrementMinuteOrSecond("second");
  561. };
  562. this.focusHandler = (event) => {
  563. this.activeEl = event.currentTarget;
  564. };
  565. this.hourDownButtonKeyDownHandler = (event) => {
  566. if (this.buttonActivated(event)) {
  567. this.decrementHour();
  568. }
  569. };
  570. this.hourKeyDownHandler = (event) => {
  571. const key = event.key;
  572. if (numberKeys.includes(key)) {
  573. const keyAsNumber = parseInt(key);
  574. let newHour;
  575. if (isValidNumber(this.hour)) {
  576. switch (this.hourCycle) {
  577. case "12":
  578. newHour =
  579. this.hour === "01" && keyAsNumber >= 0 && keyAsNumber <= 2
  580. ? `1${keyAsNumber}`
  581. : keyAsNumber;
  582. break;
  583. case "24":
  584. if (this.hour === "01") {
  585. newHour = `1${keyAsNumber}`;
  586. }
  587. else if (this.hour === "02" && keyAsNumber >= 0 && keyAsNumber <= 3) {
  588. newHour = `2${keyAsNumber}`;
  589. }
  590. else {
  591. newHour = keyAsNumber;
  592. }
  593. break;
  594. }
  595. }
  596. else {
  597. newHour = keyAsNumber;
  598. }
  599. this.setValuePart("hour", newHour);
  600. }
  601. else {
  602. switch (key) {
  603. case "Backspace":
  604. case "Delete":
  605. this.setValuePart("hour", null);
  606. break;
  607. case "ArrowDown":
  608. event.preventDefault();
  609. this.decrementHour();
  610. break;
  611. case "ArrowUp":
  612. event.preventDefault();
  613. this.incrementHour();
  614. break;
  615. case " ":
  616. case "Spacebar":
  617. event.preventDefault();
  618. break;
  619. }
  620. }
  621. };
  622. this.hourUpButtonKeyDownHandler = (event) => {
  623. if (this.buttonActivated(event)) {
  624. this.incrementHour();
  625. }
  626. };
  627. this.incrementMeridiem = () => {
  628. const newMeridiem = this.meridiem === "AM" ? "PM" : "AM";
  629. this.setValuePart("meridiem", newMeridiem);
  630. };
  631. this.incrementHour = () => {
  632. const newHour = isValidNumber(this.hour)
  633. ? this.hour === "23"
  634. ? 0
  635. : parseInt(this.hour) + 1
  636. : 1;
  637. this.setValuePart("hour", newHour);
  638. };
  639. this.incrementMinuteOrSecond = (key) => {
  640. const newValue = isValidNumber(this[key])
  641. ? this[key] === "59"
  642. ? 0
  643. : parseInt(this[key]) + 1
  644. : 0;
  645. this.setValuePart(key, newValue);
  646. };
  647. this.incrementMinute = () => {
  648. this.incrementMinuteOrSecond("minute");
  649. };
  650. this.incrementSecond = () => {
  651. this.incrementMinuteOrSecond("second");
  652. };
  653. this.meridiemDownButtonKeyDownHandler = (event) => {
  654. if (this.buttonActivated(event)) {
  655. this.decrementMeridiem();
  656. }
  657. };
  658. this.meridiemKeyDownHandler = (event) => {
  659. switch (event.key) {
  660. case "a":
  661. this.setValuePart("meridiem", "AM");
  662. break;
  663. case "p":
  664. this.setValuePart("meridiem", "PM");
  665. break;
  666. case "Backspace":
  667. case "Delete":
  668. this.setValuePart("meridiem", null);
  669. break;
  670. case "ArrowUp":
  671. event.preventDefault();
  672. this.incrementMeridiem();
  673. break;
  674. case "ArrowDown":
  675. event.preventDefault();
  676. this.decrementMeridiem();
  677. break;
  678. case " ":
  679. case "Spacebar":
  680. event.preventDefault();
  681. break;
  682. }
  683. };
  684. this.meridiemUpButtonKeyDownHandler = (event) => {
  685. if (this.buttonActivated(event)) {
  686. this.incrementMeridiem();
  687. }
  688. };
  689. this.minuteDownButtonKeyDownHandler = (event) => {
  690. if (this.buttonActivated(event)) {
  691. this.decrementMinute();
  692. }
  693. };
  694. this.minuteKeyDownHandler = (event) => {
  695. const key = event.key;
  696. if (numberKeys.includes(key)) {
  697. const keyAsNumber = parseInt(key);
  698. let newMinute;
  699. if (isValidNumber(this.minute) && this.minute.startsWith("0")) {
  700. const minuteAsNumber = parseInt(this.minute);
  701. newMinute =
  702. minuteAsNumber > maxTenthForMinuteAndSecond
  703. ? keyAsNumber
  704. : `${minuteAsNumber}${keyAsNumber}`;
  705. }
  706. else {
  707. newMinute = keyAsNumber;
  708. }
  709. this.setValuePart("minute", newMinute);
  710. }
  711. else {
  712. switch (key) {
  713. case "Backspace":
  714. case "Delete":
  715. this.setValuePart("minute", null);
  716. break;
  717. case "ArrowDown":
  718. event.preventDefault();
  719. this.decrementMinute();
  720. break;
  721. case "ArrowUp":
  722. event.preventDefault();
  723. this.incrementMinute();
  724. break;
  725. case " ":
  726. case "Spacebar":
  727. event.preventDefault();
  728. break;
  729. }
  730. }
  731. };
  732. this.minuteUpButtonKeyDownHandler = (event) => {
  733. if (this.buttonActivated(event)) {
  734. this.incrementMinute();
  735. }
  736. };
  737. this.secondDownButtonKeyDownHandler = (event) => {
  738. if (this.buttonActivated(event)) {
  739. this.decrementSecond();
  740. }
  741. };
  742. this.secondKeyDownHandler = (event) => {
  743. const key = event.key;
  744. if (numberKeys.includes(key)) {
  745. const keyAsNumber = parseInt(key);
  746. let newSecond;
  747. if (isValidNumber(this.second) && this.second.startsWith("0")) {
  748. const secondAsNumber = parseInt(this.second);
  749. newSecond =
  750. secondAsNumber > maxTenthForMinuteAndSecond
  751. ? keyAsNumber
  752. : `${secondAsNumber}${keyAsNumber}`;
  753. }
  754. else {
  755. newSecond = keyAsNumber;
  756. }
  757. this.setValuePart("second", newSecond);
  758. }
  759. else {
  760. switch (key) {
  761. case "Backspace":
  762. case "Delete":
  763. this.setValuePart("second", null);
  764. break;
  765. case "ArrowDown":
  766. event.preventDefault();
  767. this.decrementSecond();
  768. break;
  769. case "ArrowUp":
  770. event.preventDefault();
  771. this.incrementSecond();
  772. break;
  773. case " ":
  774. case "Spacebar":
  775. event.preventDefault();
  776. break;
  777. }
  778. }
  779. };
  780. this.secondUpButtonKeyDownHandler = (event) => {
  781. if (this.buttonActivated(event)) {
  782. this.incrementSecond();
  783. }
  784. };
  785. this.setHourEl = (el) => (this.hourEl = el);
  786. this.setMeridiemEl = (el) => (this.meridiemEl = el);
  787. this.setMinuteEl = (el) => (this.minuteEl = el);
  788. this.setSecondEl = (el) => (this.secondEl = el);
  789. this.setValue = (value, emit = true) => {
  790. if (isValidTime(value)) {
  791. const { hour, minute, second } = parseTimeString(value);
  792. const { localizedHour, localizedHourSuffix, localizedMinute, localizedMinuteSuffix, localizedSecond, localizedSecondSuffix, localizedMeridiem } = localizeTimeStringToParts(value, this.locale);
  793. this.localizedHour = localizedHour;
  794. this.localizedHourSuffix = localizedHourSuffix;
  795. this.localizedMinute = localizedMinute;
  796. this.localizedMinuteSuffix = localizedMinuteSuffix;
  797. this.localizedSecond = localizedSecond;
  798. this.localizedSecondSuffix = localizedSecondSuffix;
  799. this.hour = hour;
  800. this.minute = minute;
  801. this.second = second;
  802. if (localizedMeridiem) {
  803. this.localizedMeridiem = localizedMeridiem;
  804. this.meridiem = getMeridiem(this.hour);
  805. const formatParts = getTimeParts(value, this.locale);
  806. this.meridiemOrder = this.getMeridiemOrder(formatParts);
  807. }
  808. }
  809. else {
  810. this.hour = null;
  811. this.localizedHour = null;
  812. this.localizedHourSuffix = null;
  813. this.localizedMeridiem = null;
  814. this.localizedMinute = null;
  815. this.localizedMinuteSuffix = null;
  816. this.localizedSecond = null;
  817. this.localizedSecondSuffix = null;
  818. this.meridiem = null;
  819. this.minute = null;
  820. this.second = null;
  821. this.value = null;
  822. }
  823. if (emit) {
  824. this.calciteTimePickerChange.emit();
  825. }
  826. };
  827. this.setValuePart = (key, value, emit = true) => {
  828. var _a;
  829. if (key === "meridiem") {
  830. this.meridiem = value;
  831. if (isValidNumber(this.hour)) {
  832. const hourAsNumber = parseInt(this.hour);
  833. switch (value) {
  834. case "AM":
  835. if (hourAsNumber >= 12) {
  836. this.hour = formatTimePart(hourAsNumber - 12);
  837. }
  838. break;
  839. case "PM":
  840. if (hourAsNumber < 12) {
  841. this.hour = formatTimePart(hourAsNumber + 12);
  842. }
  843. break;
  844. }
  845. this.localizedHour = localizeTimePart(this.hour, "hour", this.locale);
  846. }
  847. }
  848. else {
  849. this[key] = typeof value === "number" ? formatTimePart(value) : value;
  850. this[`localized${capitalize(key)}`] = localizeTimePart(this[key], key, this.locale);
  851. }
  852. if (this.hour && this.minute) {
  853. const showSeconds = this.second && this.showSecond;
  854. this.value = `${this.hour}:${this.minute}:${showSeconds ? this.second : "00"}`;
  855. }
  856. else {
  857. this.value = null;
  858. }
  859. this.localizedMeridiem = this.value
  860. ? ((_a = localizeTimeStringToParts(this.value, this.locale)) === null || _a === void 0 ? void 0 : _a.localizedMeridiem) || null
  861. : localizeTimePart(this.meridiem, "meridiem", this.locale);
  862. if (emit) {
  863. this.calciteTimePickerChange.emit();
  864. }
  865. };
  866. }
  867. localeWatcher(newLocale) {
  868. this.hourCycle = getLocaleHourCycle(newLocale);
  869. this.setValue(this.value, false);
  870. }
  871. valueWatcher(newValue) {
  872. this.setValue(newValue, false);
  873. }
  874. //--------------------------------------------------------------------------
  875. //
  876. // Event Listeners
  877. //
  878. //--------------------------------------------------------------------------
  879. hostBlurHandler() {
  880. this.calciteTimePickerBlur.emit();
  881. }
  882. hostFocusHandler() {
  883. this.calciteTimePickerFocus.emit();
  884. }
  885. keyDownHandler(event) {
  886. const key = event.key;
  887. switch (this.activeEl) {
  888. case this.hourEl:
  889. if (key === "ArrowRight") {
  890. this.setFocus("minute");
  891. }
  892. break;
  893. case this.minuteEl:
  894. switch (key) {
  895. case "ArrowLeft":
  896. this.setFocus("hour");
  897. break;
  898. case "ArrowRight":
  899. if (this.step !== 60) {
  900. this.setFocus("second");
  901. }
  902. else if (this.hourCycle === "12") {
  903. this.setFocus("meridiem");
  904. }
  905. break;
  906. }
  907. break;
  908. case this.secondEl:
  909. switch (key) {
  910. case "ArrowLeft":
  911. this.setFocus("minute");
  912. break;
  913. case "ArrowRight":
  914. if (this.hourCycle === "12") {
  915. this.setFocus("meridiem");
  916. }
  917. break;
  918. }
  919. break;
  920. case this.meridiemEl:
  921. switch (key) {
  922. case "ArrowLeft":
  923. if (this.step !== 60) {
  924. this.setFocus("second");
  925. }
  926. else {
  927. this.setFocus("minute");
  928. }
  929. break;
  930. }
  931. break;
  932. }
  933. }
  934. //--------------------------------------------------------------------------
  935. //
  936. // Public Methods
  937. //
  938. //--------------------------------------------------------------------------
  939. /** Sets focus on the component. */
  940. async setFocus(target) {
  941. var _a;
  942. (_a = this[`${target || "hour"}El`]) === null || _a === void 0 ? void 0 : _a.focus();
  943. }
  944. // --------------------------------------------------------------------------
  945. //
  946. // Private Methods
  947. //
  948. // --------------------------------------------------------------------------
  949. buttonActivated(event) {
  950. const key = event.key;
  951. if (key === " ") {
  952. event.preventDefault();
  953. }
  954. return isActivationKey(key);
  955. }
  956. getMeridiemOrder(formatParts) {
  957. const isRTLKind = this.locale === "ar" || this.locale === "he";
  958. if (formatParts && !isRTLKind) {
  959. const index = formatParts.findIndex((parts) => {
  960. return parts.value === this.localizedMeridiem;
  961. });
  962. return index;
  963. }
  964. return 0;
  965. }
  966. // --------------------------------------------------------------------------
  967. //
  968. // Lifecycle
  969. //
  970. // --------------------------------------------------------------------------
  971. connectedCallback() {
  972. this.setValue(this.value, false);
  973. this.hourCycle = getLocaleHourCycle(this.locale);
  974. }
  975. // --------------------------------------------------------------------------
  976. //
  977. // Render Methods
  978. //
  979. // --------------------------------------------------------------------------
  980. render() {
  981. const hourIsNumber = isValidNumber(this.hour);
  982. const iconScale = this.scale === "s" || this.scale === "m" ? "s" : "m";
  983. const minuteIsNumber = isValidNumber(this.minute);
  984. const secondIsNumber = isValidNumber(this.second);
  985. const showMeridiem = this.hourCycle === "12";
  986. return (h("div", { class: {
  987. [CSS.timePicker]: true,
  988. [CSS.showMeridiem]: showMeridiem,
  989. [CSS.showSecond]: this.showSecond,
  990. [CSS[`scale-${this.scale}`]]: true
  991. }, dir: "ltr" }, h("div", { class: CSS.column, role: "group" }, h("span", { "aria-label": this.intlHourUp, class: {
  992. [CSS.button]: true,
  993. [CSS.buttonHourUp]: true,
  994. [CSS.buttonTopLeft]: true
  995. }, 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: {
  996. [CSS.input]: true,
  997. [CSS.hour]: true
  998. }, onFocus: this.focusHandler, onKeyDown: this.hourKeyDownHandler, ref: this.setHourEl, role: "spinbutton", tabIndex: 0 }, this.localizedHour || "--"), h("span", { "aria-label": this.intlHourDown, class: {
  999. [CSS.button]: true,
  1000. [CSS.buttonHourDown]: true,
  1001. [CSS.buttonBottomLeft]: true
  1002. }, 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: {
  1003. [CSS.button]: true,
  1004. [CSS.buttonMinuteUp]: true
  1005. }, 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: {
  1006. [CSS.input]: true,
  1007. [CSS.minute]: true
  1008. }, onFocus: this.focusHandler, onKeyDown: this.minuteKeyDownHandler, ref: this.setMinuteEl, role: "spinbutton", tabIndex: 0 }, this.localizedMinute || "--"), h("span", { "aria-label": this.intlMinuteDown, class: {
  1009. [CSS.button]: true,
  1010. [CSS.buttonMinuteDown]: true
  1011. }, 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: {
  1012. [CSS.button]: true,
  1013. [CSS.buttonSecondUp]: true
  1014. }, 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: {
  1015. [CSS.input]: true,
  1016. [CSS.second]: true
  1017. }, onFocus: this.focusHandler, onKeyDown: this.secondKeyDownHandler, ref: this.setSecondEl, role: "spinbutton", tabIndex: 0 }, this.localizedSecond || "--"), h("span", { "aria-label": this.intlSecondDown, class: {
  1018. [CSS.button]: true,
  1019. [CSS.buttonSecondDown]: true
  1020. }, 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: {
  1021. [CSS.column]: true,
  1022. [CSS.meridiemStart]: this.meridiemOrder === 0
  1023. }, role: "group" }, h("span", { "aria-label": this.intlMeridiemUp, class: {
  1024. [CSS.button]: true,
  1025. [CSS.buttonMeridiemUp]: true,
  1026. [CSS.buttonTopRight]: true
  1027. }, 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: {
  1028. [CSS.input]: true,
  1029. [CSS.meridiem]: true
  1030. }, onFocus: this.focusHandler, onKeyDown: this.meridiemKeyDownHandler, ref: this.setMeridiemEl, role: "spinbutton", tabIndex: 0 }, this.localizedMeridiem || "--"), h("span", { "aria-label": this.intlMeridiemDown, class: {
  1031. [CSS.button]: true,
  1032. [CSS.buttonMeridiemDown]: true,
  1033. [CSS.buttonBottomRight]: true
  1034. }, onClick: this.decrementMeridiem, onKeyDown: this.meridiemDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-down", scale: iconScale }))))));
  1035. }
  1036. get el() { return getElement(this); }
  1037. static get watchers() { return {
  1038. "locale": ["localeWatcher"],
  1039. "value": ["valueWatcher"]
  1040. }; }
  1041. };
  1042. TimePicker.style = timePickerCss;
  1043. export { InputTimePicker as calcite_input_time_picker, TimePicker as calcite_time_picker };