UNPKG

ngx-material-date-fns-adapter

Version:

date-fns adapter for Angular-Material applications. (Support jalali)

364 lines (357 loc) 13 kB
import * as i0 from '@angular/core'; import { inject, Injectable, NgModule } from '@angular/core'; import { DateAdapter, MAT_DATE_LOCALE, MAT_DATE_FORMATS } from '@angular/material/core'; import * as gregorian from 'date-fns'; import * as jalali from 'date-fns-jalali'; import { enUS } from 'date-fns/locale'; import { faIR } from 'date-fns-jalali/locale'; /** Creates an array and fills it with values. */ function range(length, valueFunction) { const valuesArray = Array(length); for (let i = 0; i < length; i++) { valuesArray[i] = valueFunction(i); } return valuesArray; } const dateFns = { gregorian: { setMonth: gregorian.setMonth, setDate: gregorian.setDate, getMonth: gregorian.getMonth, getYear: gregorian.getYear, getDate: gregorian.getDate, getDay: gregorian.getDay, getHours: gregorian.getHours, getMinutes: gregorian.getMinutes, getSeconds: gregorian.getSeconds, getDaysInMonth: gregorian.getDaysInMonth, formatISO: gregorian.formatISO, addYears: gregorian.addYears, addMonths: gregorian.addMonths, addDays: gregorian.addDays, addSeconds: gregorian.addSeconds, isValid: gregorian.isValid, isDate: gregorian.isDate, format: gregorian.format, parseISO: gregorian.parseISO, parse: gregorian.parse, set: gregorian.set, }, jalali: { setMonth: jalali.setMonth, setDate: jalali.setDate, getMonth: jalali.getMonth, getYear: jalali.getYear, getDate: jalali.getDate, getDay: jalali.getDay, getHours: jalali.getHours, getMinutes: jalali.getMinutes, getSeconds: jalali.getSeconds, getDaysInMonth: jalali.getDaysInMonth, formatISO: jalali.formatISO, addYears: jalali.addYears, addMonths: jalali.addMonths, addDays: jalali.addDays, addSeconds: jalali.addSeconds, isValid: jalali.isValid, isDate: jalali.isDate, format: jalali.format, parseISO: jalali.parseISO, parse: jalali.parse, set: jalali.set, }, }; // date-fns doesn't have a way to read/print month names or days of the week directly, // so we get them by formatting a date with a format that produces the desired month/day. const MONTH_FORMATS = { long: 'LLLL', short: 'LLL', narrow: 'LLLLL', }; const DAY_OF_WEEK_FORMATS = { long: 'EEEE', short: 'EEE', narrow: 'EEEEE', }; class DateFnsAdapter extends DateAdapter { constructor() { super(); /** Calendar type. */ this._calendarType = 'gregorian'; const matDateLocale = inject(MAT_DATE_LOCALE, { optional: true }); this.setLocale(matDateLocale); } /** * Sets the locale used for all dates. * * @param locale The new locale */ setLocale(locale = enUS) { if (locale.code === 'fa-IR') { locale = faIR; this._calendarType = 'jalali'; } else { this._calendarType = 'gregorian'; } super.setLocale(locale); } getYear(date) { return dateFns[this._calendarType].getYear(date); } getMonth(date) { return dateFns[this._calendarType].getMonth(date); } getDate(date) { return dateFns[this._calendarType].getDate(date); } getDayOfWeek(date) { return dateFns[this._calendarType].getDay(date); } getMonthNames(style) { const pattern = MONTH_FORMATS[style]; return range(12, (i) => this.format(dateFns[this._calendarType].setMonth(this.today(), i), pattern)); } getDateNames() { const dtf = typeof Intl !== 'undefined' ? new Intl.DateTimeFormat(this.locale.code, { day: 'numeric', }) : null; return range(31, (i) => { let date = this.createDate(2017, 0, i + 1); if (dtf) { return dtf.format(date).replace(/[\u200e\u200f]/g, ''); } return this.format(date, 'd'); }); } getDayOfWeekNames(style) { const pattern = DAY_OF_WEEK_FORMATS[style]; return range(7, (i) => this.format(new Date(2017, 0, i + 1), pattern)); } getYearName(date) { return this.format(date, 'y'); } getFirstDayOfWeek() { return this.locale.options?.weekStartsOn ?? 0; } getNumDaysInMonth(date) { return dateFns[this._calendarType].getDaysInMonth(date); } clone(date) { return new Date(date.getTime()); } createDate(year, month, date) { // Check for invalid month and date (except upper bound on date which we have to check after // creating the Date). if (month < 0 || month > 11) { throw Error(`Invalid month index "${month}". Month index has to be between 0 and 11.`); } if (date < 1) { throw Error(`Invalid date "${date}". Date has to be greater than 0.`); } const result = dateFns[this._calendarType].set(new Date(), { year, month, date, hours: 0, minutes: 0, seconds: 0, milliseconds: 0, }); // Check that the date wasn't above the upper bound for the month, causing the month to overflow if (this.getMonth(result) != month) { throw Error(`Invalid date "${date}" for month with index "${month}".`); } return result; } today() { return new Date(); } parse(value, parseFormat) { if (typeof value == 'string' && value.length > 0) { const iso8601Date = dateFns[this._calendarType].parseISO(value); if (this.isValid(iso8601Date)) { return iso8601Date; } const formats = Array.isArray(parseFormat) ? parseFormat : [parseFormat]; if (!parseFormat.length) { throw Error('Formats array must not be empty.'); } for (const currentFormat of formats) { const fromFormat = dateFns[this._calendarType].parse(value, currentFormat, new Date(), { locale: this.locale, }); if (this.isValid(fromFormat)) { return fromFormat; } } return this.invalid(); } else if (typeof value === 'number') { return new Date(value); } else if (value instanceof Date) { return this.clone(value); } return null; } format(date, displayFormat) { if (!this.isValid(date)) { throw Error('DateFnsAdapter: Cannot format invalid date.'); } // fix persian Month short name if (this.locale.code == 'fa-IR' && displayFormat === 'LLL') displayFormat = 'LLLL'; // fix persian monthYearLabel if (this.locale.code == 'fa-IR' && displayFormat === 'LLL uuuu') displayFormat = 'LLLL uuuu'; return dateFns[this._calendarType].format(date, displayFormat, { locale: this.locale, }); } addCalendarYears(date, years) { return dateFns[this._calendarType].addYears(date, years); } addCalendarMonths(date, months) { return dateFns[this._calendarType].addMonths(date, months); } addCalendarDays(date, days) { return dateFns[this._calendarType].addDays(date, days); } toIso8601(date) { return dateFns[this._calendarType].formatISO(date, { representation: 'date', }); } /** * Returns the given value if given a valid Date or null. Deserializes valid ISO 8601 strings * (https://www.ietf.org/rfc/rfc3339.txt) into valid Dates and empty string into null. Returns an * invalid date for all other values. */ deserialize(value) { if (typeof value === 'string') { if (!value) { return null; } const date = dateFns[this._calendarType].parseISO(value); if (this.isValid(date)) { return date; } } return super.deserialize(value); } isDateInstance(obj) { return dateFns[this._calendarType].isDate(obj); } isValid(date) { return dateFns[this._calendarType].isValid(date); } invalid() { return new Date(NaN); } setTime(target, hours, minutes, seconds) { if (hours < 0 || hours > 23) { throw Error(`Invalid hours "${hours}". Hours value must be between 0 and 23.`); } if (minutes < 0 || minutes > 59) { throw Error(`Invalid minutes "${minutes}". Minutes value must be between 0 and 59.`); } if (seconds < 0 || seconds > 59) { throw Error(`Invalid seconds "${seconds}". Seconds value must be between 0 and 59.`); } return dateFns[this._calendarType].set(this.clone(target), { hours, minutes, seconds, milliseconds: 0, }); } getHours(date) { return dateFns[this._calendarType].getHours(date); } getMinutes(date) { return dateFns[this._calendarType].getMinutes(date); } getSeconds(date) { return dateFns[this._calendarType].getSeconds(date); } parseTime(value, parseFormat) { return this.parse(value, parseFormat); } addSeconds(date, amount) { return dateFns[this._calendarType].addSeconds(date, amount); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: DateFnsAdapter, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: DateFnsAdapter }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: DateFnsAdapter, decorators: [{ type: Injectable }], ctorParameters: () => [] }); const MAT_DATE_FNS_FORMATS = { parse: { dateInput: 'P', timeInput: 'p', }, display: { dateInput: 'P', timeInput: 'p', monthYearLabel: 'LLL uuuu', dateA11yLabel: 'PP', monthYearA11yLabel: 'LLLL uuuu', timeOptionLabel: 'p', }, }; class DateFnsModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: DateFnsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.2", ngImport: i0, type: DateFnsModule }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: DateFnsModule, providers: [ { provide: DateAdapter, useClass: DateFnsAdapter, deps: [MAT_DATE_LOCALE], }, ] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: DateFnsModule, decorators: [{ type: NgModule, args: [{ providers: [ { provide: DateAdapter, useClass: DateFnsAdapter, deps: [MAT_DATE_LOCALE], }, ], }] }] }); class NgxMatDateFnsModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: NgxMatDateFnsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.2", ngImport: i0, type: NgxMatDateFnsModule }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: NgxMatDateFnsModule, providers: [provideDateFnsAdapter()] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.2", ngImport: i0, type: NgxMatDateFnsModule, decorators: [{ type: NgModule, args: [{ providers: [provideDateFnsAdapter()], }] }] }); function provideDateFnsAdapter(formats = MAT_DATE_FNS_FORMATS) { return [ { provide: DateAdapter, useClass: DateFnsAdapter, deps: [MAT_DATE_LOCALE], }, { provide: MAT_DATE_FORMATS, useValue: formats }, ]; } /* * Public API Surface of ngx-material-date-fns-adapter */ /** * Generated bundle index. Do not edit. */ export { DateFnsAdapter, DateFnsModule, MAT_DATE_FNS_FORMATS, NgxMatDateFnsModule, provideDateFnsAdapter }; //# sourceMappingURL=ngx-material-date-fns-adapter.mjs.map