wix-style-react
Version:
wix-style-react
164 lines • 7.2 kB
JavaScript
import { dateTimeFormat } from 'wix-design-systems-locale-utils';
import { _24hourTimeFormats, _12hourTimeFormats } from './constants';
import { DEFAULT_STEP } from './TimeInput';
const timeRegex = /([下上午오전후ÖS ]{0,})([0-2]?[0-9]{0,2})([:.h ]{0,})([0-5][0-9]{0,2})/;
const validationRegex = /^([下上午오전후ÖS ]{0,})(([0-1]?[0-9]|2[0-3])[^0-9]{0,}([0-5]([0-9]([^0-9]+)?)?)?)?$/;
const fullTimeNoDividerRegex = /([0-2]?[0-9])([0-5][0-9])/;
const _24hour2digitTimeRegex = [
/^([0]?[3-9])([0-5])$/,
/^([2])([4-5])$/,
/^([0])()$/,
];
const _24hour3digitTimeRegex = [/^([0-1][0-9])([0-5])$/, /^([2][0-4])([0-5])$/];
const _24hourTimeRegex = _24hour2digitTimeRegex.concat(_24hour3digitTimeRegex);
const _12hour2digitTimeRegex = [
/^([0]?[2-9])([0-5])$/,
/^([0]?[1])([3-5])$/,
/^([0])([0]?)$/,
];
const _12hour3digitTimeRegex = [/^([0][1-9])([0-5])$/, /^([1-9])([0-5][0-9])$/];
const _12hourTimeRegex = _12hour2digitTimeRegex.concat(_12hour3digitTimeRegex);
export const getFormattedDate = ({ value, timeStyle, locale }) => {
if (!value && value !== 0) {
return '';
}
if (timeStyle === 'long') {
return dateTimeFormat.getLongTime(locale, value);
}
return dateTimeFormat.getShortTime(locale, value);
};
export const getTimeSlot = ({ value, timeStyle, locale }) => {
const formattedDate = getFormattedDate({
value,
timeStyle,
locale,
});
return {
id: new Date(value).getTime(),
value: formattedDate,
};
};
export const getTimeSlots = ({ value = new Date(Date.now()), timeStyle, locale, step, }) => {
const validatedStep = parseInt(step) ? parseInt(step) : DEFAULT_STEP;
const minuteMs = 60000;
const stepMs = validatedStep > 60 ? 60 * minuteMs : validatedStep * minuteMs;
const startOfTheDay = new Date(value).setHours(0, 0, 0, 0);
const dayMs = 86400000;
const amountOfTimeSlots = dayMs / stepMs;
return new Array(amountOfTimeSlots).fill().map((_, i) => {
const timeInMs = startOfTheDay + i * stepMs;
return getTimeSlot({ value: timeInMs, timeStyle, locale });
});
};
export const getClosestTimeSlot = ({ value = new Date(Date.now()), timeSlots, }) => {
return timeSlots.find(option => option.id >= new Date(value).getTime());
};
const findTimeMatchAndAddDivider = (regexes, value) => {
const matchedRegexIndex = regexes.findIndex(regex => regex.test(value));
if (matchedRegexIndex !== -1) {
return value.replace(regexes[matchedRegexIndex], addDivider);
}
return value;
};
export const getCustomTimeSlot = ({ value, timeSlot, timeStyle, locale }) => {
let timeValue = value
.replace(/[:.h ]{1,}/, ':')
.replace(/\.| /g, '')
.replace(/a\sm|PG|πμ|π|ص/i, 'AM')
.replace(/p\sm|PTG|μμ|μ|م/i, 'PM')
.replace(/(下午|下|오후|ÖS)(.*)/, (_, __, rest) => `${rest}PM`)
.replace(/(上午|上|오전|ÖÖ)(.*)/, (_, __, rest) => `${rest}AM`)
.replace(/[AP]$/i, match => `${match}M`)
.replace(/AM|PM/i, match => ` ${match}`);
if (!timeValue && timeValue !== '0') {
return;
}
if (_24hourTimeFormats.includes(locale)) {
timeValue = findTimeMatchAndAddDivider(_24hourTimeRegex, timeValue);
}
if (_12hourTimeFormats.includes(locale)) {
timeValue = findTimeMatchAndAddDivider(_12hourTimeRegex, timeValue);
}
if (fullTimeNoDividerRegex.test(timeValue)) {
timeValue = timeValue.replace(fullTimeNoDividerRegex, addDivider);
}
if (/[0-2]?[0-9][:][0-9]$/.test(timeValue)) {
timeValue = `${timeValue}0`;
}
const timeSlotDate = dateTimeFormat.getShortDate('en', new Date(timeSlot));
try {
return getTimeSlot({
value: new Date(`${timeSlotDate} ${timeValue}`),
timeStyle,
locale,
});
}
catch {
return;
}
};
const regexReplacer = (_, __, hours, divider, minutes) => {
if (/^[1-9]$/.test(hours)) {
return `0${hours}${divider}${minutes}`;
}
return `${hours}${divider}${minutes}`;
};
const addDivider = (_, hours, minutes) => {
return `${hours}:${minutes}`;
};
const normalizeTimeSlots = timeSlots => timeSlots.map(slot => ({
...slot,
value: slot.value.replace(timeRegex, regexReplacer),
}));
export const removeIrrelevantCharacters = input => input.replace(/[下上午오전후ÖS ]{0,}/, '');
export const getAutoFilledValue = ({ inputValue, suggestedOption, locale }) => {
let value = removeIrrelevantCharacters(inputValue);
if (suggestedOption.value.startsWith('0') && !value.startsWith('0')) {
value = `0${value}`;
}
let sliceTo = value.length;
const valueMatchesPartial24hourTime = _24hourTimeFormats.includes(locale) &&
_24hourTimeRegex.some(regex => regex.test(value));
const valueMatchesPartial12hourTime = _12hourTimeFormats.includes(locale) &&
_12hourTimeRegex.some(regex => regex.test(value));
if (value.match(fullTimeNoDividerRegex) ||
valueMatchesPartial24hourTime ||
valueMatchesPartial12hourTime) {
sliceTo = sliceTo + 1;
}
return suggestedOption.value.slice(sliceTo);
};
const findTimeMatch = (slot, value, locale) => slot.value.startsWith(value) ||
slot.value.startsWith(`0${value}`) ||
slot.value.startsWith(value.replace(fullTimeNoDividerRegex, addDivider)) ||
slot.value.startsWith(`0${value}`.replace(fullTimeNoDividerRegex, addDivider)) ||
(_24hourTimeFormats.includes(locale) &&
(slot.value.startsWith(findTimeMatchAndAddDivider(_24hour2digitTimeRegex, value)) ||
slot.value.startsWith(findTimeMatchAndAddDivider(_24hour2digitTimeRegex, `0${value}`)) ||
slot.value.startsWith(findTimeMatchAndAddDivider(_24hour3digitTimeRegex, value)))) ||
(_12hourTimeFormats.includes(locale) &&
(slot.value.startsWith(findTimeMatchAndAddDivider(_12hour2digitTimeRegex, value)) ||
slot.value.startsWith(findTimeMatchAndAddDivider(_12hour2digitTimeRegex, `0${value}`)) ||
slot.value.startsWith(findTimeMatchAndAddDivider(_12hour3digitTimeRegex, value))));
export const getSuggestedOption = ({ inputValue, timeSlots, locale }) => {
const value = removeIrrelevantCharacters(inputValue);
if (!value || value === '0') {
return;
}
const currentTime = Date.now();
const nextTimeSlotId = timeSlots.findIndex(time => time.id > currentTime);
const highPriorityList = timeSlots.slice(nextTimeSlotId, timeSlots.length);
const lowPriorityList = timeSlots.slice(0, nextTimeSlotId);
const prioritizedList = [...highPriorityList, ...lowPriorityList];
const normalizedTimeSlots = normalizeTimeSlots(prioritizedList);
return normalizedTimeSlots.find(slot => findTimeMatch(slot, value, locale));
};
export const isInputInvalid = inputValue => !validationRegex.test(inputValue);
export const getTimeFilter = ({ excludePastTimes, filterTime = () => true, }) => {
if (excludePastTimes) {
const now = new Date();
return time => time > now && filterTime(time);
}
return filterTime;
};
//# sourceMappingURL=TimeInputUtils.js.map