@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
871 lines (865 loc) • 37.7 kB
JavaScript
/*!
* All material copyright ESRI, All Rights Reserved, unless otherwise specified.
* See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
*/
import { proxyCustomElement, HTMLElement, createEvent, h } from '@stencil/core/internal/client';
import { i as isValidNumber, n as numberKeys, c as isActivationKey } from './number.js';
import { d as defineCustomElement$1 } from './icon.js';
const maxTenthForMinuteAndSecond = 5;
function createLocaleDateTimeFormatter(locale, includeSeconds = true) {
try {
const options = {
hour: "2-digit",
minute: "2-digit",
timeZone: "UTC"
};
if (includeSeconds) {
options.second = "2-digit";
}
return new Intl.DateTimeFormat(locale, options);
}
catch (e) {
throw new Error(`Invalid locale supplied while attempting to create a DateTime formatter: ${locale}`);
}
}
function formatTimePart(number) {
const numberAsString = number.toString();
return number >= 0 && number <= 9 ? numberAsString.padStart(2, "0") : numberAsString;
}
function formatTimeString(value) {
if (!isValidTime(value)) {
return null;
}
const [hourString, minuteString, secondString] = value.split(":");
const hour = formatTimePart(parseInt(hourString));
const minute = formatTimePart(parseInt(minuteString));
if (secondString) {
const second = formatTimePart(parseInt(secondString));
return `${hour}:${minute}:${second}`;
}
return `${hour}:${minute}`;
}
function getLocaleHourCycle(locale) {
const formatter = createLocaleDateTimeFormatter(locale);
const parts = formatter.formatToParts(new Date(Date.UTC(0, 0, 0, 0, 0, 0)));
return getLocalizedTimePart("meridiem", parts) ? "12" : "24";
}
function getLocalizedTimePart(part, parts) {
var _a, _b, _c, _d;
if (!part || !parts) {
return null;
}
if (part === "hourSuffix") {
const hourIndex = parts.indexOf(parts.find(({ type }) => type === "hour"));
const minuteIndex = parts.indexOf(parts.find(({ type }) => type === "minute"));
const hourSuffix = parts[hourIndex + 1];
return hourSuffix && hourSuffix.type === "literal" && minuteIndex - hourIndex === 2
? ((_a = hourSuffix.value) === null || _a === void 0 ? void 0 : _a.trim()) || null
: null;
}
if (part === "minuteSuffix") {
const minuteIndex = parts.indexOf(parts.find(({ type }) => type === "minute"));
const secondIndex = parts.indexOf(parts.find(({ type }) => type === "second"));
const minuteSuffix = parts[minuteIndex + 1];
return minuteSuffix && minuteSuffix.type === "literal" && secondIndex - minuteIndex === 2
? ((_b = minuteSuffix.value) === null || _b === void 0 ? void 0 : _b.trim()) || null
: null;
}
if (part === "secondSuffix") {
const secondIndex = parts.indexOf(parts.find(({ type }) => type === "second"));
const secondSuffix = parts[secondIndex + 1];
return secondSuffix && secondSuffix.type === "literal" ? ((_c = secondSuffix.value) === null || _c === void 0 ? void 0 : _c.trim()) || null : null;
}
return ((_d = parts.find(({ type }) => (part == "meridiem" ? type === "dayPeriod" : type === part))) === null || _d === void 0 ? void 0 : _d.value) || null;
}
function getMeridiem(hour) {
if (!isValidNumber(hour)) {
return null;
}
const hourAsNumber = parseInt(hour);
return hourAsNumber >= 0 && hourAsNumber <= 11 ? "AM" : "PM";
}
function isValidTime(value) {
if (!value || value.startsWith(":") || value.endsWith(":")) {
return false;
}
const splitValue = value.split(":");
const validLength = splitValue.length > 1 && splitValue.length < 4;
if (!validLength) {
return false;
}
const [hour, minute, second] = splitValue;
const hourAsNumber = parseInt(splitValue[0]);
const minuteAsNumber = parseInt(splitValue[1]);
const secondAsNumber = parseInt(splitValue[2]);
const hourValid = isValidNumber(hour) && hourAsNumber >= 0 && hourAsNumber < 24;
const minuteValid = isValidNumber(minute) && minuteAsNumber >= 0 && minuteAsNumber < 60;
const secondValid = isValidNumber(second) && secondAsNumber >= 0 && secondAsNumber < 60;
if ((hourValid && minuteValid && !second) || (hourValid && minuteValid && secondValid)) {
return true;
}
}
function isValidTimePart(value, part) {
if (part === "meridiem") {
return value === "AM" || value === "PM";
}
if (!isValidNumber(value)) {
return false;
}
const valueAsNumber = Number(value);
return part === "hour" ? valueAsNumber >= 0 && valueAsNumber < 24 : valueAsNumber >= 0 && valueAsNumber < 60;
}
function localizeTimePart(value, part, locale) {
if (!isValidTimePart(value, part)) {
return;
}
const valueAsNumber = parseInt(value);
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));
if (!date) {
return;
}
const formatter = createLocaleDateTimeFormatter(locale);
const parts = formatter.formatToParts(date);
return getLocalizedTimePart(part, parts);
}
function localizeTimeString(value, locale = "en", includeSeconds = true) {
if (!isValidTime(value)) {
return null;
}
const { hour, minute, second = "0" } = parseTimeString(value);
const dateFromTimeString = new Date(Date.UTC(0, 0, 0, parseInt(hour), parseInt(minute), parseInt(second)));
const formatter = createLocaleDateTimeFormatter(locale, includeSeconds);
return (formatter === null || formatter === void 0 ? void 0 : formatter.format(dateFromTimeString)) || null;
}
function localizeTimeStringToParts(value, locale = "en") {
if (!isValidTime(value)) {
return null;
}
const { hour, minute, second = "0" } = parseTimeString(value);
const dateFromTimeString = new Date(Date.UTC(0, 0, 0, parseInt(hour), parseInt(minute), parseInt(second)));
if (dateFromTimeString) {
const formatter = createLocaleDateTimeFormatter(locale);
const parts = formatter.formatToParts(dateFromTimeString);
return {
localizedHour: getLocalizedTimePart("hour", parts),
localizedHourSuffix: getLocalizedTimePart("hourSuffix", parts),
localizedMinute: getLocalizedTimePart("minute", parts),
localizedMinuteSuffix: getLocalizedTimePart("minuteSuffix", parts),
localizedSecond: getLocalizedTimePart("second", parts),
localizedSecondSuffix: getLocalizedTimePart("secondSuffix", parts),
localizedMeridiem: getLocalizedTimePart("meridiem", parts)
};
}
return null;
}
function getTimeParts(value, locale = "en") {
if (!isValidTime(value)) {
return null;
}
const { hour, minute, second = "0" } = parseTimeString(value);
const dateFromTimeString = new Date(Date.UTC(0, 0, 0, parseInt(hour), parseInt(minute), parseInt(second)));
if (dateFromTimeString) {
const formatter = createLocaleDateTimeFormatter(locale);
const parts = formatter.formatToParts(dateFromTimeString);
return parts;
}
return null;
}
function parseTimeString(value) {
if (isValidTime(value)) {
const [hour, minute, second] = value.split(":");
return {
hour,
minute,
second
};
}
return {
hour: null,
minute: null,
second: null
};
}
const CSS = {
button: "button",
buttonBottomLeft: "button--bottom-left",
buttonBottomRight: "button--bottom-right",
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",
delimiter: "delimiter",
hour: "hour",
input: "input",
meridiem: "meridiem",
minute: "minute",
second: "second",
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 TEXT = {
hour: "Hour",
hourDown: "Decrease hour",
hourUp: "Increase hour",
meridiem: "AM/PM",
meridiemDown: "Decrease AM/PM",
meridiemUp: "Increase AM/PM",
minute: "Minute",
minuteDown: "Decrease minute",
minuteUp: "Increase minute",
second: "Second",
secondDown: "Decrease second",
secondUp: "Increase second"
};
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}";
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
const TimePicker = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
constructor() {
super();
this.__registerHost();
this.__attachShadow();
this.calciteTimePickerBlur = createEvent(this, "calciteTimePickerBlur", 7);
this.calciteTimePickerChange = createEvent(this, "calciteTimePickerChange", 7);
this.calciteTimePickerFocus = createEvent(this, "calciteTimePickerFocus", 7);
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
/** aria-label for the hour input
* @default "Hour"
*/
this.intlHour = TEXT.hour;
/** aria-label for the hour down button
* @default "Decrease hour"
*/
this.intlHourDown = TEXT.hourDown;
/** aria-label for the hour up button
* @default "Increase hour"
*/
this.intlHourUp = TEXT.hourUp;
/** aria-label for the meridiem (am/pm) input
* @default "AM/PM"
*/
this.intlMeridiem = TEXT.meridiem;
/** aria-label for the meridiem (am/pm) down button
* @default "Decrease AM/PM"
*/
this.intlMeridiemDown = TEXT.meridiemDown;
/** aria-label for the meridiem (am/pm) up button
* @default "Increase AM/PM"
*/
this.intlMeridiemUp = TEXT.meridiemUp;
/** aria-label for the minute input
* @default "Minute"
*/
this.intlMinute = TEXT.minute;
/** aria-label for the minute down button
* @default "Decrease minute"
*/
this.intlMinuteDown = TEXT.minuteDown;
/** aria-label for the minute up button
* @default "Increase minute"
*/
this.intlMinuteUp = TEXT.minuteUp;
/** aria-label for the second input
* @default "Second"
*/
this.intlSecond = TEXT.second;
/** aria-label for the second down button
* @default "Decrease second"
*/
this.intlSecondDown = TEXT.secondDown;
/** aria-label for the second up button
* @default "Increase second"
*/
this.intlSecondUp = TEXT.secondUp;
/**
* BCP 47 language tag for desired language and country format
* @internal
*/
this.locale = document.documentElement.lang || navigator.language || "en";
/** The scale (size) of the time picker */
this.scale = "m";
/** number (seconds) that specifies the granularity that the value must adhere to */
this.step = 60;
/** The selected time in UTC (always 24-hour format) */
this.value = null;
this.showSecond = this.step < 60;
this.decrementHour = () => {
const newHour = !this.hour ? 0 : this.hour === "00" ? 23 : parseInt(this.hour) - 1;
this.setValuePart("hour", newHour);
};
this.decrementMeridiem = () => {
const newMeridiem = this.meridiem === "PM" ? "AM" : "PM";
this.setValuePart("meridiem", newMeridiem);
};
this.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);
};
this.decrementMinute = () => {
this.decrementMinuteOrSecond("minute");
};
this.decrementSecond = () => {
this.decrementMinuteOrSecond("second");
};
this.focusHandler = (event) => {
this.activeEl = event.currentTarget;
};
this.hourDownButtonKeyDownHandler = (event) => {
if (this.buttonActivated(event)) {
this.decrementHour();
}
};
this.hourKeyDownHandler = (event) => {
const key = event.key;
if (numberKeys.includes(key)) {
const keyAsNumber = parseInt(key);
let newHour;
if (isValidNumber(this.hour)) {
switch (this.hourCycle) {
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 " ":
case "Spacebar":
event.preventDefault();
break;
}
}
};
this.hourUpButtonKeyDownHandler = (event) => {
if (this.buttonActivated(event)) {
this.incrementHour();
}
};
this.incrementMeridiem = () => {
const newMeridiem = this.meridiem === "AM" ? "PM" : "AM";
this.setValuePart("meridiem", newMeridiem);
};
this.incrementHour = () => {
const newHour = isValidNumber(this.hour)
? this.hour === "23"
? 0
: parseInt(this.hour) + 1
: 1;
this.setValuePart("hour", newHour);
};
this.incrementMinuteOrSecond = (key) => {
const newValue = isValidNumber(this[key])
? this[key] === "59"
? 0
: parseInt(this[key]) + 1
: 0;
this.setValuePart(key, newValue);
};
this.incrementMinute = () => {
this.incrementMinuteOrSecond("minute");
};
this.incrementSecond = () => {
this.incrementMinuteOrSecond("second");
};
this.meridiemDownButtonKeyDownHandler = (event) => {
if (this.buttonActivated(event)) {
this.decrementMeridiem();
}
};
this.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 " ":
case "Spacebar":
event.preventDefault();
break;
}
};
this.meridiemUpButtonKeyDownHandler = (event) => {
if (this.buttonActivated(event)) {
this.incrementMeridiem();
}
};
this.minuteDownButtonKeyDownHandler = (event) => {
if (this.buttonActivated(event)) {
this.decrementMinute();
}
};
this.minuteKeyDownHandler = (event) => {
const key = event.key;
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 " ":
case "Spacebar":
event.preventDefault();
break;
}
}
};
this.minuteUpButtonKeyDownHandler = (event) => {
if (this.buttonActivated(event)) {
this.incrementMinute();
}
};
this.secondDownButtonKeyDownHandler = (event) => {
if (this.buttonActivated(event)) {
this.decrementSecond();
}
};
this.secondKeyDownHandler = (event) => {
const key = event.key;
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 " ":
case "Spacebar":
event.preventDefault();
break;
}
}
};
this.secondUpButtonKeyDownHandler = (event) => {
if (this.buttonActivated(event)) {
this.incrementSecond();
}
};
this.setHourEl = (el) => (this.hourEl = el);
this.setMeridiemEl = (el) => (this.meridiemEl = el);
this.setMinuteEl = (el) => (this.minuteEl = el);
this.setSecondEl = (el) => (this.secondEl = el);
this.setValue = (value, emit = true) => {
if (isValidTime(value)) {
const { hour, minute, second } = parseTimeString(value);
const { localizedHour, localizedHourSuffix, localizedMinute, localizedMinuteSuffix, localizedSecond, localizedSecondSuffix, localizedMeridiem } = localizeTimeStringToParts(value, this.locale);
this.localizedHour = localizedHour;
this.localizedHourSuffix = localizedHourSuffix;
this.localizedMinute = localizedMinute;
this.localizedMinuteSuffix = localizedMinuteSuffix;
this.localizedSecond = localizedSecond;
this.localizedSecondSuffix = localizedSecondSuffix;
this.hour = hour;
this.minute = minute;
this.second = second;
if (localizedMeridiem) {
this.localizedMeridiem = localizedMeridiem;
this.meridiem = getMeridiem(this.hour);
const formatParts = getTimeParts(value, this.locale);
this.meridiemOrder = this.getMeridiemOrder(formatParts);
}
}
else {
this.hour = null;
this.localizedHour = null;
this.localizedHourSuffix = null;
this.localizedMeridiem = null;
this.localizedMinute = null;
this.localizedMinuteSuffix = null;
this.localizedSecond = null;
this.localizedSecondSuffix = null;
this.meridiem = null;
this.minute = null;
this.second = null;
this.value = null;
}
if (emit) {
this.calciteTimePickerChange.emit();
}
};
this.setValuePart = (key, value, emit = true) => {
var _a;
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(this.hour, "hour", this.locale);
}
}
else {
this[key] = typeof value === "number" ? formatTimePart(value) : value;
this[`localized${capitalize(key)}`] = localizeTimePart(this[key], key, this.locale);
}
if (this.hour && this.minute) {
const showSeconds = this.second && this.showSecond;
this.value = `${this.hour}:${this.minute}:${showSeconds ? this.second : "00"}`;
}
else {
this.value = null;
}
this.localizedMeridiem = this.value
? ((_a = localizeTimeStringToParts(this.value, this.locale)) === null || _a === void 0 ? void 0 : _a.localizedMeridiem) || null
: localizeTimePart(this.meridiem, "meridiem", this.locale);
if (emit) {
this.calciteTimePickerChange.emit();
}
};
}
localeWatcher(newLocale) {
this.hourCycle = getLocaleHourCycle(newLocale);
this.setValue(this.value, false);
}
valueWatcher(newValue) {
this.setValue(newValue, false);
}
hourChanged(newHour) {
if (this.meridiem && isValidNumber(newHour)) {
this.setValuePart("meridiem", getMeridiem(newHour));
}
}
//--------------------------------------------------------------------------
//
// Event Listeners
//
//--------------------------------------------------------------------------
hostBlurHandler() {
this.calciteTimePickerBlur.emit();
}
hostFocusHandler() {
this.calciteTimePickerFocus.emit();
}
keyDownHandler(event) {
const key = event.key;
switch (this.activeEl) {
case this.hourEl:
if (key === "ArrowRight") {
this.setFocus("minute");
}
break;
case this.minuteEl:
switch (key) {
case "ArrowLeft":
this.setFocus("hour");
break;
case "ArrowRight":
if (this.step !== 60) {
this.setFocus("second");
}
else if (this.hourCycle === "12") {
this.setFocus("meridiem");
}
break;
}
break;
case this.secondEl:
switch (key) {
case "ArrowLeft":
this.setFocus("minute");
break;
case "ArrowRight":
if (this.hourCycle === "12") {
this.setFocus("meridiem");
}
break;
}
break;
case this.meridiemEl:
switch (key) {
case "ArrowLeft":
if (this.step !== 60) {
this.setFocus("second");
}
else {
this.setFocus("minute");
}
break;
}
break;
}
}
//--------------------------------------------------------------------------
//
// Public Methods
//
//--------------------------------------------------------------------------
/** Sets focus on the component. */
async setFocus(target) {
var _a;
(_a = this[`${target || "hour"}El`]) === null || _a === void 0 ? void 0 : _a.focus();
}
// --------------------------------------------------------------------------
//
// Private Methods
//
// --------------------------------------------------------------------------
buttonActivated(event) {
const key = event.key;
if (key === " ") {
event.preventDefault();
}
return isActivationKey(key);
}
getMeridiemOrder(formatParts) {
const isRTLKind = this.locale === "ar" || this.locale === "he";
if (formatParts && !isRTLKind) {
const index = formatParts.findIndex((parts) => {
return parts.value === this.localizedMeridiem;
});
return index;
}
return 0;
}
// --------------------------------------------------------------------------
//
// Lifecycle
//
// --------------------------------------------------------------------------
connectedCallback() {
this.setValue(this.value, false);
this.hourCycle = getLocaleHourCycle(this.locale);
}
// --------------------------------------------------------------------------
//
// Render Methods
//
// --------------------------------------------------------------------------
render() {
const hourIsNumber = isValidNumber(this.hour);
const iconScale = this.scale === "s" || this.scale === "m" ? "s" : "m";
const minuteIsNumber = isValidNumber(this.minute);
const secondIsNumber = isValidNumber(this.second);
const showMeridiem = this.hourCycle === "12";
return (h("div", { class: {
[CSS.timePicker]: true,
[CSS.showMeridiem]: showMeridiem,
[CSS.showSecond]: this.showSecond,
[CSS[`scale-${this.scale}`]]: true
}, dir: "ltr" }, h("div", { class: CSS.column, role: "group" }, h("span", { "aria-label": this.intlHourUp, class: {
[CSS.button]: true,
[CSS.buttonHourUp]: true,
[CSS.buttonTopLeft]: true
}, 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: {
[CSS.input]: true,
[CSS.hour]: true
}, onFocus: this.focusHandler, onKeyDown: this.hourKeyDownHandler, ref: this.setHourEl, role: "spinbutton", tabIndex: 0 }, this.localizedHour || "--"), h("span", { "aria-label": this.intlHourDown, class: {
[CSS.button]: true,
[CSS.buttonHourDown]: true,
[CSS.buttonBottomLeft]: true
}, 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: {
[CSS.button]: true,
[CSS.buttonMinuteUp]: true
}, 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: {
[CSS.input]: true,
[CSS.minute]: true
}, onFocus: this.focusHandler, onKeyDown: this.minuteKeyDownHandler, ref: this.setMinuteEl, role: "spinbutton", tabIndex: 0 }, this.localizedMinute || "--"), h("span", { "aria-label": this.intlMinuteDown, class: {
[CSS.button]: true,
[CSS.buttonMinuteDown]: true
}, 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: {
[CSS.button]: true,
[CSS.buttonSecondUp]: true
}, 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: {
[CSS.input]: true,
[CSS.second]: true
}, onFocus: this.focusHandler, onKeyDown: this.secondKeyDownHandler, ref: this.setSecondEl, role: "spinbutton", tabIndex: 0 }, this.localizedSecond || "--"), h("span", { "aria-label": this.intlSecondDown, class: {
[CSS.button]: true,
[CSS.buttonSecondDown]: true
}, onClick: this.decrementSecond, onKeyDown: this.secondDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-down", scale: iconScale })))), this.localizedSecondSuffix && (h("span", { class: CSS.delimiter }, this.localizedSecondSuffix)), showMeridiem && (h("div", { class: {
[CSS.column]: true,
[CSS.meridiemStart]: this.meridiemOrder === 0
}, role: "group" }, h("span", { "aria-label": this.intlMeridiemUp, class: {
[CSS.button]: true,
[CSS.buttonMeridiemUp]: true,
[CSS.buttonTopRight]: true
}, 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: {
[CSS.input]: true,
[CSS.meridiem]: true
}, onFocus: this.focusHandler, onKeyDown: this.meridiemKeyDownHandler, ref: this.setMeridiemEl, role: "spinbutton", tabIndex: 0 }, this.localizedMeridiem || "--"), h("span", { "aria-label": this.intlMeridiemDown, class: {
[CSS.button]: true,
[CSS.buttonMeridiemDown]: true,
[CSS.buttonBottomRight]: true
}, onClick: this.decrementMeridiem, onKeyDown: this.meridiemDownButtonKeyDownHandler, role: "button", tabIndex: -1 }, h("calcite-icon", { icon: "chevron-down", scale: iconScale }))))));
}
get el() { return this; }
static get watchers() { return {
"locale": ["localeWatcher"],
"value": ["valueWatcher"],
"hour": ["hourChanged"]
}; }
static get style() { return timePickerCss; }
}, [1, "calcite-time-picker", {
"intlHour": [1, "intl-hour"],
"intlHourDown": [1, "intl-hour-down"],
"intlHourUp": [1, "intl-hour-up"],
"intlMeridiem": [1, "intl-meridiem"],
"intlMeridiemDown": [1, "intl-meridiem-down"],
"intlMeridiemUp": [1, "intl-meridiem-up"],
"intlMinute": [1, "intl-minute"],
"intlMinuteDown": [1, "intl-minute-down"],
"intlMinuteUp": [1, "intl-minute-up"],
"intlSecond": [1, "intl-second"],
"intlSecondDown": [1, "intl-second-down"],
"intlSecondUp": [1, "intl-second-up"],
"locale": [1025, "lang"],
"scale": [1],
"step": [2],
"value": [1025],
"hour": [32],
"hourCycle": [32],
"localizedHour": [32],
"localizedHourSuffix": [32],
"localizedMeridiem": [32],
"localizedMinute": [32],
"localizedMinuteSuffix": [32],
"localizedSecond": [32],
"localizedSecondSuffix": [32],
"meridiem": [32],
"minute": [32],
"second": [32],
"showSecond": [32],
"setFocus": [64]
}, [[0, "blur", "hostBlurHandler"], [0, "focus", "hostFocusHandler"], [0, "keydown", "keyDownHandler"]]]);
function defineCustomElement() {
if (typeof customElements === "undefined") {
return;
}
const components = ["calcite-time-picker", "calcite-icon"];
components.forEach(tagName => { switch (tagName) {
case "calcite-time-picker":
if (!customElements.get(tagName)) {
customElements.define(tagName, TimePicker);
}
break;
case "calcite-icon":
if (!customElements.get(tagName)) {
defineCustomElement$1();
}
break;
} });
}
defineCustomElement();
export { TimePicker as T, defineCustomElement as d, formatTimeString as f, isValidTime as i, localizeTimeString as l };