Skip to content

Commit

Permalink
refactor in-component modifier function out into its own Modifier Class.
Browse files Browse the repository at this point in the history
  • Loading branch information
stopfstedt committed Jan 16, 2025
1 parent 72c23b0 commit 552234e
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 73 deletions.
2 changes: 1 addition & 1 deletion packages/ilios-common/addon/components/date-picker.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
aria-label={{t "general.pickADate"}}
class="date-picker"
data-test-date-picker
{{this.picker @value @minDate @maxDate this.intl.primaryLocale}}
{{date-picker @value @minDate @maxDate this.intl.primaryLocale @onChange}}
...attributes
/>
72 changes: 0 additions & 72 deletions packages/ilios-common/addon/components/date-picker.js

This file was deleted.

87 changes: 87 additions & 0 deletions packages/ilios-common/addon/modifiers/date-picker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import Modifier from 'ember-modifier';
import { registerDestructor } from '@ember/destroyable';
import flatpickr from 'flatpickr';
import { French } from 'flatpickr/dist/l10n/fr.js';
import { Spanish } from 'flatpickr/dist/l10n/es.js';
import { next } from '@ember/runloop';
import { isTesting } from '@embroider/macros';
import { service } from '@ember/service';

function cleanup(instance) {
instance.locale = null;
instance.onChangeHandler = null;
if (instance.flatpickr) {
instance.flatpickr.destroy();
instance.flatpickr = null;
}
}

export default class DatePickerModifier extends Modifier {
@service intl;
flatpickr = null;
locale = null;
onChangeHandler = null;

constructor(owner, args) {
super(owner, args);
registerDestructor(this, cleanup);
}

modify(element, [value, minDate, maxDate, locale, onChangeHandler]) {
// We only need to set this once.
if (!this.onChangeHandler) {
this.onChangeHandler = onChangeHandler;
}
if (!this.flatpickr) {
this.flatpickr = this.initPicker(element, value, minDate, maxDate, locale);
this.locale = locale;
}

if (this.flatpickr.selectedDates[0] !== value) {
this.flatpickr.setDate(value);
}
if (this.flatpickr.minDate !== minDate) {
this.flatpickr.set('minDate', minDate);
}
if (this.flatpickr.maxDate !== maxDate) {
this.flatpickr.set('maxDate', maxDate);
}

if (this.locale !== locale) {
this.locale = locale;
this.flatpickr.set('locale', this.getFlatpickrLocale(locale));
}
}

// @see https://flatpickr.js.org/localization/
getFlatpickrLocale(localeIdentifier) {
switch (localeIdentifier) {
case 'fr':
return French;
case 'es':
return Spanish;
default:
return 'en';
}
}

initPicker(element, value, minDate, maxDate, locale) {
return flatpickr(element, {
locale: this.getFlatpickrLocale(locale),
defaultDate: value,
formatDate: (dateObj) =>
this.intl.formatDate(dateObj, { day: '2-digit', month: '2-digit', year: 'numeric' }),
onChange: (selectedDates) => this.onChange(selectedDates[0]),
maxDate: maxDate ?? null,
minDate: minDate ?? null,
disableMobile: isTesting(),
});
}
async onChange(date) {
if (this.onChangeHandler) {
await this.onChangeHandler(date);
}
// eslint-disable-next-line ember/no-runloop
await next(() => {});
}
}
1 change: 1 addition & 0 deletions packages/ilios-common/app/modifiers/date-picker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from 'ilios-common/modifiers/date-picker';
21 changes: 21 additions & 0 deletions packages/test-app/tests/integration/modifiers/date-picker-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'test-app/tests/helpers';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';

// todo: flesh this out. [ST 2025/01/19]
module('Integration | Modifier | date-picker', function (hooks) {
setupRenderingTest(hooks);

test('it works with minimal input', async function (assert) {
this.set('value', Date.now());
this.set('minDate', null);
this.set('maxDate', null);
this.set('locale', 'en');
await render(
hbs`<div {{date-picker this.value this.minDate this.maxDate this.locale (noop)}}></div>`,
);
// todo: add more test assertions here.
assert.ok(true);
});
});

0 comments on commit 552234e

Please sign in to comment.