UNPKG

@ecwenze1/vue-datepicker

Version:

A clean datepicker made with VueJs

299 lines (259 loc) 8.41 kB
import dayjs from './dayjs'; import { getDefaultInputFormat, getDefaultHeaderFormat, getDefaultOutputFormat, replaceRegexWithDates, } from './format'; import { convertQuarterToMonth, } from './convert'; // Locale import { en } from '../../../locale'; // Constants import { AVAILABLE_YEARS } from '../../../constants'; export { // -- Format getDefaultInputFormat, getDefaultHeaderFormat, getDefaultOutputFormat, // -- Convert convertQuarterToMonth, // -- Initialize Dates initDate, generateDates, transformDateForModel, // -- Compare isDateAllowed, isCurrent, areSameDates, isBeforeDate, isAfterDate, isBetweenDates, isDateAfter, // - Generate Date generateDate, generateDateFormatted, generateDateWithYearAndMonth, generateMonthAndYear, generateDateRange, generateDateRangeWithoutDisabled, getRangeDatesFormatted, genFormattedInputDate, }; // ------------------------------- // Initialize dates for components // ------------------------------- function initDate (date, { range, locale, type }) { if (range) { return { start: date && date.start != null ? generateDate({ date: date.start, locale }) : undefined, end: date && date.end != null ? generateDate({ date: date.end, locale }) : undefined, }; } return date != null ? generateDate({ date, locale, type }) : undefined; } function generateDates ({ headerFormat, locale, maxDate, minDate, mutableDate, range, rangeHeaderText, }) { return { formattedHeaderYear: generateDateFormatted({ date: mutableDate, locale, format: 'YYYY', }), formattedHeaderDate: genFormattedHeaderDate({ date: mutableDate, headerFormat, locale, range, rangeHeaderText, }), minDate, maxDate, minMonth: genMinMaxFormatted({ date: minDate, type: 'month', locale }), maxMonth: genMinMaxFormatted({ date: maxDate, type: 'month', locale }), minYear: genMinMaxFormatted({ date: minDate, type: 'year', locale }), maxYear: genMinMaxFormatted({ date: maxDate, type: 'year', locale }), }; } function transformDateForModel (date, format, range) { if (range) { return { start: date.start.format(format), end: date.end && date.end.format(format), }; } return date.format(format); } // ------------------------------- // Compares Dates // ------------------------------- function isDateAllowed ({ date, min, max, type = 'date', allowedFn }) { const formattedDate = date.format(getDefaultOutputFormat(type)); return (!allowedFn || allowedFn(formattedDate)) && (!min || areSameDates(formattedDate, min, type) || isAfterDate(formattedDate, min, type)) && (!max || areSameDates(formattedDate, max, type) || isBeforeDate(formattedDate, max, type)); } function isCurrent ({ date, type = 'date', locale }) { const formattedDate = generateDateFormatted({ date, locale, format: getDefaultOutputFormat(type), }); const todaysDateFormatted = generateDateFormatted({ date: undefined, locale, format: getDefaultOutputFormat(type), }); // if type is quarter, we need to compare year & month // For example, formattedDate looks like 2020-1 // For example, todaysDateFormatted looks like 2020-1 return areSameDates(formattedDate, todaysDateFormatted, type === 'quarter' ? 'month' : type); } function areSameDates (date, dateSelected, type = 'date') { return dayjs(date, getDefaultOutputFormat(type)) .isSame(dayjs(dateSelected, getDefaultOutputFormat(type)), type); } function isBeforeDate (date, beforeDate, type = 'day') { if (type === 'year') { return Boolean(beforeDate) && date < dayjs(beforeDate, 'YYYY-MM-DD').get(type); } const selectedDate = dayjs.isDayjs(date) ? date : dayjs(date).startOf('day'); return Boolean(beforeDate) && selectedDate.isBefore(dayjs(beforeDate).startOf('day'), type); } function isAfterDate (date, afterDate, type = 'day') { if (type === 'year') { return Boolean(afterDate) && date > dayjs(afterDate, 'YYYY-MM-DD').get(type); } const selectedDate = dayjs.isDayjs(date) ? date : dayjs(date).startOf('day'); return Boolean(afterDate) && selectedDate.isAfter(dayjs(afterDate).startOf('day'), type); } function isBetweenDates (date, startDate, maxDate) { return isAfterDate(date, startDate) && isBeforeDate(date, maxDate); } function isDateAfter (newDate, oldDate) { return dayjs(newDate).isAfter(dayjs(oldDate)); } // ------------------------------- // Generate Date properly formatted with locale // ------------------------------- function generateDate ({ date, locale = { lang: en }, type = 'date' }) { if (type === 'year') return dayjs(date).utc(); return dayjs(date).locale(locale.lang); } function generateDateFormatted ({ date, locale, format }) { return generateDate({ date, locale }).format(format); } function generateDateWithYearAndMonth ({ year, month, locale }) { return generateDate({ locale }).year(year).month(month).startOf('month'); } function generateMonthAndYear (value, pickerDate, mode) { if (mode === 'year') return { year: value, month: pickerDate.month }; if (mode === 'quarter') return { year: pickerDate.year, month: convertQuarterToMonth(value) }; return { year: pickerDate.year, month: value }; } function generateDateRange ({ startDate, endDate, locale, interval = 'day', }) { const start = generateDate({ date: startDate, locale }); const end = generateDate({ date: endDate, locale }); const diffBetweenDates = end.diff(start, interval); return [...Array(diffBetweenDates + 1).keys()].map(i => start.add(i, interval)); } function generateDateRangeWithoutDisabled ({ dates = {}, minDate, maxDate, locale }) { const { start, end } = dates; const validMinDate = minDate || generateDate({ locale }).year(AVAILABLE_YEARS.min); const validMaxDate = maxDate || generateDate({ locale }).year(AVAILABLE_YEARS.max); return generateDateRange({ startDate: start, endDate: end, locale }) .filter(date => date.isSameOrAfter(validMinDate, 'day') && date.isSameOrBefore(dayjs(validMaxDate, 'day'))); } // ------------------------------- // Helpers // ------------------------------- function genFormattedInputDate ({ inputFormat, internalDate, isDateDefined, locale, range, rangeInputText, type, }) { if (!isDateDefined) return; if (range && rangeInputText) { const [startDate, endDate] = getRangeDatesFormatted({ dates: internalDate, locale, format: inputFormat, }).split(' ~ '); return replaceRegexWithDates({ regexText: rangeInputText, startDate, endDate }); } // If type is quarter, // We need to convert this quarter date, to a monthly date // because dayjs will transform a monthly date to quarter date only // Exemple => '2019-2' => should be converted to date : 2019-06-01 const currentMonth = internalDate.month(); const newMonth = type === 'quarter' ? convertQuarterToMonth(currentMonth) : currentMonth; return generateDateFormatted({ date: internalDate.set('month', newMonth), locale, format: inputFormat, }); } function genFormattedHeaderDate ({ headerFormat, locale, date, range, rangeHeaderText, }) { if (range && rangeHeaderText) { const [startDate, endDate] = getRangeDatesFormatted({ dates: date, locale, format: headerFormat, }).split(' ~ '); const [fromText, toText] = replaceRegexWithDates({ regexText: rangeHeaderText, startDate, endDate, }, true); return [fromText.trim(), toText.trim()]; } if (!date) return '--'; return generateDateFormatted({ date, locale, format: headerFormat, }); } function genMinMaxFormatted ({ date, type, locale }) { if (!date) return; return generateDateFormatted({ date, locale, format: getDefaultOutputFormat(type), }); } function getRangeDatesFormatted ({ dates = {}, locale, format }) { const { start, end } = dates; if (!start && !end) return `__ ~ __`; if (!start && end) return `__ ~ ${generateDate({ date: end, locale }).startOf('day').format(format)}`; if (start && !end) return `${generateDate({ date: start, locale }).startOf('day').format(format)} ~ __`; return `\ ${generateDate({ date: start, locale }).startOf('day').format(format)} \ ~ \ ${generateDate({ date: end, locale }).startOf('day').format(format)}`; }