@commercetools-uikit/calendar-time-utils
Version:
Utilities to work with time values for a calendar.
269 lines (255 loc) • 12.1 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var _slicedToArray = require('@babel/runtime-corejs3/helpers/slicedToArray');
var _parseInt = require('@babel/runtime-corejs3/core-js-stable/parse-int');
var _sliceInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/slice');
var _mapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/map');
var _Array$from = require('@babel/runtime-corejs3/core-js-stable/array/from');
var _startsWithInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/starts-with');
var _Map = require('@babel/runtime-corejs3/core-js-stable/map');
var _Object$entries = require('@babel/runtime-corejs3/core-js-stable/object/entries');
var _reduceInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/reduce');
var moment = require('moment-timezone');
var utils = require('@commercetools-uikit/utils');
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
var _parseInt__default = /*#__PURE__*/_interopDefault(_parseInt);
var _sliceInstanceProperty__default = /*#__PURE__*/_interopDefault(_sliceInstanceProperty);
var _mapInstanceProperty__default = /*#__PURE__*/_interopDefault(_mapInstanceProperty);
var _Array$from__default = /*#__PURE__*/_interopDefault(_Array$from);
var _startsWithInstanceProperty__default = /*#__PURE__*/_interopDefault(_startsWithInstanceProperty);
var _Map__default = /*#__PURE__*/_interopDefault(_Map);
var _Object$entries__default = /*#__PURE__*/_interopDefault(_Object$entries);
var _reduceInstanceProperty__default = /*#__PURE__*/_interopDefault(_reduceInstanceProperty);
var moment__default = /*#__PURE__*/_interopDefault(moment);
// Reference: https://momentjs.com/docs/#/displaying/format/
const formatToken = {
D: 'D',
// NUMERIC_SINGLE_DAY
DD: 'DD',
// NUMERIC_TWO_DIGITS_DAY
M: 'M',
// NUMERIC_SINGLE_MONTH
MM: 'MM',
// NUMERIC_TWO_DIGIT_MONTH
YY: 'YY',
// TWO_DIGITS_YEAR
YYYY: 'YYYY',
// FOUR_DIGITS_YEAR
h: 'h',
// HOUR_12_SINGLE
hh: 'hh',
// HOUR_12_TWO_DIGITS
H: 'H',
// HOUR_24_SINGLE
HH: 'HH',
// HOUR_24_TWO_DIGITS
m: 'm',
// MINUTE_SINGLE
mm: 'mm',
// MINUTE_TWO_DIGITS
A: 'A' // PERIOD - https://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns
};
// Here is where we translate from the standard characters used in the pattern
// (calculated in the moment.js library) to the characters used in the locale
// We just need to provide the translation for the characters that are different
// For instance, in english we don't need to translate date characters as
// they are the same as the pattern characters
const DATE_FORMAT_LOCALIZED_MAPPINGS = {
en: {
// MM/DD/YYYY - h:mm A -> MM/DD/YYYY - HH:mm AM/PM
[formatToken.h]: 'HH',
[formatToken.A]: 'AM/PM'
},
de: {
// DD.MM.YYYY - HH:mm -> TT.MM.JJJJ - SS:mm
[formatToken.DD]: 'TT',
[formatToken.YYYY]: 'JJJJ',
[formatToken.HH]: 'SS'
},
es: {
// DD/MM/YYYY - H:mm -> DD/MM/AAAA - HH:mm
[formatToken.H]: 'HH',
[formatToken.YYYY]: 'AAAA'
},
fr: {
// DD/MM/YYYY - HH:mm -> JJ/MM/AAAA - HH:mm
[formatToken.DD]: 'JJ',
[formatToken.YYYY]: 'AAAA'
},
pt: {
// DD/MM/YYYY - HH:mm -> DD/MM/AAAA - HH:mm
[formatToken.YYYY]: 'AAAA'
}
};
const getDaysInMonth = (day, timeZone) => moment__default["default"].tz(day, timeZone).daysInMonth();
const changeDateInMonth = (day, timeZone, dayOfMonth) => moment__default["default"].tz(day, timeZone).date(dayOfMonth).toISOString();
const changeTime = (dateString, timeZone, parsedTime) => {
const date = moment__default["default"].tz(dateString, timeZone);
date.hours(parsedTime.hours);
date.minutes(parsedTime.minutes);
date.seconds(parsedTime.seconds);
date.seconds(parsedTime.seconds);
date.milliseconds(parsedTime.milliseconds);
return date.toISOString();
};
const getPreviousDay = day => moment__default["default"](day).subtract(1, 'day').format('YYYY-MM-DD');
const formatDefaultTime = (time, locale) => {
const today = moment__default["default"]();
if (moment__default["default"](time, 'HH:mm', true).isValid()) {
const _time$split = time.split(':'),
_time$split2 = _slicedToArray(_time$split, 2),
hour = _time$split2[0],
minute = _time$split2[1];
today.set({
hour: _parseInt__default["default"](hour, 10),
minute: _parseInt__default["default"](minute, 10)
});
return moment__default["default"](today).locale(locale).format('LT'); // 5:13 PM
} else {
process.env.NODE_ENV !== "production" ? utils.warning(false, `DataTimeInput: the specified defaultDaySelectionTime '${time}' is not supported. The format should be hh:mm, e.g. 11:10. Using 00:00 as default time.`) : void 0;
today.set({
hour: 0,
minute: 0
});
return moment__default["default"](today).locale(locale).format('LT'); // 12:00 AM
}
};
const formatTime = (day, locale, timeZone) => {
const date = moment__default["default"].tz(day, timeZone).locale(locale);
if (date.milliseconds()) return date.format('HH:mm:ss.SSS');
if (date.seconds()) return date.format('LTS'); // 5:13:51 PM
return date.format('LT'); // 5:13 PM
};
const formatDate = (day, locale, timeZone) => {
const date = moment__default["default"](day, moment__default["default"].ISO_8601, locale).tz(timeZone).format('L');
const time = formatTime(day, locale, timeZone);
return `${date} ${time}`;
};
const getDateInMonth = (day, timeZone) => moment__default["default"].tz(day, timeZone).date();
const getToday = timeZone => moment__default["default"].tz(timeZone).startOf('day').toISOString();
const changeMonth = (day, timeZone, delta) => moment__default["default"].tz(day, timeZone).add(delta, 'month').toISOString();
const getPaddingDayCount = (day, locale, timeZone) => {
const firstDayOfWeek = moment__default["default"].localeData(locale).firstDayOfWeek();
const firstDayOfMonth = moment__default["default"].tz(day, timeZone).startOf('month').day();
// ensure number is always positive
return (firstDayOfMonth - firstDayOfWeek + 7) % 7;
};
const getWeekdayNames = locale => {
const weekDays = moment__default["default"].localeData(locale).weekdaysMin();
const firstDay = moment__default["default"].localeData(locale).firstDayOfWeek();
return [..._sliceInstanceProperty__default["default"](weekDays).call(weekDays, firstDay), ..._sliceInstanceProperty__default["default"](weekDays).call(weekDays, 0, firstDay)];
};
const getStartOf = (day, timeZone) => moment__default["default"].tz(day, timeZone).startOf('day').toISOString();
const getMonthCalendarLabel = (day, locale, timeZone) => timeZone ? moment__default["default"].tz(day, timeZone).locale(locale).format('MMMM') : moment__default["default"](day, moment__default["default"].ISO_8601, locale).format('MMMM');
const getYearCalendarLabel = (day, locale, timeZone) => timeZone ? moment__default["default"].tz(day, timeZone).locale(locale).format('YYYY') : moment__default["default"](day, moment__default["default"].ISO_8601, locale).format('YYYY');
const isSameDay = (a, b) => moment__default["default"](a).isSame(b, 'day');
const getCalendarDayLabel = (day, timeZone) => moment__default["default"].tz(day, timeZone).format('D');
const createItemDateTimeToString = (locale, timeZone) => item => item ? formatDate(item, locale, timeZone) : '';
const createCalendarItems = (day, timeString, timeZone) => {
var _context;
const parsedTime = utils.parseTime(timeString);
return _mapInstanceProperty__default["default"](_context = _Array$from__default["default"]({
length: getDaysInMonth(day, timeZone)
})).call(_context, (_, i) => {
const dayOfMonth = i + 1;
let date = changeDateInMonth(day, timeZone, dayOfMonth);
if (parsedTime) {
date = changeTime(date, timeZone, parsedTime);
}
return date;
});
};
const createSuggestedItems = (inputValue, timeZone) => {
if (_startsWithInstanceProperty__default["default"](inputValue).call(inputValue, 't')) return [getToday(timeZone)];
return [];
};
const parseInputText = (text, locale, timeZone) => {
const parts = text.split(' ');
const dateString = parts[0];
const timeString = _sliceInstanceProperty__default["default"](parts).call(parts, 1).join(' ');
if (!dateString) return '';
const date = moment__default["default"].tz(dateString, moment__default["default"].localeData(locale).longDateFormat('L'), timeZone);
if (!date.isValid()) return '';
// enable parsing a date only
if (!timeString) return date.startOf('day').toISOString();
const parsedTime = utils.parseTime(timeString);
if (parsedTime) {
date.hours(parsedTime.hours);
date.minutes(parsedTime.minutes);
date.seconds(parsedTime.seconds);
date.seconds(parsedTime.seconds);
date.milliseconds(parsedTime.milliseconds);
return date.toISOString();
}
return '';
};
const localizedDateFormatPatternCache = new _Map__default["default"]();
const getLocalizedDateTimeFormatPattern = function (locale) {
let formatType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'date';
const key = `${locale}::${formatType}`;
if (localizedDateFormatPatternCache.has(key)) {
return localizedDateFormatPatternCache.get(key);
}
// References:
// https://momentjs.com/docs/#/i18n/locale-data/
// https://momentjs.com/docs/#/displaying/ ("Localized formats" section)
const localeData = moment__default["default"]().locale(locale).localeData();
let localizedFormat = '';
switch (formatType) {
case 'date':
localizedFormat = localeData.longDateFormat('L');
break;
case 'time':
localizedFormat = localeData.longDateFormat('LT');
break;
case 'full':
localizedFormat = `${localeData.longDateFormat('L')} - ${localeData.longDateFormat('LT')}`;
break;
default:
throw new Error(`CalendarTime.getLocalizedDateTimeFormatPattern: Unknown format type '${formatType}'`);
}
// We try to get the localization both with the whole locale (e.g. 'en-GB')
// and the generic language code (e.g. 'en').
const _locale$split = locale.split('-'),
_locale$split2 = _slicedToArray(_locale$split, 1),
languageCode = _locale$split2[0];
const localeMappings = _Object$entries__default["default"](DATE_FORMAT_LOCALIZED_MAPPINGS[locale] || DATE_FORMAT_LOCALIZED_MAPPINGS[languageCode] || {});
// In case we don't have a translation for the locale, we fallback to the
// pattern from the moment locale data.
let pattern = localizedFormat;
if (localeMappings && localeMappings.length > 0) {
pattern = _reduceInstanceProperty__default["default"](localeMappings).call(localeMappings, (localizedPattern, _ref) => {
let _ref2 = _slicedToArray(_ref, 2),
token = _ref2[0],
mappedValue = _ref2[1];
return localizedPattern.replace(token, mappedValue);
}, localizedFormat);
}
localizedDateFormatPatternCache.set(key, pattern);
return pattern;
};
// NOTE: This string will be replaced on build time with the package version.
var version = "20.2.2";
exports.changeDateInMonth = changeDateInMonth;
exports.changeMonth = changeMonth;
exports.changeTime = changeTime;
exports.createCalendarItems = createCalendarItems;
exports.createItemDateTimeToString = createItemDateTimeToString;
exports.createSuggestedItems = createSuggestedItems;
exports.formatDate = formatDate;
exports.formatDefaultTime = formatDefaultTime;
exports.formatTime = formatTime;
exports.getCalendarDayLabel = getCalendarDayLabel;
exports.getDateInMonth = getDateInMonth;
exports.getDaysInMonth = getDaysInMonth;
exports.getLocalizedDateTimeFormatPattern = getLocalizedDateTimeFormatPattern;
exports.getMonthCalendarLabel = getMonthCalendarLabel;
exports.getPaddingDayCount = getPaddingDayCount;
exports.getPreviousDay = getPreviousDay;
exports.getStartOf = getStartOf;
exports.getToday = getToday;
exports.getWeekdayNames = getWeekdayNames;
exports.getYearCalendarLabel = getYearCalendarLabel;
exports.isSameDay = isSameDay;
exports.parseInputText = parseInputText;
exports.version = version;