Skip to content

Commit

Permalink
fix(build): import Flatpickr Locale on demand via regular imports (#227)
Browse files Browse the repository at this point in the history
* fix(build): import Flatpickr Locale on demand via regular imports
- we shouldn't use require(locale) because they all end up being part of the final bundle, it's better to let the user import whichever Flatpickr Locale he wants to use and that will end up being a much smaller bundle with only the locale we really need
  • Loading branch information
ghiscoding authored Jan 5, 2021
1 parent fec1ce8 commit 6644822
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 71 deletions.
3 changes: 3 additions & 0 deletions examples/webpack-demo-vanilla-bundle/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import * as SlickerModule from '@slickgrid-universal/vanilla-bundle';
import { App } from './app';
import { TranslateService } from 'translate.service';

// load necessary Flatpickr Locale(s), but make sure it's imported AFTER the SlickerModule import
import 'flatpickr/dist/l10n/fr';

class Main {
app: App;
constructor(private renderer: Renderer) { }
Expand Down
19 changes: 16 additions & 3 deletions packages/common/src/editors/__tests__/dateEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,10 +434,24 @@ describe('DateEditor', () => {
});

describe('with different locale', () => {
it('should display text in new locale', (done) => {
it('should display a console warning when locale is not previously imported', (done) => {
const consoleSpy = jest.spyOn(global.console, 'warn').mockReturnValue();

gridOptionMock.translater = translateService;

translateService.use('fr-CA'); // will be trimmed to "fr"
translateService.use('zz-yy'); // will be trimmed to 2 chars "zz"
editor = new DateEditor(editorArguments);
setTimeout(() => {
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining(`[Slickgrid-Universal] Flatpickr missing locale imports (zz), will revert to English as the default locale.`));
done();
});
});

it('should display text in new locale', async () => {
await (await import('flatpickr/dist/l10n/fr')).French;
gridOptionMock.translater = translateService;

translateService.use('fr');
editor = new DateEditor(editorArguments);

const spy = jest.spyOn(editor.flatInstance, 'open');
Expand All @@ -450,7 +464,6 @@ describe('DateEditor', () => {
expect(selectonOptionElms.length).toBe(12);
expect(selectonOptionElms[0].textContent).toBe('janvier');
expect(spy).toHaveBeenCalled();
done();
});
});
});
Expand Down
23 changes: 8 additions & 15 deletions packages/common/src/editors/dateEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,15 @@ export class DateEditor implements Editor {
dateFormat: inputFormat,
closeOnSelect: true,
wrap: true,
locale: (currentLocale !== 'en') ? this.loadFlatpickrLocale(currentLocale) : 'en',
locale: currentLocale,
onChange: () => this.handleOnDateChange(),
errorHandler: () => {
// do nothing, Flatpickr is a little too sensitive and will throw an error when provided date is lower than minDate so just disregard the error completely
errorHandler: (error: Error) => {
if (error.toString().includes('invalid locale')) {
console.warn(`[Slickgrid-Universal] Flatpickr missing locale imports (${currentLocale}), will revert to English as the default locale.
See Flatpickr Localization for more info, for example if we want to use French, then we can import it with: import 'flatpickr/dist/l10n/fr';`);
}
// for any other error do nothing
// Flatpickr is a little too sensitive and will throw an error when provided date is lower than minDate so just disregard the error completely
}
};

Expand Down Expand Up @@ -404,16 +409,4 @@ export class DateEditor implements Editor {
}
grid.onCompositeEditorChange.notify({ ...activeCell, item, grid, column, formValues: compositeEditorOptions.formValues, editors: compositeEditorOptions.editors }, new Slick.EventData());
}

/** Load a different set of locales for Flatpickr to be localized */
private loadFlatpickrLocale(language: string) {
let locales = 'en';

if (language !== 'en') {
// change locale if needed, Flatpickr reference: https://chmln.github.io/flatpickr/localization/
const localeDefault: any = require(`flatpickr/dist/l10n/${language}.js`).default;
locales = (localeDefault && localeDefault[language]) ? localeDefault[language] : 'en';
}
return locales;
}
}
20 changes: 13 additions & 7 deletions packages/common/src/filters/__tests__/compoundDateFilter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ describe('CompoundDateFilter', () => {
closeOnSelect: true,
dateFormat: 'Y-m-d',
defaultDate: '',
errorHandler: expect.toBeFunction(),
locale: 'en',
onChange: expect.anything(),
wrap: true,
Expand Down Expand Up @@ -207,8 +208,10 @@ describe('CompoundDateFilter', () => {
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: '<=', searchTerms: ['2000-01-01T05:00:00.000Z'], shouldTriggerQuery: true });
});

it('should work with different locale when locale is changed', () => {
translateService.use('fr-CA'); // will be trimmed to "fr"
it('should work with different locale when locale is changed', async () => {
await (await import('flatpickr/dist/l10n/fr')).French;

translateService.use('fr');
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z'];
mockColumn.filter!.operator = '<=';
const spyCallback = jest.spyOn(filterArguments, 'callback');
Expand All @@ -233,10 +236,10 @@ describe('CompoundDateFilter', () => {
expect(selectonOptionElms[0].textContent).toBe('janvier');
});

it('should throw an error and use English locale when user tries to load an unsupported Flatpickr locale', () => {
translateService.use('zx');
it('should display a console warning when locale is not previously imported', (done) => {
const consoleSpy = jest.spyOn(global.console, 'warn').mockReturnValue();

translateService.use('zz-yy'); // will be trimmed to 2 chars "zz"
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z'];
mockColumn.filter!.operator = '<=';

Expand All @@ -250,9 +253,12 @@ describe('CompoundDateFilter', () => {
filterInputElm.focus();
filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));

expect(consoleSpy).toHaveBeenCalledWith(expect.toInclude('[Slickgrid-Universal - CompoundDate Filter] It seems that "zx" is not a locale supported by Flatpickr'));
expect(selectonOptionElms.length).toBe(12);
expect(selectonOptionElms[0].textContent).toBe('January');
setTimeout(() => {
expect(selectonOptionElms.length).toBe(12);
expect(selectonOptionElms[0].textContent).toBe('January');
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining(`[Slickgrid-Universal] Flatpickr missing locale imports (zz), will revert to English as the default locale.`));
done();
});
});

it('should trigger a callback with the clear filter set when calling the "clear" method', () => {
Expand Down
20 changes: 13 additions & 7 deletions packages/common/src/filters/__tests__/dateRangeFilter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ describe('DateRangeFilter', () => {
dateFormat: 'Y-m-d',
defaultDate: [],
enableTime: true,
errorHandler: expect.toBeFunction(),
locale: 'en',
mode: 'range',
onChange: expect.anything(),
Expand Down Expand Up @@ -193,8 +194,10 @@ describe('DateRangeFilter', () => {
expect(spyCallback).toHaveBeenCalledWith(expect.anything(), { columnDef: mockColumn, operator: 'RangeInclusive', searchTerms: ['2000-01-01', '2000-01-31'], shouldTriggerQuery: true });
});

it('should work with different locale when locale is changed', () => {
translateService.use('fr-CA'); // will be trimmed to "fr"
it('should work with different locale when locale is changed', async () => {
await (await import('flatpickr/dist/l10n/fr')).French;

translateService.use('fr');
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z'];
mockColumn.filter!.operator = 'RangeInclusive';
const spyCallback = jest.spyOn(filterArguments, 'callback');
Expand All @@ -218,10 +221,10 @@ describe('DateRangeFilter', () => {
expect(selectonOptionElms[0].textContent).toBe('janvier');
});

it('should throw an error and use English locale when user tries to load an unsupported Flatpickr locale', () => {
translateService.use('zx');
it('should display a console warning when locale is not previously imported', (done) => {
const consoleSpy = jest.spyOn(global.console, 'warn').mockReturnValue();

translateService.use('zz-yy'); // will be trimmed to 2 chars "zz"
filterArguments.searchTerms = ['2000-01-01T05:00:00.000Z', '2000-01-31T05:00:00.000Z'];
mockColumn.filter!.operator = 'RangeInclusive';

Expand All @@ -235,9 +238,12 @@ describe('DateRangeFilter', () => {
filterInputElm.focus();
filterInputElm.dispatchEvent(new (window.window as any).KeyboardEvent('keyup', { keyCode: 97, bubbles: true, cancelable: true }));

expect(consoleSpy).toHaveBeenCalledWith(expect.toInclude('[Slickgrid-Universal - DateRange Filter] It seems that "zx" is not a locale supported by Flatpickr'));
expect(selectonOptionElms.length).toBe(12);
expect(selectonOptionElms[0].textContent).toBe('January');
setTimeout(() => {
expect(selectonOptionElms.length).toBe(12);
expect(selectonOptionElms[0].textContent).toBe('January');
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining(`[Slickgrid-Universal] Flatpickr missing locale imports (zz), will revert to English as the default locale.`));
done();
});
});

it('should trigger a callback with the clear filter set when calling the "clear" method', () => {
Expand Down
26 changes: 7 additions & 19 deletions packages/common/src/filters/compoundDateFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ export class CompoundDateFilter implements Filter {
dateFormat: inputFormat,
wrap: true,
closeOnSelect: true,
locale: (currentLocale !== 'en') ? this.loadFlatpickrLocale(currentLocale) : 'en',
locale: currentLocale,
onChange: (selectedDates: Date[] | Date, dateStr: string) => {
this._currentValue = dateStr;
this._currentDate = Array.isArray(selectedDates) && selectedDates[0] || undefined;
Expand All @@ -203,6 +203,12 @@ export class CompoundDateFilter implements Filter {
customEvent = new CustomEvent('keyup');
}
this.onTriggerEvent(customEvent);
},
errorHandler: (error) => {
if (error.toString().includes('invalid locale')) {
console.warn(`[Slickgrid-Universal] Flatpickr missing locale imports (${currentLocale}), will revert to English as the default locale.
See Flatpickr Localization for more info, for example if we want to use French, then we can import it with: import 'flatpickr/dist/l10n/fr';`);
}
}
};

Expand Down Expand Up @@ -298,24 +304,6 @@ export class CompoundDateFilter implements Filter {
return $filterContainerElm;
}

/** Load a different set of locales for Flatpickr to be localized */
private loadFlatpickrLocale(language: string) {
let locales = 'en';

try {
if (language !== 'en') {
// change locale if needed, Flatpickr reference: https://chmln.github.io/flatpickr/localization/
const localeDefault: any = require(`flatpickr/dist/l10n/${language}.js`).default;
locales = (localeDefault && localeDefault[language]) ? localeDefault[language] : 'en';
}
} catch (e) {
console.warn(`[Slickgrid-Universal - CompoundDate Filter] It seems that "${language}" is not a locale supported by Flatpickr, we will use "en" instead. `
+ `To avoid seeing this message, you can specifically set "filter: { filterOptions: { locale: 'en' } }" in your column definition.`);
return 'en';
}
return locales;
}

private onTriggerEvent(e: Event | undefined) {
if (this._clearFilterTriggered) {
this.callback(e, { columnDef: this.columnDef, clearFilterTriggered: this._clearFilterTriggered, shouldTriggerQuery: this._shouldTriggerQuery });
Expand Down
26 changes: 7 additions & 19 deletions packages/common/src/filters/dateRangeFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ export class DateRangeFilter implements Filter {
mode: 'range',
wrap: true,
closeOnSelect: true,
locale: (currentLocale !== 'en') ? this.loadFlatpickrLocale(currentLocale) : 'en',
locale: currentLocale,
onChange: (selectedDates: Date[] | Date, _dateStr: string, _instance: any) => {
if (Array.isArray(selectedDates)) {
this._currentDates = selectedDates;
Expand All @@ -213,6 +213,12 @@ export class DateRangeFilter implements Filter {
// since backend request are only executed after user start typing, changing the time should be treated the same way
const newEvent = pickerOptions.enableTime ? new CustomEvent('keyup') : undefined;
this.onTriggerEvent(newEvent);
},
errorHandler: (error) => {
if (error.toString().includes('invalid locale')) {
console.warn(`[Slickgrid-Universal] Flatpickr missing locale imports (${currentLocale}), will revert to English as the default locale.
See Flatpickr Localization for more info, for example if we want to use French, then we can import it with: import 'flatpickr/dist/l10n/fr';`);
}
}
};

Expand Down Expand Up @@ -269,24 +275,6 @@ export class DateRangeFilter implements Filter {
return this.$filterInputElm;
}

/** Load a different set of locales for Flatpickr to be localized */
private loadFlatpickrLocale(language: string) {
let locales = 'en';

try {
if (language !== 'en') {
// change locale if needed, Flatpickr reference: https://chmln.github.io/flatpickr/localization/
const localeDefault: any = require(`flatpickr/dist/l10n/${language}.js`).default;
locales = (localeDefault && localeDefault[language]) ? localeDefault[language] : 'en';
}
} catch (e) {
console.warn(`[Slickgrid-Universal - DateRange Filter] It seems that "${language}" is not a locale supported by Flatpickr, we will use "en" instead. `
+ `To avoid seeing this message, you can specifically set "filter: { filterOptions: { locale: 'en' } }" in your column definition.`);
return 'en';
}
return locales;
}

private onTriggerEvent(e: Event | undefined) {
if (this._clearFilterTriggered) {
this.callback(e, { columnDef: this.columnDef, clearFilterTriggered: this._clearFilterTriggered, shouldTriggerQuery: this._shouldTriggerQuery });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'flatpickr/dist/l10n/fr';
import 'slickgrid/lib/jquery.event.drag-2.3.0';
import 'slickgrid/lib/jquery.mousewheel';
import 'slickgrid/slick.core';
Expand Down
1 change: 0 additions & 1 deletion test/cypress/screenshots/README.md

This file was deleted.

0 comments on commit 6644822

Please sign in to comment.