@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
860 lines (859 loc) • 29.3 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.1/LICENSE.txt */
import { toFunction, GenericController } from "@arcgis/lumina/controllers";
import { createEvent } from "@arcgis/lumina";
import { l as localizedTwentyFourHourMeridiems, i as isValidNumber, n as numberStringFormatter, g as getDateTimeFormat, b as getSupportedNumberingSystem } from "./locale.js";
import { d as decimalPlaces, g as getDecimals } from "./math.js";
import { c as capitalizeWord } from "./text.js";
import { n as numberKeys } from "./key.js";
const maxTenthForMinuteAndSecond = 5;
function createLocaleDateTimeFormatter({
locale,
numberingSystem,
includeSeconds,
fractionalSecondDigits,
hour12
}) {
const options = {
hour: "2-digit",
minute: "2-digit",
timeZone: "UTC",
numberingSystem: getSupportedNumberingSystem(numberingSystem)
};
if (typeof hour12 === "boolean") {
options.hour12 = hour12;
}
if (includeSeconds) {
options.second = "2-digit";
if (fractionalSecondDigits) {
options.fractionalSecondDigits = fractionalSecondDigits;
}
}
return getDateTimeFormat(locale, options);
}
function formatFractionalSecond(fractionalSecondAsIntegerString, step) {
return parseFloat(`0.${fractionalSecondAsIntegerString}`).toFixed(decimalPlaces(step)).replace("0.", "");
}
function formatTimePart(number, minLength) {
if (number === null || number === void 0) {
return;
}
const numberAsString = number.toString();
const numberDecimalPlaces = decimalPlaces(number);
if (number < 1 && numberDecimalPlaces > 0 && numberDecimalPlaces < 4) {
const fractionalDigits = numberAsString.replace("0.", "");
if (!minLength || fractionalDigits.length === minLength) {
return fractionalDigits;
}
if (fractionalDigits.length < minLength) {
return fractionalDigits.padEnd(minLength, "0");
}
return fractionalDigits;
}
if (number >= 0 && number < 10) {
return numberAsString.padStart(2, "0");
}
if (number >= 10) {
return numberAsString;
}
}
function fractionalSecondPartToMilliseconds(fractionalSecondPart) {
return parseInt((parseFloat(`0.${fractionalSecondPart}`) / 1e-3).toFixed(3));
}
function getLocaleHourFormat(locale) {
const options = { locale };
if (locale === "mk") {
options.hour12 = false;
} else if (locale.toLowerCase() === "es-mx") {
options.hour12 = true;
}
const formatter = createLocaleDateTimeFormatter(options);
const parts = formatter.formatToParts(new Date(Date.UTC(0, 0, 0, 0, 0, 0)));
return parts.find(({ type }) => type === "dayPeriod")?.value ? "12" : "24";
}
function getLocalizedMeridiem({
locale,
meridiem,
parts: fromParts
}) {
const localesWithBrowserBugs = ["he", "bs", "mk"];
let localizedMeridiem;
if (fromParts) {
localizedMeridiem = fromParts.find(({ type }) => type === "dayPeriod")?.value || null;
if (locale && localesWithBrowserBugs.includes(locale)) {
const localeData = localizedTwentyFourHourMeridiems.get(locale);
if (localizedMeridiem === "PM") {
localizedMeridiem = localeData.pm;
}
if (localizedMeridiem === "AM") {
localizedMeridiem = localeData.am;
}
}
} else if (meridiem) {
if (localesWithBrowserBugs.includes(locale)) {
const localeData = localizedTwentyFourHourMeridiems.get(locale);
localizedMeridiem = meridiem === "PM" ? localeData.pm : localeData.am;
} else {
const formatter = createLocaleDateTimeFormatter({ locale, hour12: true });
const arbitraryAMHour = 6;
const arbitraryPMHour = 18;
const dateWithHourBasedOnMeridiem = new Date(
Date.UTC(0, 0, 0, meridiem === "AM" ? arbitraryAMHour : arbitraryPMHour, 0)
);
const parts = formatter.formatToParts(dateWithHourBasedOnMeridiem);
localizedMeridiem = parts.find(({ type }) => type === "dayPeriod")?.value || null;
}
}
return localizedMeridiem;
}
function getLocalizedDecimalSeparator(locale, numberingSystem) {
numberStringFormatter.numberFormatOptions = {
locale,
numberingSystem
};
return numberStringFormatter.localize("1.1").split("")[1];
}
function getLocalizedTimePartSuffix({
hour12,
locale,
numberingSystem = "latn",
part,
step
}) {
const formatter = createLocaleDateTimeFormatter({ hour12, includeSeconds: step < 60, locale, numberingSystem });
const parts = formatter.formatToParts(new Date(Date.UTC(0, 0, 0, 0, 0, 0)));
return getLocalizedTimePart(`${part}Suffix`, parts, locale);
}
function getLocalizedTimePart(part, parts, locale = "en") {
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?.type === "literal" && minuteIndex - hourIndex === 2 ? hourSuffix.value || null : null;
}
if (part === "minuteSuffix") {
const minuteIndex = parts.indexOf(parts.find(({ type }) => type === "minute"));
const minuteSuffix = parts[minuteIndex + 1];
return minuteSuffix?.type === "literal" ? minuteSuffix.value || null : null;
}
if (part === "secondSuffix") {
let secondSuffixPart;
const fractionalSecondIndex = parts.indexOf(parts.find(({ type }) => type === "fractionalSecond"));
if (fractionalSecondIndex !== -1) {
secondSuffixPart = parts[fractionalSecondIndex + 1];
} else {
const secondIndex = parts.indexOf(parts.find(({ type }) => type === "second"));
secondSuffixPart = parts[secondIndex + 1];
}
return secondSuffixPart?.type === "literal" && secondSuffixPart.value || null;
}
if (part === "meridiem") {
const meridiemFromBrowser = parts.find(({ type }) => type === "dayPeriod")?.value || null;
if (meridiemFromBrowser) {
return getLocalizedMeridiem({ locale, parts });
}
}
return parts.find(({ type }) => type === part)?.value || null;
}
function getMeridiem(hour) {
if (!isValidNumber(hour)) {
return null;
}
const hourAsNumber = parseInt(hour);
return hourAsNumber >= 0 && hourAsNumber <= 11 ? "AM" : "PM";
}
function getMeridiemOrder(locale) {
const formatter = new Intl.DateTimeFormat(locale, {
hour: "2-digit",
hour12: true,
minute: "2-digit",
timeZone: "UTC"
});
const timeParts = formatter.formatToParts(new Date(Date.UTC(0, 0, 0, 0, 0)));
return timeParts.findIndex((value) => value.type === "dayPeriod");
}
function isValidTime(value) {
const isString = typeof value === "string";
if (!value || isString && (value.startsWith(":") || value.endsWith(":")) || !isString && (!value.hour || !value.minute)) {
return false;
}
let hour;
let minute;
let second;
if (isString) {
[hour, minute, second] = value.split(":");
} else {
({ hour, minute, second } = value);
}
if (!hour || !minute) {
return false;
}
const hourAsNumber = parseInt(hour);
const minuteAsNumber = parseInt(minute);
const secondAsNumber = parseInt(second);
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;
}
return false;
}
function isValidTimePart(value, part) {
if (part === "meridiem") {
return value === "AM" || value === "PM";
}
if (!isValidNumber(value)) {
return false;
}
const valueAsNumber = Number(value);
const isZeroOrGreater = valueAsNumber >= 0;
const isLessThanMaxHour = valueAsNumber < 24;
const isLessThanMaxSecond = valueAsNumber < 60;
const isLessThanMaxFractionalSecond = valueAsNumber <= 999;
if (part === "hour") {
return isZeroOrGreater && isLessThanMaxHour;
}
if (part === "fractionalSecond") {
return isZeroOrGreater && isLessThanMaxFractionalSecond;
}
return isZeroOrGreater && isLessThanMaxSecond;
}
function localizeTimePart({
value,
part,
locale,
numberingSystem = "latn",
hour12
}) {
if (!isValidTimePart(value, part)) {
return;
}
if (part === "fractionalSecond") {
const localizedDecimalSeparator = getLocalizedDecimalSeparator(locale, numberingSystem);
let localizedFractionalSecond = null;
if (value) {
numberStringFormatter.numberFormatOptions = {
locale,
numberingSystem
};
const localizedZero = numberStringFormatter.localize("0");
if (parseInt(value) === 0) {
localizedFractionalSecond = "".padStart(value.length, localizedZero);
} else {
localizedFractionalSecond = numberStringFormatter.localize(`0.${value}`).replace(`${localizedZero}${localizedDecimalSeparator}`, "");
if (localizedFractionalSecond.length < value.length) {
localizedFractionalSecond = localizedFractionalSecond.padEnd(value.length, localizedZero);
}
}
}
return localizedFractionalSecond;
}
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 includeSeconds = ["second", "fractionalSecond"].includes(part);
const formatter = createLocaleDateTimeFormatter({ hour12, includeSeconds, locale, numberingSystem });
const parts = formatter.formatToParts(date);
return getLocalizedTimePart(part, parts, locale);
}
function localizeTimeString({
hour12,
locale,
numberingSystem = "latn",
parts: toParts = false,
step,
value
}) {
if (!isValidTime(value)) {
return null;
}
const { hour, minute, second = "0", fractionalSecond } = parseTimeString(value, step);
const includeSeconds = step < 60;
const dateFromTimeString = new Date(
Date.UTC(
0,
0,
0,
parseInt(hour),
parseInt(minute),
includeSeconds && parseInt(second),
includeSeconds && fractionalSecond && fractionalSecondPartToMilliseconds(fractionalSecond)
)
);
const formatter = createLocaleDateTimeFormatter({
fractionalSecondDigits: decimalPlaces(step),
hour12,
includeSeconds,
locale,
numberingSystem
});
if (toParts) {
const parts = formatter.formatToParts(dateFromTimeString);
return {
hour: getLocalizedTimePart("hour", parts),
hourSuffix: getLocalizedTimePart("hourSuffix", parts),
minute: getLocalizedTimePart("minute", parts),
minuteSuffix: getLocalizedTimePart("minuteSuffix", parts),
second: getLocalizedTimePart("second", parts),
decimalSeparator: getLocalizedDecimalSeparator(locale, numberingSystem),
fractionalSecond: getLocalizedTimePart("fractionalSecond", parts),
secondSuffix: locale !== "bg" && getLocalizedTimePart("secondSuffix", parts),
meridiem: getLocalizedTimePart("meridiem", parts, locale)
};
} else {
let result = formatter.format(dateFromTimeString) || null;
if (!toParts && typeof result === "string" && locale === "bg" && result && result.includes(" ч.")) {
result = result.replaceAll(" ч.", "");
}
if (["he", "bs", "mk"].includes(locale)) {
const localeData = localizedTwentyFourHourMeridiems.get(locale);
if (result.includes("AM")) {
result = result.replaceAll("AM", localeData.am);
} else if (result.includes("PM")) {
result = result.replaceAll("PM", localeData.pm);
}
if (locale !== "he" && result.indexOf(".") !== result.length - 1) {
result = result.replace(".", ",");
}
}
return result;
}
}
function parseTimeString(value, step) {
if (isValidTime(value)) {
const [hour, minute, secondDecimal] = value.split(":");
let second = secondDecimal;
let fractionalSecond = null;
if (secondDecimal?.includes(".")) {
[second, fractionalSecond] = secondDecimal.split(".");
}
if (step) {
fractionalSecond = formatFractionalSecond(fractionalSecond, step);
}
return {
fractionalSecond,
hour,
minute,
second
};
}
return {
fractionalSecond: null,
hour: null,
minute: null,
second: null
};
}
function toISOTimeString(value, step = 60) {
if (!isValidTime(value)) {
return null;
}
let hour;
let minute;
let second;
let secondDecimal;
let fractionalSecond;
let isoTimeString = null;
if (typeof value === "string") {
[hour, minute, secondDecimal] = value.split(":");
[second, fractionalSecond] = secondDecimal?.split(".") || ["0"];
} else {
hour = value.hour;
minute = value.minute;
second = value.second;
fractionalSecond = value.fractionalSecond;
}
if (hour && minute) {
isoTimeString = `${formatTimePart(parseInt(hour))}:${formatTimePart(parseInt(minute))}`;
if (step < 60) {
isoTimeString += `:${formatTimePart(parseInt(second || "0"))}`;
if (step < 1) {
isoTimeString += `.${formatFractionalSecond(fractionalSecond || "0", step)}`;
}
}
}
return isoTimeString;
}
class TimeController extends GenericController {
constructor() {
super(...arguments);
this.localizedDecimalSeparator = ".";
this.userChangedValue = false;
this.handleHourKeyDownEvent = (event) => {
const key = event.key;
if (numberKeys.includes(key)) {
const keyAsNumber = parseInt(key);
let newHour;
if (isValidNumber(this.hour)) {
switch (this.hourFormat) {
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":
event.preventDefault();
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.handleMinuteKeyDownEvent = (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":
event.preventDefault();
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.handleSecondKeyDownEvent = (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":
event.preventDefault();
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.handleFractionalSecondKeyDownEvent = (event) => {
const { key } = event;
if (numberKeys.includes(key)) {
const stepPrecision = decimalPlaces(this.component.step);
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":
event.preventDefault();
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;
}
}
};
this.handleMeridiemKeyDownEvent = (event) => {
switch (event.key) {
case "a":
this.setValuePart("meridiem", "AM");
break;
case "p":
this.setValuePart("meridiem", "PM");
break;
case "Backspace":
case "Delete":
event.preventDefault();
this.setValuePart("meridiem");
break;
case "ArrowUp":
event.preventDefault();
this.toggleMeridiem("up");
break;
case "ArrowDown":
event.preventDefault();
this.toggleMeridiem("down");
break;
case " ":
case "Spacebar":
event.preventDefault();
break;
}
};
this.calciteTimeChange = createEvent();
}
//#endregion
//#region Public Methods
decrementHour() {
const newHour = !this.hour ? 0 : this.hour === "00" ? 23 : parseInt(this.hour) - 1;
this.setValuePart("hour", newHour);
}
decrementMinute() {
this.decrementMinuteOrSecond("minute");
}
decrementSecond() {
this.decrementMinuteOrSecond("second");
}
incrementHour() {
const newHour = isValidNumber(this.hour) ? this.hour === "23" ? 0 : parseInt(this.hour) + 1 : 1;
this.setValuePart("hour", newHour);
}
incrementMinute() {
this.incrementMinuteOrSecond("minute");
}
incrementSecond() {
this.incrementMinuteOrSecond("second");
}
nudgeFractionalSecond(direction) {
const stepDecimal = getDecimals(this.component.step);
const stepPrecision = decimalPlaces(this.component.step);
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);
}
toggleMeridiem(direction) {
let newMeridiem;
if (!this.meridiem) {
newMeridiem = direction === "down" ? "PM" : "AM";
} else {
newMeridiem = this.meridiem === "AM" ? "PM" : "AM";
}
this.setValuePart("meridiem", newMeridiem);
}
//#endregion
//#region Private Methods
hostConnected() {
this.setHourFormat();
this.setMeridiemOrder();
this.setValue(this.component.value);
}
hostUpdate(changes) {
let updateHourFormat = false;
let updateMeridiemOrder = false;
let updateValue = false;
if (changes.has("hourFormat")) {
updateHourFormat = true;
updateValue = true;
}
if (changes.has("messages") && changes.get("messages")?._lang !== this.component.messages._lang) {
updateHourFormat = true;
updateMeridiemOrder = true;
updateValue = true;
}
if (changes.has("numberingSystem")) {
updateValue = true;
}
if (changes.has("step")) {
const oldStep = this.component.step;
const newStep = changes.get("step");
if (oldStep >= 60 && newStep > 0 && newStep < 60 || newStep >= 60 && oldStep > 0 && oldStep < 60) {
updateValue = true;
}
}
if (updateHourFormat) {
this.setHourFormat();
}
if (updateMeridiemOrder) {
this.setMeridiemOrder();
}
if (updateValue) {
this.setValue(this.component.value);
}
this.userChangedValue = false;
}
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);
}
incrementMinuteOrSecond(key) {
const newValue = isValidNumber(this[key]) ? this[key] === "59" ? 0 : parseInt(this[key]) + 1 : 0;
this.setValuePart(key, newValue);
}
setHourFormat() {
const { hourFormat, messages } = this.component;
this.hourFormat = hourFormat === "user" ? getLocaleHourFormat(messages._lang) : hourFormat;
}
setMeridiemOrder() {
const { messages } = this.component;
this.meridiemOrder = getMeridiemOrder(messages._lang);
}
setValue(value, userChangedValue = false) {
const { messages, numberingSystem, step, value: previousValue } = this.component;
const locale = messages._lang;
const hour12 = this.hourFormat === "12";
const newValue = toISOTimeString(value, step);
if (isValidTime(value)) {
const { hour, minute, second, fractionalSecond } = parseTimeString(newValue, step);
const {
hour: localizedHour,
hourSuffix: localizedHourSuffix,
minute: localizedMinute,
minuteSuffix: localizedMinuteSuffix,
second: localizedSecond,
secondSuffix: localizedSecondSuffix,
decimalSeparator: localizedDecimalSeparator,
fractionalSecond: localizedFractionalSecond,
meridiem: localizedMeridiem
} = localizeTimeString({
hour12,
locale,
numberingSystem,
parts: true,
step,
value: newValue
});
this.hour = hour;
this.minute = minute;
this.second = second;
this.fractionalSecond = 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.meridiem = getMeridiem(this.hour);
this.localizedMeridiem = localizedMeridiem;
}
} else {
this.hour = null;
this.minute = null;
this.second = null;
this.fractionalSecond = null;
this.meridiem = null;
this.localizedHour = null;
this.localizedHourSuffix = getLocalizedTimePartSuffix({ hour12, part: "hour", locale, numberingSystem, step });
this.localizedMinute = null;
this.localizedMinuteSuffix = getLocalizedTimePartSuffix({
hour12,
part: "minute",
locale,
numberingSystem,
step
});
this.localizedSecond = null;
this.localizedDecimalSeparator = getLocalizedDecimalSeparator(locale, numberingSystem);
this.localizedFractionalSecond = null;
this.localizedSecondSuffix = getLocalizedTimePartSuffix({
hour12,
part: "second",
locale,
numberingSystem,
step
});
this.localizedMeridiem = null;
}
if (newValue !== previousValue) {
this.userChangedValue = userChangedValue;
this.component.value = newValue ?? "";
} else {
this.component.requestUpdate();
}
}
setValuePart(key, value) {
const { hourFormat } = this;
const { messages, numberingSystem, step } = this.component;
const locale = messages._lang;
const hour12 = hourFormat === "12";
const previousValue = this.component.value;
if (key === "meridiem") {
const oldMeridiem = this.meridiem;
this.meridiem = value;
this.localizedMeridiem = localizeTimePart({
hour12,
locale,
numberingSystem,
part: "meridiem",
value: this.meridiem
});
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;
default:
this.userChangedValue = true;
this.component.value = "";
break;
}
this.localizedHour = localizeTimePart({
hour12,
locale,
numberingSystem,
part: "hour",
value: this.hour
});
}
if (oldMeridiem !== this.meridiem) {
this.component.requestUpdate();
}
} else if (key === "fractionalSecond") {
const oldFractionalSecond = this.fractionalSecond;
const stepPrecision = decimalPlaces(step);
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
});
if (oldFractionalSecond !== this.fractionalSecond) {
this.component.requestUpdate();
}
} else {
const oldValue = this[key];
this[key] = typeof value === "number" ? formatTimePart(value) : value;
this[`localized${capitalizeWord(key)}`] = localizeTimePart({
value: this[key],
part: key,
locale,
numberingSystem,
hour12
});
if (oldValue !== this[key]) {
this.component.requestUpdate();
}
}
const { hour, minute, second, fractionalSecond } = this;
const newValue = toISOTimeString({ hour, minute, second, fractionalSecond }, step);
if (previousValue !== newValue) {
if (key === "hour" && hourFormat === "12") {
this.meridiem = getMeridiem(hour);
this.localizedMeridiem = getLocalizedMeridiem({ locale, meridiem: this.meridiem });
}
this.userChangedValue = true;
this.calciteTimeChange.emit(newValue ?? "");
}
}
//#endregion
}
const useTime = toFunction(TimeController);
export {
useTime as u
};