UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

724 lines (723 loc) • 33.6 kB
/*! All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://github.com/Esri/calcite-design-system/blob/dev/LICENSE.md for details. v3.2.1 */ import { c as customElement } from "../../chunks/runtime.js"; import { ref } from "lit-html/directives/ref.js"; import { html } from "lit"; import { LitElement, createEvent, safeClassMap } from "@arcgis/lumina"; import { n as numberKeys } from "../../chunks/key.js"; import { i as isValidNumber } from "../../chunks/locale.js"; import { f as formatTimePart, p as parseTimeString, i as isValidTime, l as localizeTimeStringToParts, g as getMeridiem, a as getLocalizedTimePartSuffix, b as getLocalizedDecimalSeparator, c as localizeTimePart, d as getLocaleHourFormat, e as getMeridiemOrder, m as maxTenthForMinuteAndSecond } from "../../chunks/time.js"; import { c as componentFocusable, g as getIconScale } from "../../chunks/component.js"; import { g as getDecimals, d as decimalPlaces } from "../../chunks/math.js"; import { g as getElementDir } from "../../chunks/dom.js"; import { u as useT9n } from "../../chunks/useT9n.js"; import { css } from "@lit/reactive-element/css-tag.js"; const CSS = { button: "button", buttonBottomLeft: "button--bottom-left", buttonBottomRight: "button--bottom-right", buttonFractionalSecondDown: "button--fractionalSecond-down", buttonFractionalSecondUp: "button--fractionalSecond-up", buttonHourDown: "button--hour-down", buttonHourUp: "button--hour-up", buttonMeridiemDown: "button--meridiem-down", buttonMeridiemUp: "button--meridiem-up", buttonMinuteDown: "button--minute-down", buttonMinuteUp: "button--minute-up", buttonSecondDown: "button--second-down", buttonSecondUp: "button--second-up", buttonTopLeft: "button--top-left", buttonTopRight: "button--top-right", column: "column", decimalSeparator: "decimal-separator", delimiter: "delimiter", fractionalSecond: "fractionalSecond", hour: "hour", hourSuffix: "hour-suffix", input: "input", inputFocus: "inputFocus", meridiem: "meridiem", minute: "minute", minuteSuffix: "minute-suffix", second: "second", secondSuffix: "second-suffix", showMeridiem: "show-meridiem", showSecond: "show-second", "scale-s": "scale-s", "scale-m": "scale-m", "scale-l": "scale-l", timePicker: "time-picker", meridiemStart: "meridiem--start" }; const styles = css`:host{display:inline-block}.time-picker{display:flex;-webkit-user-select:none;user-select:none;align-items:center;font-weight:var(--calcite-font-weight-medium);--tw-shadow: 0 6px 20px -4px rgba(0, 0, 0, .1), 0 4px 12px -2px rgba(0, 0, 0, .08);--tw-shadow-colored: 0 6px 20px -4px var(--tw-shadow-color), 0 4px 12px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);border-radius:var(--calcite-time-picker-corner-radius, var(--calcite-border-radius-round));color:var(--calcite-time-picker-color, var(--calcite-color-text-1));background-color:var(--calcite-time-picker-background-color, var(--calcite-color-foreground-1))}.time-picker .column{display:flex;flex-direction:column}.time-picker .meridiem--start{order:-1}.time-picker .button{display:inline-flex;cursor:pointer;align-items:center;justify-content:center;background-color:var(--calcite-time-picker-background-color, var(--calcite-color-foreground-1))}.time-picker .button:hover,.time-picker .button:focus{outline:2px solid transparent;outline-offset:2px;z-index:var(--calcite-z-index-header);outline-offset:0;background-color:var(--calcite-time-picker-button-background-color-hover, var(--calcite-color-foreground-2))}.time-picker .button:active{background-color:var(--calcite-time-picker-button-background-color-press, var(--calcite-color-foreground-3))}.time-picker .button.top-left{border-start-start-radius:var(--calcite-time-picker-corner-radius, var(--calcite-border-radius-round))}.time-picker .button.bottom-left{border-end-start-radius:var(--calcite-time-picker-corner-radius, var(--calcite-border-radius-round))}.time-picker .button.top-right{border-start-end-radius:var(--calcite-time-picker-corner-radius, var(--calcite-border-radius-round))}.time-picker .button.bottom-right{border-end-end-radius:var(--calcite-time-picker-corner-radius, var(--calcite-border-radius-round))}.time-picker .button calcite-icon{color:var(--calcite-time-picker-icon-color, var(--calcite-color-text-3))}.time-picker .input{display:inline-flex;cursor:pointer;align-items:center;justify-content:center;font-weight:var(--calcite-font-weight-medium);background-color:var(--calcite-time-picker-background-color, var(--calcite-color-foreground-1))}.time-picker .input:hover{box-shadow:inset 0 0 0 2px var(--calcite-time-picker-input-border-color-hover, var(--calcite-color-foreground-2));z-index:var(--calcite-z-index-header)}.time-picker .input:focus,.time-picker .input:hover:focus{outline:2px solid transparent;outline-offset:2px;outline-offset:0}.time-picker .input.inputFocus,.time-picker .input:hover.inputFocus{box-shadow:inset 0 0 0 2px var(--calcite-time-picker-input-border-color-press, var(--calcite-color-brand));z-index:var(--calcite-z-index-header)}.time-picker.scale-s{font-size:var(--calcite-font-size--1)}.time-picker.scale-s .button,.time-picker.scale-s .input{padding-inline:var(--calcite-spacing-md);padding-block:var(--calcite-spacing-xxs)}.time-picker.scale-s:not(.show-meridiem) .delimiter:last-child{padding-inline-end:var(--calcite-spacing-md)}.time-picker.scale-m{font-size:var(--calcite-font-size-0)}.time-picker.scale-m .button,.time-picker.scale-m .input{padding-inline:var(--calcite-spacing-xl);padding-block:var(--calcite-spacing-sm)}.time-picker.scale-m:not(.show-meridiem) .delimiter:last-child{padding-inline-end:var(--calcite-spacing-xl)}.time-picker.scale-l{font-size:var(--calcite-font-size-1)}.time-picker.scale-l .button,.time-picker.scale-l .input{padding-inline:var(--calcite-spacing-xxl);padding-block:var(--calcite-spacing-md)}.time-picker.scale-l:not(.show-meridiem) .delimiter:last-child{padding-inline-end:var(--calcite-spacing-xxl)}:host([hidden]){display:none}[hidden]{display:none}`; function capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1); } class TimePicker extends LitElement { constructor() { super(); this.pointerActivated = false; this.messages = useT9n(); this.localizedDecimalSeparator = "."; this.hourFormat = "user"; this.scale = "m"; this.step = 60; this.value = null; this.calciteTimePickerChange = createEvent({ cancelable: false }); this.listen("blur", this.blurHandler); this.listen("keydown", this.keyDownHandler); this.listen("pointerdown", this.pointerDownHandler); } static { this.properties = { activeEl: [16, {}, { state: true }], effectiveHourFormat: [16, {}, { state: true }], fractionalSecond: [16, {}, { state: true }], hour: [16, {}, { state: true }], localizedDecimalSeparator: [16, {}, { state: true }], localizedFractionalSecond: [16, {}, { state: true }], localizedHour: [16, {}, { state: true }], localizedHourSuffix: [16, {}, { state: true }], localizedMeridiem: [16, {}, { state: true }], localizedMinute: [16, {}, { state: true }], localizedMinuteSuffix: [16, {}, { state: true }], localizedSecond: [16, {}, { state: true }], localizedSecondSuffix: [16, {}, { state: true }], meridiem: [16, {}, { state: true }], minute: [16, {}, { state: true }], second: [16, {}, { state: true }], showFractionalSecond: [16, {}, { state: true }], showSecond: [16, {}, { state: true }], hourFormat: [3, {}, { reflect: true }], messageOverrides: [0, {}, { attribute: false }], numberingSystem: 1, scale: [3, {}, { reflect: true }], step: [11, {}, { reflect: true, type: Number }], value: 1 }; } static { this.shadowRootOptions = { mode: "open", delegatesFocus: true }; } static { this.styles = styles; } async setFocus() { await componentFocusable(this); this.el?.focus(); } connectedCallback() { super.connectedCallback(); this.updateLocale(); this.toggleSecond(); } willUpdate(changes) { if (changes.has("step") && (this.hasUpdated || this.step !== 60)) { this.toggleSecond(); } if (changes.has("value") && (this.hasUpdated || this.value !== null)) { this.setValue(this.value); } if (changes.has("hourFormat") || changes.has("messages")) { this.updateLocale(); } } blurHandler() { this.activeEl = void 0; this.pointerActivated = false; } keyDownHandler(event) { this.pointerActivated = false; const { defaultPrevented, key } = event; if (defaultPrevented) { return; } switch (this.activeEl) { case this.hourEl: if (key === "ArrowRight") { this.focusPart("minute"); event.preventDefault(); } break; case this.minuteEl: switch (key) { case "ArrowLeft": this.focusPart("hour"); event.preventDefault(); break; case "ArrowRight": if (this.step !== 60) { this.focusPart("second"); event.preventDefault(); } else if (this.effectiveHourFormat === "12") { this.focusPart("meridiem"); event.preventDefault(); } break; } break; case this.secondEl: switch (key) { case "ArrowLeft": this.focusPart("minute"); event.preventDefault(); break; case "ArrowRight": if (this.showFractionalSecond) { this.focusPart("fractionalSecond"); } else if (this.effectiveHourFormat === "12") { this.focusPart("meridiem"); event.preventDefault(); } break; } break; case this.fractionalSecondEl: switch (key) { case "ArrowLeft": this.focusPart("second"); event.preventDefault(); break; case "ArrowRight": if (this.effectiveHourFormat === "12") { this.focusPart("meridiem"); event.preventDefault(); } break; } break; case this.meridiemEl: switch (key) { case "ArrowLeft": if (this.showFractionalSecond) { this.focusPart("fractionalSecond"); } else if (this.step !== 60) { this.focusPart("second"); event.preventDefault(); } else { this.focusPart("minute"); event.preventDefault(); } break; } break; } } pointerDownHandler() { this.pointerActivated = true; } async focusPart(target) { await componentFocusable(this); this[`${target || "hour"}El`]?.focus(); } decrementHour() { const newHour = !this.hour ? 0 : parseInt(this.hour) === 0 ? 23 : parseInt(this.hour) - 1; this.setValuePart("hour", newHour); } decrementMeridiem() { const newMeridiem = this.meridiem === "PM" ? "AM" : "PM"; this.setValuePart("meridiem", newMeridiem); } decrementMinuteOrSecond(key) { let newValue; if (isValidNumber(this[key])) { const valueAsNumber = parseInt(this[key]); newValue = valueAsNumber === 0 ? 59 : valueAsNumber - 1; } else { newValue = 59; } this.setValuePart(key, newValue); } decrementMinute() { this.decrementMinuteOrSecond("minute"); } decrementSecond() { this.decrementMinuteOrSecond("second"); } focusHandler(event) { if (this.pointerActivated) { return; } this.activeEl = event.currentTarget; } fractionalSecondKeyDownHandler(event) { const { key } = event; if (numberKeys.includes(key)) { const { stepPrecision } = this; const fractionalSecondAsInteger = parseInt(this.fractionalSecond); const fractionalSecondAsIntegerLength = fractionalSecondAsInteger.toString().length; let newFractionalSecondAsIntegerString; if (fractionalSecondAsIntegerLength >= stepPrecision) { newFractionalSecondAsIntegerString = key.padStart(stepPrecision, "0"); } else if (fractionalSecondAsIntegerLength < stepPrecision) { newFractionalSecondAsIntegerString = `${fractionalSecondAsInteger}${key}`.padStart(stepPrecision, "0"); } this.setValuePart("fractionalSecond", parseFloat(`0.${newFractionalSecondAsIntegerString}`)); } else { switch (key) { case "Backspace": case "Delete": this.setValuePart("fractionalSecond", null); break; case "ArrowDown": event.preventDefault(); this.nudgeFractionalSecond("down"); break; case "ArrowUp": event.preventDefault(); this.nudgeFractionalSecond("up"); break; case " ": event.preventDefault(); break; } } } fractionalSecondDownClickHandler() { this.activeEl = this.fractionalSecondEl; this.fractionalSecondEl.focus(); this.nudgeFractionalSecond("down"); } fractionalSecondUpClickHandler() { this.activeEl = this.fractionalSecondEl; this.fractionalSecondEl.focus(); this.nudgeFractionalSecond("up"); } hourDownClickHandler() { this.activeEl = this.hourEl; this.hourEl.focus(); this.decrementHour(); } hourKeyDownHandler(event) { const { key } = event; if (numberKeys.includes(key)) { const keyAsNumber = parseInt(key); let newHour; if (isValidNumber(this.hour)) { switch (this.effectiveHourFormat) { case "12": newHour = this.hour === "01" && keyAsNumber >= 0 && keyAsNumber <= 2 ? `1${keyAsNumber}` : keyAsNumber; break; case "24": if (this.hour === "01") { newHour = `1${keyAsNumber}`; } else if (this.hour === "02" && keyAsNumber >= 0 && keyAsNumber <= 3) { newHour = `2${keyAsNumber}`; } else { newHour = keyAsNumber; } break; } } else { newHour = keyAsNumber; } this.setValuePart("hour", newHour); } else { switch (key) { case "Backspace": case "Delete": this.setValuePart("hour", null); break; case "ArrowDown": event.preventDefault(); this.decrementHour(); break; case "ArrowUp": event.preventDefault(); this.incrementHour(); break; case " ": event.preventDefault(); break; } } } hourUpClickHandler() { this.activeEl = this.hourEl; this.hourEl.focus(); this.incrementHour(); } incrementMeridiem() { const newMeridiem = this.meridiem === "AM" ? "PM" : "AM"; this.setValuePart("meridiem", newMeridiem); } incrementHour() { const newHour = isValidNumber(this.hour) ? this.hour === "23" ? 0 : parseInt(this.hour) + 1 : 1; this.setValuePart("hour", newHour); } incrementMinuteOrSecond(key) { const newValue = isValidNumber(this[key]) ? this[key] === "59" ? 0 : parseInt(this[key]) + 1 : 0; this.setValuePart(key, newValue); } incrementMinute() { this.incrementMinuteOrSecond("minute"); } incrementSecond() { this.incrementMinuteOrSecond("second"); } inputClickHandler(event) { this.activeEl = event.target; } meridiemUpClickHandler() { this.activeEl = this.meridiemEl; this.meridiemEl.focus(); this.incrementMeridiem(); } meridiemKeyDownHandler(event) { switch (event.key) { case "a": this.setValuePart("meridiem", "AM"); break; case "p": this.setValuePart("meridiem", "PM"); break; case "Backspace": case "Delete": this.setValuePart("meridiem", null); break; case "ArrowUp": event.preventDefault(); this.incrementMeridiem(); break; case "ArrowDown": event.preventDefault(); this.decrementMeridiem(); break; case " ": event.preventDefault(); break; } } meridiemDownClickHandler() { this.activeEl = this.meridiemEl; this.meridiemEl.focus(); this.decrementMeridiem(); } minuteDownClickHandler() { this.activeEl = this.minuteEl; this.minuteEl.focus(); this.decrementMinute(); } minuteUpClickHandler() { this.activeEl = this.minuteEl; this.minuteEl.focus(); this.incrementMinute(); } minuteKeyDownHandler(event) { const { key } = event; if (numberKeys.includes(key)) { const keyAsNumber = parseInt(key); let newMinute; if (isValidNumber(this.minute) && this.minute.startsWith("0")) { const minuteAsNumber = parseInt(this.minute); newMinute = minuteAsNumber > maxTenthForMinuteAndSecond ? keyAsNumber : `${minuteAsNumber}${keyAsNumber}`; } else { newMinute = keyAsNumber; } this.setValuePart("minute", newMinute); } else { switch (key) { case "Backspace": case "Delete": this.setValuePart("minute", null); break; case "ArrowDown": event.preventDefault(); this.decrementMinute(); break; case "ArrowUp": event.preventDefault(); this.incrementMinute(); break; case " ": event.preventDefault(); break; } } } nudgeFractionalSecond(direction) { const stepDecimal = getDecimals(this.step); const { stepPrecision } = this; const fractionalSecondAsInteger = parseInt(this.fractionalSecond); const fractionalSecondAsFloat = parseFloat(`0.${this.fractionalSecond}`); let nudgedValue; let nudgedValueRounded; let nudgedValueRoundedDecimals; let newFractionalSecond; if (direction === "up") { nudgedValue = isNaN(fractionalSecondAsInteger) ? 0 : fractionalSecondAsFloat + stepDecimal; nudgedValueRounded = parseFloat(nudgedValue.toFixed(stepPrecision)); nudgedValueRoundedDecimals = getDecimals(nudgedValueRounded); newFractionalSecond = nudgedValueRounded < 1 && decimalPlaces(nudgedValueRoundedDecimals) > 0 ? formatTimePart(nudgedValueRoundedDecimals, stepPrecision) : "".padStart(stepPrecision, "0"); } if (direction === "down") { nudgedValue = isNaN(fractionalSecondAsInteger) || fractionalSecondAsInteger === 0 ? 1 - stepDecimal : fractionalSecondAsFloat - stepDecimal; nudgedValueRounded = parseFloat(nudgedValue.toFixed(stepPrecision)); nudgedValueRoundedDecimals = getDecimals(nudgedValueRounded); newFractionalSecond = nudgedValueRounded < 1 && decimalPlaces(nudgedValueRoundedDecimals) > 0 && Math.sign(nudgedValueRoundedDecimals) === 1 ? formatTimePart(nudgedValueRoundedDecimals, stepPrecision) : "".padStart(stepPrecision, "0"); } this.setValuePart("fractionalSecond", newFractionalSecond); } sanitizeValue(value) { const { hour, minute, second, fractionalSecond } = parseTimeString(value); if (fractionalSecond) { const sanitizedFractionalSecond = this.sanitizeFractionalSecond(fractionalSecond); return `${hour}:${minute}:${second}.${sanitizedFractionalSecond}`; } return isValidTime(value) && value; } sanitizeFractionalSecond(fractionalSecond) { const { stepPrecision } = this; return fractionalSecond && stepPrecision !== fractionalSecond.length ? parseFloat(`0.${fractionalSecond}`).toFixed(stepPrecision).replace("0.", "") : fractionalSecond; } secondKeyDownHandler(event) { const { key } = event; if (numberKeys.includes(key)) { const keyAsNumber = parseInt(key); let newSecond; if (isValidNumber(this.second) && this.second.startsWith("0")) { const secondAsNumber = parseInt(this.second); newSecond = secondAsNumber > maxTenthForMinuteAndSecond ? keyAsNumber : `${secondAsNumber}${keyAsNumber}`; } else { newSecond = keyAsNumber; } this.setValuePart("second", newSecond); } else { switch (key) { case "Backspace": case "Delete": this.setValuePart("second", null); break; case "ArrowDown": event.preventDefault(); this.decrementSecond(); break; case "ArrowUp": event.preventDefault(); this.incrementSecond(); break; case " ": event.preventDefault(); break; } } } secondDownClickHandler() { this.activeEl = this.secondEl; this.secondEl.focus(); this.decrementSecond(); } secondUpClickHandler() { this.activeEl = this.secondEl; this.secondEl.focus(); this.incrementSecond(); } setHourEl(el) { this.hourEl = el; } setMeridiemEl(el) { this.meridiemEl = el; } setMinuteEl(el) { this.minuteEl = el; } setSecondEl(el) { this.secondEl = el; } setFractionalSecondEl(el) { this.fractionalSecondEl = el; } setValue(value) { if (isValidTime(value)) { const { hour, minute, second, fractionalSecond } = parseTimeString(value); const { effectiveHourFormat, messages: { _lang: locale }, numberingSystem, step } = this; const { hour: localizedHour, hourSuffix: localizedHourSuffix, minute: localizedMinute, minuteSuffix: localizedMinuteSuffix, second: localizedSecond, secondSuffix: localizedSecondSuffix, decimalSeparator: localizedDecimalSeparator, fractionalSecond: localizedFractionalSecond, meridiem: localizedMeridiem } = localizeTimeStringToParts({ value, locale, numberingSystem, hour12: effectiveHourFormat === "12", step }); this.hour = hour; this.minute = minute; this.second = second; this.fractionalSecond = this.sanitizeFractionalSecond(fractionalSecond); this.localizedHour = localizedHour; this.localizedHourSuffix = localizedHourSuffix; this.localizedMinute = localizedMinute; this.localizedMinuteSuffix = localizedMinuteSuffix; this.localizedSecond = localizedSecond; this.localizedDecimalSeparator = localizedDecimalSeparator; this.localizedFractionalSecond = localizedFractionalSecond; this.localizedSecondSuffix = localizedSecondSuffix; if (localizedMeridiem) { this.localizedMeridiem = localizedMeridiem; this.meridiem = getMeridiem(this.hour); } } else { this.hour = null; this.fractionalSecond = null; this.localizedHour = null; this.localizedHourSuffix = getLocalizedTimePartSuffix("hour", this.messages._lang, this.numberingSystem); this.localizedMeridiem = null; this.localizedMinute = null; this.localizedMinuteSuffix = getLocalizedTimePartSuffix("minute", this.messages._lang, this.numberingSystem); this.localizedSecond = null; this.localizedDecimalSeparator = getLocalizedDecimalSeparator(this.messages._lang, this.numberingSystem); this.localizedFractionalSecond = null; this.localizedSecondSuffix = getLocalizedTimePartSuffix("second", this.messages._lang, this.numberingSystem); this.meridiem = null; this.minute = null; this.second = null; this.value = null; } } setValuePart(key, value) { const { effectiveHourFormat, messages: { _lang: locale }, numberingSystem, step } = this; const hour12 = effectiveHourFormat === "12"; if (key === "meridiem") { this.meridiem = value; if (isValidNumber(this.hour)) { const hourAsNumber = parseInt(this.hour); switch (value) { case "AM": if (hourAsNumber >= 12) { this.hour = formatTimePart(hourAsNumber - 12); } break; case "PM": if (hourAsNumber < 12) { this.hour = formatTimePart(hourAsNumber + 12); } break; } this.localizedHour = localizeTimePart({ value: this.hour, part: "hour", locale, numberingSystem, hour12 }); } } else if (key === "fractionalSecond") { const { stepPrecision } = this; if (typeof value === "number") { this.fractionalSecond = value === 0 ? "".padStart(stepPrecision, "0") : formatTimePart(value, stepPrecision); } else { this.fractionalSecond = value; } this.localizedFractionalSecond = localizeTimePart({ value: this.fractionalSecond, part: "fractionalSecond", locale, numberingSystem, hour12 }); } else { this[key] = typeof value === "number" ? formatTimePart(value) : value; this[`localized${capitalize(key)}`] = localizeTimePart({ value: this[key], part: key, locale, numberingSystem, hour12 }); } let emit = false; let newValue; if (this.hour && this.minute) { newValue = `${this.hour}:${this.minute}`; if (this.showSecond) { newValue = `${newValue}:${this.second ?? "00"}`; if (this.showFractionalSecond && this.fractionalSecond) { newValue = `${newValue}.${this.fractionalSecond}`; } } } else { newValue = null; } if (this.value !== newValue) { emit = true; } this.value = newValue; this.localizedMeridiem = this.value ? localizeTimeStringToParts({ hour12, locale, numberingSystem, step, value: this.value })?.meridiem || null : localizeTimePart({ hour12, value: this.meridiem, part: "meridiem", locale, numberingSystem }); if (emit) { this.calciteTimePickerChange.emit(); } } toggleSecond() { this.showSecond = this.step < 60; this.stepPrecision = decimalPlaces(this.step); this.showFractionalSecond = this.stepPrecision > 0; } updateLocale() { this.effectiveHourFormat = this.hourFormat === "user" ? getLocaleHourFormat(this.messages._lang) : this.hourFormat; this.localizedDecimalSeparator = getLocalizedDecimalSeparator(this.messages._lang, this.numberingSystem); this.meridiemOrder = getMeridiemOrder(this.messages._lang); this.setValue(this.sanitizeValue(this.value)); } render() { const hourIsNumber = isValidNumber(this.hour); const iconScale = getIconScale(this.scale); const minuteIsNumber = isValidNumber(this.minute); const secondIsNumber = isValidNumber(this.second); const fractionalSecondIsNumber = isValidNumber(this.fractionalSecond); const showSecondSuffix = this.messages._lang !== "bg" && this.localizedSecondSuffix; const showMeridiem = this.effectiveHourFormat === "12"; return html`<div class=${safeClassMap({ [CSS.timePicker]: true, [CSS.showMeridiem]: showMeridiem, [CSS.showSecond]: this.showSecond, [CSS[`scale-${this.scale}`]]: true })} dir=ltr><div class=${safeClassMap(CSS.column)} role=group><span .ariaLabel=${this.messages.hourUp} class=${safeClassMap({ [CSS.button]: true, [CSS.buttonHourUp]: true, [CSS.buttonTopLeft]: true })} @click=${this.hourUpClickHandler} role=button><calcite-icon icon=chevron-up .scale=${iconScale}></calcite-icon></span><span .ariaLabel=${this.messages.hour} aria-valuemax=23 aria-valuemin=1 .ariaValueNow=${hourIsNumber && parseInt(this.hour) || "0"} .ariaValueText=${this.hour} class=${safeClassMap({ [CSS.input]: true, [CSS.hour]: true, [CSS.inputFocus]: this.activeEl && this.activeEl === this.hourEl })} @click=${this.inputClickHandler} @focus=${this.focusHandler} @keydown=${this.hourKeyDownHandler} role=spinbutton tabindex=0 ${ref(this.setHourEl)}>${this.localizedHour || "--"}</span><span .ariaLabel=${this.messages.hourDown} class=${safeClassMap({ [CSS.button]: true, [CSS.buttonHourDown]: true, [CSS.buttonBottomLeft]: true })} @click=${this.hourDownClickHandler} role=button><calcite-icon icon=chevron-down .scale=${iconScale}></calcite-icon></span></div><span class=${safeClassMap({ [CSS.delimiter]: true, [CSS.hourSuffix]: true })}>${this.localizedHourSuffix}</span><div class=${safeClassMap(CSS.column)} role=group><span .ariaLabel=${this.messages.minuteUp} class=${safeClassMap({ [CSS.button]: true, [CSS.buttonMinuteUp]: true })} @click=${this.minuteUpClickHandler} role=button><calcite-icon icon=chevron-up .scale=${iconScale}></calcite-icon></span><span .ariaLabel=${this.messages.minute} aria-valuemax=12 aria-valuemin=1 .ariaValueNow=${minuteIsNumber && parseInt(this.minute) || "0"} .ariaValueText=${this.minute} class=${safeClassMap({ [CSS.input]: true, [CSS.minute]: true, [CSS.inputFocus]: this.activeEl && this.activeEl === this.minuteEl })} @click=${this.inputClickHandler} @focus=${this.focusHandler} @keydown=${this.minuteKeyDownHandler} role=spinbutton tabindex=0 ${ref(this.setMinuteEl)}>${this.localizedMinute || "--"}</span><span .ariaLabel=${this.messages.minuteDown} class=${safeClassMap({ [CSS.button]: true, [CSS.buttonMinuteDown]: true })} @click=${this.minuteDownClickHandler} role=button><calcite-icon icon=chevron-down .scale=${iconScale}></calcite-icon></span></div>${this.showSecond && html`<span class=${safeClassMap({ [CSS.delimiter]: true, [CSS.minuteSuffix]: true })}>${this.localizedMinuteSuffix}</span>` || ""}${this.showSecond && html`<div class=${safeClassMap(CSS.column)} role=group><span .ariaLabel=${this.messages.secondUp} class=${safeClassMap({ [CSS.button]: true, [CSS.buttonSecondUp]: true })} @click=${this.secondUpClickHandler} role=button><calcite-icon icon=chevron-up .scale=${iconScale}></calcite-icon></span><span .ariaLabel=${this.messages.second} aria-valuemax=59 aria-valuemin=0 .ariaValueNow=${secondIsNumber && parseInt(this.second) || "0"} .ariaValueText=${this.second} class=${safeClassMap({ [CSS.input]: true, [CSS.second]: true, [CSS.inputFocus]: this.activeEl && this.activeEl === this.secondEl })} @click=${this.inputClickHandler} @focus=${this.focusHandler} @keydown=${this.secondKeyDownHandler} role=spinbutton tabindex=0 ${ref(this.setSecondEl)}>${this.localizedSecond || "--"}</span><span .ariaLabel=${this.messages.secondDown} class=${safeClassMap({ [CSS.button]: true, [CSS.buttonSecondDown]: true })} @click=${this.secondDownClickHandler} role=button><calcite-icon icon=chevron-down .scale=${iconScale}></calcite-icon></span></div>` || ""}${this.showFractionalSecond && html`<span class=${safeClassMap({ [CSS.delimiter]: true, [CSS.decimalSeparator]: true })}>${this.localizedDecimalSeparator}</span>` || ""}${this.showFractionalSecond && html`<div class=${safeClassMap(CSS.column)} role=group><span .ariaLabel=${this.messages.fractionalSecondUp} class=${safeClassMap({ [CSS.button]: true, [CSS.buttonFractionalSecondUp]: true })} @click=${this.fractionalSecondUpClickHandler} role=button><calcite-icon icon=chevron-up .scale=${iconScale}></calcite-icon></span><span .ariaLabel=${this.messages.fractionalSecond} aria-valuemax=999 aria-valuemin=1 .ariaValueNow=${fractionalSecondIsNumber && parseInt(this.fractionalSecond) || "0"} .ariaValueText=${this.localizedFractionalSecond} class=${safeClassMap({ [CSS.input]: true, [CSS.fractionalSecond]: true, [CSS.inputFocus]: this.activeEl && this.activeEl === this.fractionalSecondEl })} @click=${this.inputClickHandler} @focus=${this.focusHandler} @keydown=${this.fractionalSecondKeyDownHandler} role=spinbutton tabindex=0 ${ref(this.setFractionalSecondEl)}>${this.localizedFractionalSecond || "".padStart(this.stepPrecision, "-")}</span><span .ariaLabel=${this.messages.fractionalSecondDown} class=${safeClassMap({ [CSS.button]: true, [CSS.buttonFractionalSecondDown]: true })} @click=${this.fractionalSecondDownClickHandler} role=button><calcite-icon icon=chevron-down .scale=${iconScale}></calcite-icon></span></div>` || ""}${showSecondSuffix && html`<span class=${safeClassMap({ [CSS.delimiter]: true, [CSS.secondSuffix]: true })}>${this.localizedSecondSuffix}</span>` || ""}${showMeridiem && html`<div class=${safeClassMap({ [CSS.column]: true, [CSS.meridiemStart]: this.meridiemOrder === 0 || getElementDir(this.el) === "rtl" })} role=group><span .ariaLabel=${this.messages.meridiemUp} class=${safeClassMap({ [CSS.button]: true, [CSS.buttonMeridiemUp]: true, [CSS.buttonTopRight]: true })} @click=${this.meridiemUpClickHandler} role=button><calcite-icon icon=chevron-up .scale=${iconScale}></calcite-icon></span><span .ariaLabel=${this.messages.meridiem} aria-valuemax=2 aria-valuemin=1 .ariaValueNow=${this.meridiem === "PM" && "2" || "1"} .ariaValueText=${this.meridiem} class=${safeClassMap({ [CSS.input]: true, [CSS.meridiem]: true, [CSS.inputFocus]: this.activeEl && this.activeEl === this.meridiemEl })} @click=${this.inputClickHandler} @focus=${this.focusHandler} @keydown=${this.meridiemKeyDownHandler} role=spinbutton tabindex=0 ${ref(this.setMeridiemEl)}>${this.localizedMeridiem || "--"}</span><span .ariaLabel=${this.messages.meridiemDown} class=${safeClassMap({ [CSS.button]: true, [CSS.buttonMeridiemDown]: true, [CSS.buttonBottomRight]: true })} @click=${this.meridiemDownClickHandler} role=button><calcite-icon icon=chevron-down .scale=${iconScale}></calcite-icon></span></div>` || ""}</div>`; } } customElement("calcite-time-picker", TimePicker); export { TimePicker };