diff --git a/projects/ng-aquila/src/datefield/datefield.md b/projects/ng-aquila/src/datefield/datefield.md index 7245e6a78..80ca49968 100644 --- a/projects/ng-aquila/src/datefield/datefield.md +++ b/projects/ng-aquila/src/datefield/datefield.md @@ -33,8 +33,6 @@ Momentjs ships with every locale thus significantly increasing the bundle size. The ISO date adapter works solely with YYYY-MM-DD strings. Under the hood it uses dayjs to support formatting, parsing and localization. With this adapter you don't have to create a proper Date, Dayjs or Moment Object first to bind it with ngModel or reactive forms. -For localization you have to import the locales yourself. `en` is the default locale. To add e.g. german you use `import 'dayjs/locale/de'`. - Please install the `dayjs` package to use this adapter. #### Native Date diff --git a/projects/ng-aquila/src/iso-date-adapter/adapter/dayjs-locale-utils.spec.ts b/projects/ng-aquila/src/iso-date-adapter/adapter/dayjs-locale-utils.spec.ts index 5159574b5..6405aad1c 100644 --- a/projects/ng-aquila/src/iso-date-adapter/adapter/dayjs-locale-utils.spec.ts +++ b/projects/ng-aquila/src/iso-date-adapter/adapter/dayjs-locale-utils.spec.ts @@ -1,4 +1,4 @@ -import { convertToDayjsLocale } from './dayjs-locale-utils'; +import { convertToDayjsLocale, getDayjsLocaleData } from './dayjs-locale-utils'; describe('dayjs locale utils', () => { describe('convertToDayjsLocale', () => { @@ -38,4 +38,30 @@ describe('dayjs locale utils', () => { }); }); }); + + describe('getDayjsLocaleData', () => { + it('should return the localeData of the requested locale ("de")', async () => { + const deLocaleData = await getDayjsLocaleData('de'); + // smoke testing a few of the properties of the 'de' locale + expect(deLocaleData.firstDayOfWeek()).toBe(1); + expect(deLocaleData.weekdaysMin()).toEqual(['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa']); + expect(deLocaleData.monthsShort()).toEqual(['Jan', 'Feb', 'März', 'Apr', 'Mai', 'Juni', 'Juli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dez']); + }); + + it('should return the localeData of the requested locale ("es-us")', async () => { + const esUsLocaleData = await getDayjsLocaleData('es-us'); + // smoke testing a few of the properties of the 'es-us' locale + expect(esUsLocaleData.firstDayOfWeek()).toBe(0); + expect(esUsLocaleData.weekdaysMin()).toEqual(['do', 'lu', 'ma', 'mi', 'ju', 'vi', 'sá']); + expect(esUsLocaleData.monthsShort()).toEqual(['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dic']); + }); + + it('should fall back to the global localeData for unknown locales', async () => { + const localeData = await getDayjsLocaleData('unknown'); + // smoke testing a few of the properties of the global ('en') locale + expect(localeData.firstDayOfWeek()).toBe(0); + expect(localeData.weekdaysMin()).toEqual(['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']); + expect(localeData.monthsShort()).toEqual(['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']); + }); + }); }); diff --git a/projects/ng-aquila/src/iso-date-adapter/adapter/dayjs-locale-utils.ts b/projects/ng-aquila/src/iso-date-adapter/adapter/dayjs-locale-utils.ts index 23e9d2b1c..983a98a50 100644 --- a/projects/ng-aquila/src/iso-date-adapter/adapter/dayjs-locale-utils.ts +++ b/projects/ng-aquila/src/iso-date-adapter/adapter/dayjs-locale-utils.ts @@ -1,3 +1,4 @@ +import dayjs from 'dayjs'; import supportedLocales from 'dayjs/locale.json'; /** @@ -33,3 +34,20 @@ export function convertToDayjsLocale(localeId: string): string { return dayjsLocale.key; } + +/** + * This function uses a dynamic import to load the dayjs data for the requested locale + * and returns the localeData for this locale. + * + * @param localeId a "language-range" following the BCP 47 standard + * @returns a Promise that resolves with the dayjs localeData for the given locale + */ +export async function getDayjsLocaleData(localeId: string): Promise { + return import(`dayjs/locale/${localeId}`) + .then(() => dayjs().locale(localeId).localeData()) + .catch(() => { + console.warn(`The requested dayjs locale '${localeId}' could not be loaded.`); + // return the global localeData as fallback + return dayjs.localeData(); + }); +} diff --git a/projects/ng-aquila/src/iso-date-adapter/adapter/iso-date-adapter.spec.ts b/projects/ng-aquila/src/iso-date-adapter/adapter/iso-date-adapter.spec.ts index a60d4cf36..110f010c2 100644 --- a/projects/ng-aquila/src/iso-date-adapter/adapter/iso-date-adapter.spec.ts +++ b/projects/ng-aquila/src/iso-date-adapter/adapter/iso-date-adapter.spec.ts @@ -23,9 +23,7 @@ describe('NxIsoDateAdapter', () => { ); beforeEach(inject([NxDateAdapter], (dateAdapter: NxIsoDateAdapter) => { - dayjs.locale('en'); adapter = dateAdapter; - adapter.setLocale('en'); assertValidDate = (d: string | null, valid: boolean) => { expect(adapter.isDateInstance(d)).not.toBeNull(); @@ -34,9 +32,8 @@ describe('NxIsoDateAdapter', () => { })); describe('Localization', () => { - beforeEach(() => { - adapter.setLocale('de'); - dayjs.locale('de'); + beforeEach(async () => { + await adapter.setLocale('de'); }); it('should parse locale date with explicit format', () => { @@ -56,17 +53,17 @@ describe('NxIsoDateAdapter', () => { }); describe('Localization with locale id that is unknown to dayjs', () => { - it('should automatically fall back to a locale that is known to dayjs', () => { + it('should automatically fall back to a locale that is known to dayjs', async () => { // 'de-BY' is unknwon to dayjs (and the world). The IsoDateAdapter should fall back to 'de'. - adapter.setLocale('de-BY'); + await adapter.setLocale('de-BY'); const date = adapter.parse('01.12.2020', 'MM.DD.YYYY', true); expect(date).toBe('2020-01-12'); }); }); describe('Localization with a different format between global day.js and the adapter', () => { - beforeEach(() => { - adapter.setLocale('de'); + beforeEach(async () => { + await adapter.setLocale('de'); dayjs.locale('en'); }); @@ -105,9 +102,9 @@ describe('NxIsoDateAdapter', () => { assertValidDate(adapter.deserialize('2017-01-01'), true); }); - it('setLocale should not modify global moment locale', () => { + it('setLocale should not modify global moment locale', async () => { expect(dayjs.locale()).toBe('en'); - adapter.setLocale('de'); + await adapter.setLocale('de'); expect(dayjs.locale()).toBe('en'); }); diff --git a/projects/ng-aquila/src/iso-date-adapter/adapter/iso-date-adapter.ts b/projects/ng-aquila/src/iso-date-adapter/adapter/iso-date-adapter.ts index 3370d00e9..28afecc3e 100644 --- a/projects/ng-aquila/src/iso-date-adapter/adapter/iso-date-adapter.ts +++ b/projects/ng-aquila/src/iso-date-adapter/adapter/iso-date-adapter.ts @@ -7,7 +7,7 @@ import localeData from 'dayjs/plugin/localeData'; import localizedFormat from 'dayjs/plugin/localizedFormat'; import utc from 'dayjs/plugin/utc'; -import { convertToDayjsLocale } from './dayjs-locale-utils'; +import { convertToDayjsLocale, getDayjsLocaleData } from './dayjs-locale-utils'; dayjs.extend(localeData); dayjs.extend(customParseFormat); @@ -231,9 +231,9 @@ export class NxIsoDateAdapter extends NxDateAdapter { return this._localeData.narrowDaysOfWeek; } - setLocale(locale: string) { + async setLocale(locale: string) { this._dayjsLocale = convertToDayjsLocale(locale); - const data = dayjs().locale(this._dayjsLocale).localeData(); + const data = await getDayjsLocaleData(this._dayjsLocale); this._localeData = { firstDayOfWeek: data.firstDayOfWeek(),