time-picker.js 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161
  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.97
  5. */
  6. import { h } from "@stencil/core";
  7. import { isActivationKey, numberKeys } from "../../utils/key";
  8. import { isValidNumber } from "../../utils/number";
  9. import { formatTimePart, getLocaleHourCycle, getMeridiem, getTimeParts, isValidTime, localizeTimePart, localizeTimeStringToParts, maxTenthForMinuteAndSecond, parseTimeString } from "../../utils/time";
  10. import { CSS, TEXT } from "./resources";
  11. import { connectLocalized, disconnectLocalized, updateEffectiveLocale } from "../../utils/locale";
  12. function capitalize(str) {
  13. return str.charAt(0).toUpperCase() + str.slice(1);
  14. }
  15. export class TimePicker {
  16. constructor() {
  17. //--------------------------------------------------------------------------
  18. //
  19. // Properties
  20. //
  21. //--------------------------------------------------------------------------
  22. /**
  23. * Accessible name for the component's hour input.
  24. *
  25. * @default "Hour"
  26. */
  27. this.intlHour = TEXT.hour;
  28. /**
  29. * Accessible name for the component's hour down button.
  30. *
  31. * @default "Decrease hour"
  32. */
  33. this.intlHourDown = TEXT.hourDown;
  34. /**
  35. * Accessible name for the component's hour up button.
  36. *
  37. * @default "Increase hour"
  38. */
  39. this.intlHourUp = TEXT.hourUp;
  40. /**
  41. * Accessible name for the component's meridiem (AM/PM) input.
  42. *
  43. * @default "AM/PM"
  44. */
  45. this.intlMeridiem = TEXT.meridiem;
  46. /**
  47. * Accessible name for the component's meridiem (AM/PM) down button.
  48. *
  49. * @default "Decrease AM/PM"
  50. */
  51. this.intlMeridiemDown = TEXT.meridiemDown;
  52. /**
  53. * Accessible name for the component's meridiem (AM/PM) up button.
  54. *
  55. * @default "Increase AM/PM"
  56. */
  57. this.intlMeridiemUp = TEXT.meridiemUp;
  58. /**
  59. * Accessible name for the component's minute input.
  60. *
  61. * @default "Minute"
  62. */
  63. this.intlMinute = TEXT.minute;
  64. /**
  65. * Accessible name for the component's minute down button.
  66. *
  67. * @default "Decrease minute"
  68. */
  69. this.intlMinuteDown = TEXT.minuteDown;
  70. /**
  71. * Accessible name for the component's minute up button.
  72. *
  73. * @default "Increase minute"
  74. */
  75. this.intlMinuteUp = TEXT.minuteUp;
  76. /**
  77. * Accessible name for the component's second input.
  78. *
  79. * @default "Second"
  80. */
  81. this.intlSecond = TEXT.second;
  82. /**
  83. * Accessible name for the component's second down button.
  84. *
  85. * @default "Decrease second"
  86. */
  87. this.intlSecondDown = TEXT.secondDown;
  88. /**
  89. * Accessible name for the component's second up button.
  90. *
  91. * @default "Increase second"
  92. */
  93. this.intlSecondUp = TEXT.secondUp;
  94. /** Specifies the size of the component. */
  95. this.scale = "m";
  96. /** Specifies the granularity the `value` must adhere to (in seconds). */
  97. this.step = 60;
  98. /** The component's value in UTC (always 24-hour format). */
  99. this.value = null;
  100. // --------------------------------------------------------------------------
  101. //
  102. // State
  103. //
  104. // --------------------------------------------------------------------------
  105. this.effectiveLocale = "";
  106. this.showSecond = this.step < 60;
  107. this.decrementHour = () => {
  108. const newHour = !this.hour ? 0 : this.hour === "00" ? 23 : parseInt(this.hour) - 1;
  109. this.setValuePart("hour", newHour);
  110. };
  111. this.decrementMeridiem = () => {
  112. const newMeridiem = this.meridiem === "PM" ? "AM" : "PM";
  113. this.setValuePart("meridiem", newMeridiem);
  114. };
  115. this.decrementMinuteOrSecond = (key) => {
  116. let newValue;
  117. if (isValidNumber(this[key])) {
  118. const valueAsNumber = parseInt(this[key]);
  119. newValue = valueAsNumber === 0 ? 59 : valueAsNumber - 1;
  120. }
  121. else {
  122. newValue = 59;
  123. }
  124. this.setValuePart(key, newValue);
  125. };
  126. this.decrementMinute = () => {
  127. this.decrementMinuteOrSecond("minute");
  128. };
  129. this.decrementSecond = () => {
  130. this.decrementMinuteOrSecond("second");
  131. };
  132. this.focusHandler = (event) => {
  133. this.activeEl = event.currentTarget;
  134. };
  135. this.hourDownButtonKeyDownHandler = (event) => {
  136. if (this.buttonActivated(event)) {
  137. this.decrementHour();
  138. }
  139. };
  140. this.hourKeyDownHandler = (event) => {
  141. const { key } = event;
  142. if (numberKeys.includes(key)) {
  143. const keyAsNumber = parseInt(key);
  144. let newHour;
  145. if (isValidNumber(this.hour)) {
  146. switch (this.hourCycle) {
  147. case "12":
  148. newHour =
  149. this.hour === "01" && keyAsNumber >= 0 && keyAsNumber <= 2
  150. ? `1${keyAsNumber}`
  151. : keyAsNumber;
  152. break;
  153. case "24":
  154. if (this.hour === "01") {
  155. newHour = `1${keyAsNumber}`;
  156. }
  157. else if (this.hour === "02" && keyAsNumber >= 0 && keyAsNumber <= 3) {
  158. newHour = `2${keyAsNumber}`;
  159. }
  160. else {
  161. newHour = keyAsNumber;
  162. }
  163. break;
  164. }
  165. }
  166. else {
  167. newHour = keyAsNumber;
  168. }
  169. this.setValuePart("hour", newHour);
  170. }
  171. else {
  172. switch (key) {
  173. case "Backspace":
  174. case "Delete":
  175. this.setValuePart("hour", null);
  176. break;
  177. case "ArrowDown":
  178. event.preventDefault();
  179. this.decrementHour();
  180. break;
  181. case "ArrowUp":
  182. event.preventDefault();
  183. this.incrementHour();
  184. break;
  185. case " ":
  186. event.preventDefault();
  187. break;
  188. }
  189. }
  190. };
  191. this.hourUpButtonKeyDownHandler = (event) => {
  192. if (this.buttonActivated(event)) {
  193. this.incrementHour();
  194. }
  195. };
  196. this.incrementMeridiem = () => {
  197. const newMeridiem = this.meridiem === "AM" ? "PM" : "AM";
  198. this.setValuePart("meridiem", newMeridiem);
  199. };
  200. this.incrementHour = () => {
  201. const newHour = isValidNumber(this.hour)
  202. ? this.hour === "23"
  203. ? 0
  204. : parseInt(this.hour) + 1
  205. : 1;
  206. this.setValuePart("hour", newHour);
  207. };
  208. this.incrementMinuteOrSecond = (key) => {
  209. const newValue = isValidNumber(this[key])
  210. ? this[key] === "59"
  211. ? 0
  212. : parseInt(this[key]) + 1
  213. : 0;
  214. this.setValuePart(key, newValue);
  215. };
  216. this.incrementMinute = () => {
  217. this.incrementMinuteOrSecond("minute");
  218. };
  219. this.incrementSecond = () => {
  220. this.incrementMinuteOrSecond("second");
  221. };
  222. this.meridiemDownButtonKeyDownHandler = (event) => {
  223. if (this.buttonActivated(event)) {
  224. this.decrementMeridiem();
  225. }
  226. };
  227. this.meridiemKeyDownHandler = (event) => {
  228. switch (event.key) {
  229. case "a":
  230. this.setValuePart("meridiem", "AM");
  231. break;
  232. case "p":
  233. this.setValuePart("meridiem", "PM");
  234. break;
  235. case "Backspace":
  236. case "Delete":
  237. this.setValuePart("meridiem", null);
  238. break;
  239. case "ArrowUp":
  240. event.preventDefault();
  241. this.incrementMeridiem();
  242. break;
  243. case "ArrowDown":
  244. event.preventDefault();
  245. this.decrementMeridiem();
  246. break;
  247. case " ":
  248. event.preventDefault();
  249. break;
  250. }
  251. };
  252. this.meridiemUpButtonKeyDownHandler = (event) => {
  253. if (this.buttonActivated(event)) {
  254. this.incrementMeridiem();
  255. }
  256. };
  257. this.minuteDownButtonKeyDownHandler = (event) => {
  258. if (this.buttonActivated(event)) {
  259. this.decrementMinute();
  260. }
  261. };
  262. this.minuteKeyDownHandler = (event) => {
  263. const { key } = event;
  264. if (numberKeys.includes(key)) {
  265. const keyAsNumber = parseInt(key);
  266. let newMinute;
  267. if (isValidNumber(this.minute) && this.minute.startsWith("0")) {
  268. const minuteAsNumber = parseInt(this.minute);
  269. newMinute =
  270. minuteAsNumber > maxTenthForMinuteAndSecond
  271. ? keyAsNumber
  272. : `${minuteAsNumber}${keyAsNumber}`;
  273. }
  274. else {
  275. newMinute = keyAsNumber;
  276. }
  277. this.setValuePart("minute", newMinute);
  278. }
  279. else {
  280. switch (key) {
  281. case "Backspace":
  282. case "Delete":
  283. this.setValuePart("minute", null);
  284. break;
  285. case "ArrowDown":
  286. event.preventDefault();
  287. this.decrementMinute();
  288. break;
  289. case "ArrowUp":
  290. event.preventDefault();
  291. this.incrementMinute();
  292. break;
  293. case " ":
  294. event.preventDefault();
  295. break;
  296. }
  297. }
  298. };
  299. this.minuteUpButtonKeyDownHandler = (event) => {
  300. if (this.buttonActivated(event)) {
  301. this.incrementMinute();
  302. }
  303. };
  304. this.secondDownButtonKeyDownHandler = (event) => {
  305. if (this.buttonActivated(event)) {
  306. this.decrementSecond();
  307. }
  308. };
  309. this.secondKeyDownHandler = (event) => {
  310. const { key } = event;
  311. if (numberKeys.includes(key)) {
  312. const keyAsNumber = parseInt(key);
  313. let newSecond;
  314. if (isValidNumber(this.second) && this.second.startsWith("0")) {
  315. const secondAsNumber = parseInt(this.second);
  316. newSecond =
  317. secondAsNumber > maxTenthForMinuteAndSecond
  318. ? keyAsNumber
  319. : `${secondAsNumber}${keyAsNumber}`;
  320. }
  321. else {
  322. newSecond = keyAsNumber;
  323. }
  324. this.setValuePart("second", newSecond);
  325. }
  326. else {
  327. switch (key) {
  328. case "Backspace":
  329. case "Delete":
  330. this.setValuePart("second", null);
  331. break;
  332. case "ArrowDown":
  333. event.preventDefault();
  334. this.decrementSecond();
  335. break;
  336. case "ArrowUp":
  337. event.preventDefault();
  338. this.incrementSecond();
  339. break;
  340. case " ":
  341. event.preventDefault();
  342. break;
  343. }
  344. }
  345. };
  346. this.secondUpButtonKeyDownHandler = (event) => {
  347. if (this.buttonActivated(event)) {
  348. this.incrementSecond();
  349. }
  350. };
  351. this.setHourEl = (el) => (this.hourEl = el);
  352. this.setMeridiemEl = (el) => (this.meridiemEl = el);
  353. this.setMinuteEl = (el) => (this.minuteEl = el);
  354. this.setSecondEl = (el) => (this.secondEl = el);
  355. this.setValue = (value, emit = true) => {
  356. if (isValidTime(value)) {
  357. const { hour, minute, second } = parseTimeString(value);
  358. const { effectiveLocale: locale, numberingSystem } = this;
  359. const { localizedHour, localizedHourSuffix, localizedMinute, localizedMinuteSuffix, localizedSecond, localizedSecondSuffix, localizedMeridiem } = localizeTimeStringToParts({ value, locale, numberingSystem });
  360. this.localizedHour = localizedHour;
  361. this.localizedHourSuffix = localizedHourSuffix;
  362. this.localizedMinute = localizedMinute;
  363. this.localizedMinuteSuffix = localizedMinuteSuffix;
  364. this.localizedSecond = localizedSecond;
  365. this.localizedSecondSuffix = localizedSecondSuffix;
  366. this.hour = hour;
  367. this.minute = minute;
  368. this.second = second;
  369. if (localizedMeridiem) {
  370. this.localizedMeridiem = localizedMeridiem;
  371. this.meridiem = getMeridiem(this.hour);
  372. const formatParts = getTimeParts({ value, locale, numberingSystem });
  373. this.meridiemOrder = this.getMeridiemOrder(formatParts);
  374. }
  375. }
  376. else {
  377. this.hour = null;
  378. this.localizedHour = null;
  379. this.localizedHourSuffix = null;
  380. this.localizedMeridiem = null;
  381. this.localizedMinute = null;
  382. this.localizedMinuteSuffix = null;
  383. this.localizedSecond = null;
  384. this.localizedSecondSuffix = null;
  385. this.meridiem = null;
  386. this.minute = null;
  387. this.second = null;
  388. this.value = null;
  389. }
  390. if (emit) {
  391. this.calciteInternalTimePickerChange.emit();
  392. }
  393. };
  394. this.setValuePart = (key, value, emit = true) => {
  395. var _a;
  396. const { effectiveLocale: locale, numberingSystem } = this;
  397. if (key === "meridiem") {
  398. this.meridiem = value;
  399. if (isValidNumber(this.hour)) {
  400. const hourAsNumber = parseInt(this.hour);
  401. switch (value) {
  402. case "AM":
  403. if (hourAsNumber >= 12) {
  404. this.hour = formatTimePart(hourAsNumber - 12);
  405. }
  406. break;
  407. case "PM":
  408. if (hourAsNumber < 12) {
  409. this.hour = formatTimePart(hourAsNumber + 12);
  410. }
  411. break;
  412. }
  413. this.localizedHour = localizeTimePart({
  414. value: this.hour,
  415. part: "hour",
  416. locale,
  417. numberingSystem
  418. });
  419. }
  420. }
  421. else {
  422. this[key] = typeof value === "number" ? formatTimePart(value) : value;
  423. this[`localized${capitalize(key)}`] = localizeTimePart({
  424. value: this[key],
  425. part: key,
  426. locale,
  427. numberingSystem
  428. });
  429. }
  430. if (this.hour && this.minute) {
  431. const showSeconds = this.second && this.showSecond;
  432. this.value = `${this.hour}:${this.minute}:${showSeconds ? this.second : "00"}`;
  433. }
  434. else {
  435. this.value = null;
  436. }
  437. this.localizedMeridiem = this.value
  438. ? ((_a = localizeTimeStringToParts({ value: this.value, locale, numberingSystem })) === null || _a === void 0 ? void 0 : _a.localizedMeridiem) || null
  439. : localizeTimePart({ value: this.meridiem, part: "meridiem", locale, numberingSystem });
  440. if (emit) {
  441. this.calciteInternalTimePickerChange.emit();
  442. }
  443. };
  444. }
  445. localeChanged() {
  446. updateEffectiveLocale(this);
  447. }
  448. valueWatcher(newValue) {
  449. this.setValue(newValue, false);
  450. }
  451. effectiveLocaleWatcher() {
  452. this.updateLocale();
  453. }
  454. //--------------------------------------------------------------------------
  455. //
  456. // Event Listeners
  457. //
  458. //--------------------------------------------------------------------------
  459. hostBlurHandler() {
  460. this.calciteInternalTimePickerBlur.emit();
  461. }
  462. hostFocusHandler() {
  463. this.calciteInternalTimePickerFocus.emit();
  464. }
  465. keyDownHandler(event) {
  466. const { defaultPrevented, key } = event;
  467. if (defaultPrevented) {
  468. return;
  469. }
  470. switch (this.activeEl) {
  471. case this.hourEl:
  472. if (key === "ArrowRight") {
  473. this.setFocus("minute");
  474. event.preventDefault();
  475. }
  476. break;
  477. case this.minuteEl:
  478. switch (key) {
  479. case "ArrowLeft":
  480. this.setFocus("hour");
  481. event.preventDefault();
  482. break;
  483. case "ArrowRight":
  484. if (this.step !== 60) {
  485. this.setFocus("second");
  486. event.preventDefault();
  487. }
  488. else if (this.hourCycle === "12") {
  489. this.setFocus("meridiem");
  490. event.preventDefault();
  491. }
  492. break;
  493. }
  494. break;
  495. case this.secondEl:
  496. switch (key) {
  497. case "ArrowLeft":
  498. this.setFocus("minute");
  499. event.preventDefault();
  500. break;
  501. case "ArrowRight":
  502. if (this.hourCycle === "12") {
  503. this.setFocus("meridiem");
  504. event.preventDefault();
  505. }
  506. break;
  507. }
  508. break;
  509. case this.meridiemEl:
  510. switch (key) {
  511. case "ArrowLeft":
  512. if (this.step !== 60) {
  513. this.setFocus("second");
  514. event.preventDefault();
  515. }
  516. else {
  517. this.setFocus("minute");
  518. event.preventDefault();
  519. }
  520. break;
  521. }
  522. break;
  523. }
  524. }
  525. //--------------------------------------------------------------------------
  526. //
  527. // Public Methods
  528. //
  529. //--------------------------------------------------------------------------
  530. /**
  531. * Sets focus on the component.
  532. *
  533. * @param target
  534. */
  535. async setFocus(target) {
  536. var _a;
  537. (_a = this[`${target || "hour"}El`]) === null || _a === void 0 ? void 0 : _a.focus();
  538. }
  539. // --------------------------------------------------------------------------
  540. //
  541. // Private Methods
  542. //
  543. // --------------------------------------------------------------------------
  544. buttonActivated(event) {
  545. const { key } = event;
  546. if (key === " ") {
  547. event.preventDefault();
  548. }
  549. return isActivationKey(key);
  550. }
  551. getMeridiemOrder(formatParts) {
  552. const locale = this.effectiveLocale;
  553. const isRTLKind = locale === "ar" || locale === "he";
  554. if (formatParts && !isRTLKind) {
  555. const index = formatParts.findIndex((parts) => {
  556. return parts.value === this.localizedMeridiem;
  557. });
  558. return index;
  559. }
  560. return 0;
  561. }
  562. updateLocale() {
  563. this.hourCycle = getLocaleHourCycle(this.effectiveLocale, this.numberingSystem);
  564. this.setValue(this.value, false);
  565. }
  566. // --------------------------------------------------------------------------
  567. //
  568. // Lifecycle
  569. //
  570. // --------------------------------------------------------------------------
  571. connectedCallback() {
  572. connectLocalized(this);
  573. this.updateLocale();
  574. this.meridiemOrder = this.getMeridiemOrder(getTimeParts({
  575. value: "0:00:00",
  576. locale: this.effectiveLocale,
  577. numberingSystem: this.numberingSystem
  578. }));
  579. }
  580. disconnectedCallback() {
  581. disconnectLocalized(this);
  582. }
  583. // --------------------------------------------------------------------------
  584. //
  585. // Render Methods
  586. //
  587. // --------------------------------------------------------------------------
  588. render() {
  589. const hourIsNumber = isValidNumber(this.hour);
  590. const iconScale = this.scale === "s" || this.scale === "m" ? "s" : "m";
  591. const minuteIsNumber = isValidNumber(this.minute);
  592. const secondIsNumber = isValidNumber(this.second);
  593. const showMeridiem = this.hourCycle === "12";
  594. return (h("div", { class: {
  595. [CSS.timePicker]: true,
  596. [CSS.showMeridiem]: showMeridiem,
  597. [CSS.showSecond]: this.showSecond,
  598. [CSS[`scale-${this.scale}`]]: true
  599. }, dir: "ltr" }, h("div", { class: CSS.column, role: "group" }, h("span", { "aria-label": this.intlHourUp, class: {
  600. [CSS.button]: true,
  601. [CSS.buttonHourUp]: true,
  602. [CSS.buttonTopLeft]: true
  603. }, 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: {
  604. [CSS.input]: true,
  605. [CSS.hour]: true
  606. }, onFocus: this.focusHandler, onKeyDown: this.hourKeyDownHandler, ref: this.setHourEl, role: "spinbutton", tabIndex: 0 }, this.localizedHour || "--"), h("span", { "aria-label": this.intlHourDown, class: {
  607. [CSS.button]: true,
  608. [CSS.buttonHourDown]: true,
  609. [CSS.buttonBottomLeft]: true
  610. }, 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: {
  611. [CSS.button]: true,
  612. [CSS.buttonMinuteUp]: true
  613. }, 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: {
  614. [CSS.input]: true,
  615. [CSS.minute]: true
  616. }, onFocus: this.focusHandler, onKeyDown: this.minuteKeyDownHandler, ref: this.setMinuteEl, role: "spinbutton", tabIndex: 0 }, this.localizedMinute || "--"), h("span", { "aria-label": this.intlMinuteDown, class: {
  617. [CSS.button]: true,
  618. [CSS.buttonMinuteDown]: true
  619. }, 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: {
  620. [CSS.button]: true,
  621. [CSS.buttonSecondUp]: true
  622. }, 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: {
  623. [CSS.input]: true,
  624. [CSS.second]: true
  625. }, onFocus: this.focusHandler, onKeyDown: this.secondKeyDownHandler, ref: this.setSecondEl, role: "spinbutton", tabIndex: 0 }, this.localizedSecond || "--"), h("span", { "aria-label": this.intlSecondDown, class: {
  626. [CSS.button]: true,
  627. [CSS.buttonSecondDown]: true
  628. }, 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: {
  629. [CSS.column]: true,
  630. [CSS.meridiemStart]: this.meridiemOrder === 0
  631. }, role: "group" }, h("span", { "aria-label": this.intlMeridiemUp, class: {
  632. [CSS.button]: true,
  633. [CSS.buttonMeridiemUp]: true,
  634. [CSS.buttonTopRight]: true
  635. }, 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: {
  636. [CSS.input]: true,
  637. [CSS.meridiem]: true
  638. }, onFocus: this.focusHandler, onKeyDown: this.meridiemKeyDownHandler, ref: this.setMeridiemEl, role: "spinbutton", tabIndex: 0 }, this.localizedMeridiem || "--"), h("span", { "aria-label": this.intlMeridiemDown, class: {
  639. [CSS.button]: true,
  640. [CSS.buttonMeridiemDown]: true,
  641. [CSS.buttonBottomRight]: true
  642. }, onClick: this.decrementMeridiem, onKeyDown: this.meridiemDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-down", scale: iconScale }))))));
  643. }
  644. static get is() { return "calcite-time-picker"; }
  645. static get encapsulation() { return "shadow"; }
  646. static get originalStyleUrls() {
  647. return {
  648. "$": ["time-picker.scss"]
  649. };
  650. }
  651. static get styleUrls() {
  652. return {
  653. "$": ["time-picker.css"]
  654. };
  655. }
  656. static get properties() {
  657. return {
  658. "intlHour": {
  659. "type": "string",
  660. "mutable": false,
  661. "complexType": {
  662. "original": "string",
  663. "resolved": "string",
  664. "references": {}
  665. },
  666. "required": false,
  667. "optional": false,
  668. "docs": {
  669. "tags": [{
  670. "name": "default",
  671. "text": "\"Hour\""
  672. }],
  673. "text": "Accessible name for the component's hour input."
  674. },
  675. "attribute": "intl-hour",
  676. "reflect": false,
  677. "defaultValue": "TEXT.hour"
  678. },
  679. "intlHourDown": {
  680. "type": "string",
  681. "mutable": false,
  682. "complexType": {
  683. "original": "string",
  684. "resolved": "string",
  685. "references": {}
  686. },
  687. "required": false,
  688. "optional": false,
  689. "docs": {
  690. "tags": [{
  691. "name": "default",
  692. "text": "\"Decrease hour\""
  693. }],
  694. "text": "Accessible name for the component's hour down button."
  695. },
  696. "attribute": "intl-hour-down",
  697. "reflect": false,
  698. "defaultValue": "TEXT.hourDown"
  699. },
  700. "intlHourUp": {
  701. "type": "string",
  702. "mutable": false,
  703. "complexType": {
  704. "original": "string",
  705. "resolved": "string",
  706. "references": {}
  707. },
  708. "required": false,
  709. "optional": false,
  710. "docs": {
  711. "tags": [{
  712. "name": "default",
  713. "text": "\"Increase hour\""
  714. }],
  715. "text": "Accessible name for the component's hour up button."
  716. },
  717. "attribute": "intl-hour-up",
  718. "reflect": false,
  719. "defaultValue": "TEXT.hourUp"
  720. },
  721. "intlMeridiem": {
  722. "type": "string",
  723. "mutable": false,
  724. "complexType": {
  725. "original": "string",
  726. "resolved": "string",
  727. "references": {}
  728. },
  729. "required": false,
  730. "optional": false,
  731. "docs": {
  732. "tags": [{
  733. "name": "default",
  734. "text": "\"AM/PM\""
  735. }],
  736. "text": "Accessible name for the component's meridiem (AM/PM) input."
  737. },
  738. "attribute": "intl-meridiem",
  739. "reflect": false,
  740. "defaultValue": "TEXT.meridiem"
  741. },
  742. "intlMeridiemDown": {
  743. "type": "string",
  744. "mutable": false,
  745. "complexType": {
  746. "original": "string",
  747. "resolved": "string",
  748. "references": {}
  749. },
  750. "required": false,
  751. "optional": false,
  752. "docs": {
  753. "tags": [{
  754. "name": "default",
  755. "text": "\"Decrease AM/PM\""
  756. }],
  757. "text": "Accessible name for the component's meridiem (AM/PM) down button."
  758. },
  759. "attribute": "intl-meridiem-down",
  760. "reflect": false,
  761. "defaultValue": "TEXT.meridiemDown"
  762. },
  763. "intlMeridiemUp": {
  764. "type": "string",
  765. "mutable": false,
  766. "complexType": {
  767. "original": "string",
  768. "resolved": "string",
  769. "references": {}
  770. },
  771. "required": false,
  772. "optional": false,
  773. "docs": {
  774. "tags": [{
  775. "name": "default",
  776. "text": "\"Increase AM/PM\""
  777. }],
  778. "text": "Accessible name for the component's meridiem (AM/PM) up button."
  779. },
  780. "attribute": "intl-meridiem-up",
  781. "reflect": false,
  782. "defaultValue": "TEXT.meridiemUp"
  783. },
  784. "intlMinute": {
  785. "type": "string",
  786. "mutable": false,
  787. "complexType": {
  788. "original": "string",
  789. "resolved": "string",
  790. "references": {}
  791. },
  792. "required": false,
  793. "optional": false,
  794. "docs": {
  795. "tags": [{
  796. "name": "default",
  797. "text": "\"Minute\""
  798. }],
  799. "text": "Accessible name for the component's minute input."
  800. },
  801. "attribute": "intl-minute",
  802. "reflect": false,
  803. "defaultValue": "TEXT.minute"
  804. },
  805. "intlMinuteDown": {
  806. "type": "string",
  807. "mutable": false,
  808. "complexType": {
  809. "original": "string",
  810. "resolved": "string",
  811. "references": {}
  812. },
  813. "required": false,
  814. "optional": false,
  815. "docs": {
  816. "tags": [{
  817. "name": "default",
  818. "text": "\"Decrease minute\""
  819. }],
  820. "text": "Accessible name for the component's minute down button."
  821. },
  822. "attribute": "intl-minute-down",
  823. "reflect": false,
  824. "defaultValue": "TEXT.minuteDown"
  825. },
  826. "intlMinuteUp": {
  827. "type": "string",
  828. "mutable": false,
  829. "complexType": {
  830. "original": "string",
  831. "resolved": "string",
  832. "references": {}
  833. },
  834. "required": false,
  835. "optional": false,
  836. "docs": {
  837. "tags": [{
  838. "name": "default",
  839. "text": "\"Increase minute\""
  840. }],
  841. "text": "Accessible name for the component's minute up button."
  842. },
  843. "attribute": "intl-minute-up",
  844. "reflect": false,
  845. "defaultValue": "TEXT.minuteUp"
  846. },
  847. "intlSecond": {
  848. "type": "string",
  849. "mutable": false,
  850. "complexType": {
  851. "original": "string",
  852. "resolved": "string",
  853. "references": {}
  854. },
  855. "required": false,
  856. "optional": false,
  857. "docs": {
  858. "tags": [{
  859. "name": "default",
  860. "text": "\"Second\""
  861. }],
  862. "text": "Accessible name for the component's second input."
  863. },
  864. "attribute": "intl-second",
  865. "reflect": false,
  866. "defaultValue": "TEXT.second"
  867. },
  868. "intlSecondDown": {
  869. "type": "string",
  870. "mutable": false,
  871. "complexType": {
  872. "original": "string",
  873. "resolved": "string",
  874. "references": {}
  875. },
  876. "required": false,
  877. "optional": false,
  878. "docs": {
  879. "tags": [{
  880. "name": "default",
  881. "text": "\"Decrease second\""
  882. }],
  883. "text": "Accessible name for the component's second down button."
  884. },
  885. "attribute": "intl-second-down",
  886. "reflect": false,
  887. "defaultValue": "TEXT.secondDown"
  888. },
  889. "intlSecondUp": {
  890. "type": "string",
  891. "mutable": false,
  892. "complexType": {
  893. "original": "string",
  894. "resolved": "string",
  895. "references": {}
  896. },
  897. "required": false,
  898. "optional": false,
  899. "docs": {
  900. "tags": [{
  901. "name": "default",
  902. "text": "\"Increase second\""
  903. }],
  904. "text": "Accessible name for the component's second up button."
  905. },
  906. "attribute": "intl-second-up",
  907. "reflect": false,
  908. "defaultValue": "TEXT.secondUp"
  909. },
  910. "locale": {
  911. "type": "string",
  912. "mutable": true,
  913. "complexType": {
  914. "original": "string",
  915. "resolved": "string",
  916. "references": {}
  917. },
  918. "required": false,
  919. "optional": false,
  920. "docs": {
  921. "tags": [{
  922. "name": "internal",
  923. "text": undefined
  924. }, {
  925. "name": "deprecated",
  926. "text": "set the global `lang` attribute on the element instead."
  927. }, {
  928. "name": "mdn",
  929. "text": "[lang](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang)"
  930. }],
  931. "text": "BCP 47 language tag for desired language and country format."
  932. },
  933. "attribute": "locale",
  934. "reflect": false
  935. },
  936. "scale": {
  937. "type": "string",
  938. "mutable": false,
  939. "complexType": {
  940. "original": "Scale",
  941. "resolved": "\"l\" | \"m\" | \"s\"",
  942. "references": {
  943. "Scale": {
  944. "location": "import",
  945. "path": "../interfaces"
  946. }
  947. }
  948. },
  949. "required": false,
  950. "optional": false,
  951. "docs": {
  952. "tags": [],
  953. "text": "Specifies the size of the component."
  954. },
  955. "attribute": "scale",
  956. "reflect": true,
  957. "defaultValue": "\"m\""
  958. },
  959. "step": {
  960. "type": "number",
  961. "mutable": false,
  962. "complexType": {
  963. "original": "number",
  964. "resolved": "number",
  965. "references": {}
  966. },
  967. "required": false,
  968. "optional": false,
  969. "docs": {
  970. "tags": [],
  971. "text": "Specifies the granularity the `value` must adhere to (in seconds)."
  972. },
  973. "attribute": "step",
  974. "reflect": true,
  975. "defaultValue": "60"
  976. },
  977. "numberingSystem": {
  978. "type": "string",
  979. "mutable": false,
  980. "complexType": {
  981. "original": "NumberingSystem",
  982. "resolved": "\"arab\" | \"arabext\" | \"bali\" | \"beng\" | \"deva\" | \"fullwide\" | \"gujr\" | \"guru\" | \"hanidec\" | \"khmr\" | \"knda\" | \"laoo\" | \"latn\" | \"limb\" | \"mlym\" | \"mong\" | \"mymr\" | \"orya\" | \"tamldec\" | \"telu\" | \"thai\" | \"tibt\"",
  983. "references": {
  984. "NumberingSystem": {
  985. "location": "import",
  986. "path": "../../utils/locale"
  987. }
  988. }
  989. },
  990. "required": false,
  991. "optional": true,
  992. "docs": {
  993. "tags": [],
  994. "text": "Specifies the Unicode numeral system used by the component for localization."
  995. },
  996. "attribute": "numbering-system",
  997. "reflect": false
  998. },
  999. "value": {
  1000. "type": "string",
  1001. "mutable": true,
  1002. "complexType": {
  1003. "original": "string",
  1004. "resolved": "string",
  1005. "references": {}
  1006. },
  1007. "required": false,
  1008. "optional": false,
  1009. "docs": {
  1010. "tags": [],
  1011. "text": "The component's value in UTC (always 24-hour format)."
  1012. },
  1013. "attribute": "value",
  1014. "reflect": false,
  1015. "defaultValue": "null"
  1016. }
  1017. };
  1018. }
  1019. static get states() {
  1020. return {
  1021. "effectiveLocale": {},
  1022. "hour": {},
  1023. "hourCycle": {},
  1024. "localizedHour": {},
  1025. "localizedHourSuffix": {},
  1026. "localizedMeridiem": {},
  1027. "localizedMinute": {},
  1028. "localizedMinuteSuffix": {},
  1029. "localizedSecond": {},
  1030. "localizedSecondSuffix": {},
  1031. "meridiem": {},
  1032. "minute": {},
  1033. "second": {},
  1034. "showSecond": {}
  1035. };
  1036. }
  1037. static get events() {
  1038. return [{
  1039. "method": "calciteInternalTimePickerBlur",
  1040. "name": "calciteInternalTimePickerBlur",
  1041. "bubbles": true,
  1042. "cancelable": false,
  1043. "composed": true,
  1044. "docs": {
  1045. "tags": [{
  1046. "name": "internal",
  1047. "text": undefined
  1048. }],
  1049. "text": ""
  1050. },
  1051. "complexType": {
  1052. "original": "void",
  1053. "resolved": "void",
  1054. "references": {}
  1055. }
  1056. }, {
  1057. "method": "calciteInternalTimePickerChange",
  1058. "name": "calciteInternalTimePickerChange",
  1059. "bubbles": true,
  1060. "cancelable": false,
  1061. "composed": true,
  1062. "docs": {
  1063. "tags": [{
  1064. "name": "internal",
  1065. "text": undefined
  1066. }],
  1067. "text": ""
  1068. },
  1069. "complexType": {
  1070. "original": "string",
  1071. "resolved": "string",
  1072. "references": {}
  1073. }
  1074. }, {
  1075. "method": "calciteInternalTimePickerFocus",
  1076. "name": "calciteInternalTimePickerFocus",
  1077. "bubbles": true,
  1078. "cancelable": false,
  1079. "composed": true,
  1080. "docs": {
  1081. "tags": [{
  1082. "name": "internal",
  1083. "text": undefined
  1084. }],
  1085. "text": ""
  1086. },
  1087. "complexType": {
  1088. "original": "void",
  1089. "resolved": "void",
  1090. "references": {}
  1091. }
  1092. }];
  1093. }
  1094. static get methods() {
  1095. return {
  1096. "setFocus": {
  1097. "complexType": {
  1098. "signature": "(target: TimePart) => Promise<void>",
  1099. "parameters": [{
  1100. "tags": [{
  1101. "name": "param",
  1102. "text": "target"
  1103. }],
  1104. "text": ""
  1105. }],
  1106. "references": {
  1107. "Promise": {
  1108. "location": "global"
  1109. },
  1110. "TimePart": {
  1111. "location": "import",
  1112. "path": "../../utils/time"
  1113. }
  1114. },
  1115. "return": "Promise<void>"
  1116. },
  1117. "docs": {
  1118. "text": "Sets focus on the component.",
  1119. "tags": [{
  1120. "name": "param",
  1121. "text": "target"
  1122. }]
  1123. }
  1124. }
  1125. };
  1126. }
  1127. static get elementRef() { return "el"; }
  1128. static get watchers() {
  1129. return [{
  1130. "propName": "locale",
  1131. "methodName": "localeChanged"
  1132. }, {
  1133. "propName": "value",
  1134. "methodName": "valueWatcher"
  1135. }, {
  1136. "propName": "effectiveLocale",
  1137. "methodName": "effectiveLocaleWatcher"
  1138. }];
  1139. }
  1140. static get listeners() {
  1141. return [{
  1142. "name": "blur",
  1143. "method": "hostBlurHandler",
  1144. "target": undefined,
  1145. "capture": false,
  1146. "passive": false
  1147. }, {
  1148. "name": "focus",
  1149. "method": "hostFocusHandler",
  1150. "target": undefined,
  1151. "capture": false,
  1152. "passive": false
  1153. }, {
  1154. "name": "keydown",
  1155. "method": "keyDownHandler",
  1156. "target": undefined,
  1157. "capture": false,
  1158. "passive": false
  1159. }];
  1160. }
  1161. }