Skip to content

Commit

Permalink
refactor: implement .fire() to replace dispatchCustomEvent helper
Browse files Browse the repository at this point in the history
  • Loading branch information
motss committed Nov 14, 2021
1 parent 52d5b7a commit c411e13
Show file tree
Hide file tree
Showing 18 changed files with 205 additions and 136 deletions.
15 changes: 10 additions & 5 deletions src/__tests__/date-picker/app-date-picker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import { elementUpdated, fixture, html, oneEvent } from '@open-wc/testing-helper
import { MAX_DATE } from '../../constants';
import type { AppDatePicker } from '../../date-picker/app-date-picker';
import { appDatePickerName } from '../../date-picker/constants';
import { toDateString } from '../../helpers/to-date-string';
import { toFormatters } from '../../helpers/to-formatters';
import { toResolvedDate } from '../../helpers/to-resolved-date';
import type { MaybeDate } from '../../helpers/typings';
import type { AppMonthCalendar } from '../../month-calendar/app-month-calendar';
import type { DateUpdatedEvent, Formatters, StartView } from '../../typings';
import type { CustomEventDetail, Formatters, StartView } from '../../typings';
import type { AppYearGrid } from '../../year-grid/app-year-grid';
import { messageFormatter } from '../test-utils/message-formatter';

Expand Down Expand Up @@ -297,9 +298,11 @@ describe(appDatePickerName, () => {
newSelectedDate2
);

const expectedDateUpdatedEvent: DateUpdatedEvent = {
const expectedDateUpdatedEvent: CustomEventDetail['date-updated']['detail'] = {
isKeypress: false,
value: newSelectedDate2,
value: toDateString(newSelectedDate2),
valueAsDate: newSelectedDate2,
valueAsNumber: +newSelectedDate2,
};

expect(dateUpdatedEvent.detail).deep.equal(expectedDateUpdatedEvent);
Expand Down Expand Up @@ -351,9 +354,11 @@ describe(appDatePickerName, () => {
);
expect(selectedDate?.fullDate).deep.equal(newSelectedDate);

const expectedDateUpdatedEvent: DateUpdatedEvent = {
const expectedDateUpdatedEvent: CustomEventDetail['date-updated']['detail'] = {
isKeypress: false,
value: newSelectedDate,
value: toDateString(newSelectedDate),
valueAsDate: newSelectedDate,
valueAsNumber: +newSelectedDate,
};

expect(dateUpdatedEvent.detail).deep.equal(expectedDateUpdatedEvent);
Expand Down
46 changes: 0 additions & 46 deletions src/__tests__/helpers/dispatch-custom-event.test.ts

This file was deleted.

12 changes: 8 additions & 4 deletions src/__tests__/month-calendar/app-month-calendar.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import { getWeekdays } from 'nodemod/dist/calendar/helpers/get-weekdays.js';
import type { CalendarInit } from 'nodemod/dist/calendar/typings';

import type { confirmKeySet, navigationKeySetGrid } from '../../constants';
import { toDateString } from '../../helpers/to-date-string';
import { toFormatters } from '../../helpers/to-formatters';
import type { AppMonthCalendar } from '../../month-calendar/app-month-calendar';
import { appMonthCalendarName } from '../../month-calendar/constants';
import type { MonthCalendarData } from '../../month-calendar/typings';
import type { DateUpdatedEvent, InferredFromSet } from '../../typings';
import type { CustomEventDetail, InferredFromSet } from '../../typings';
import { messageFormatter } from '../test-utils/message-formatter';

describe(appMonthCalendarName, () => {
Expand Down Expand Up @@ -204,7 +205,7 @@ describe(appMonthCalendarName, () => {

const dateUpdatedEventTask = new Promise((resolve) => {
el.addEventListener('date-updated', function fn(ev) {
resolve((ev as CustomEvent<DateUpdatedEvent>).detail);
resolve((ev as CustomEvent<CustomEventDetail['date-updated']['detail']>).detail);

el.removeEventListener('date-updated', fn);
});
Expand Down Expand Up @@ -244,9 +245,12 @@ describe(appMonthCalendarName, () => {
expect(newSelectedDate?.fullDate).deep.equal(calendarInit.date);

const isKeypress = testEventType === 'keydown';
const expectedDateUpdatedEvent: DateUpdatedEvent = {
const expectedDate = new Date('2020-02-09');
const expectedDateUpdatedEvent: CustomEventDetail['date-updated']['detail'] = {
isKeypress,
value: new Date('2020-02-09'),
value: toDateString(expectedDate),
valueAsDate: expectedDate,
valueAsNumber: +expectedDate,
...(isKeypress && { key: testKeyPayloads[0].down }),
};

Expand Down
6 changes: 3 additions & 3 deletions src/__tests__/year-grid/app-year-grid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { sendKeys } from '@web/test-runner-commands';

import type { confirmKeySet } from '../../constants';
import { toFormatters } from '../../helpers/to-formatters';
import type { InferredFromSet, YearUpdatedEvent } from '../../typings';
import type { CustomEventDetail, InferredFromSet } from '../../typings';
import type { AppYearGrid } from '../../year-grid/app-year-grid';
import { appYearGridName } from '../../year-grid/constants';
import type { YearGridData } from '../../year-grid/typings';
Expand Down Expand Up @@ -98,7 +98,7 @@ describe(appYearGridName, () => {

const yearUpdatedEventTask = new Promise((resolve) => {
function fn(ev: Event) {
resolve((ev as CustomEvent<YearUpdatedEvent>).detail);
resolve((ev as CustomEvent<CustomEventDetail['year-updated']['detail']>).detail);
el.removeEventListener('year-updated', fn);
}

Expand Down Expand Up @@ -135,7 +135,7 @@ describe(appYearGridName, () => {
n.getAttribute('tabindex') ?? '',
n.getAttribute('aria-selected') ?? '',
]);
const expectedYearUpdatedEvent: YearUpdatedEvent = {
const expectedYearUpdatedEvent: CustomEventDetail['year-updated']['detail'] = {
year: data.max.getUTCFullYear(),
};

Expand Down
13 changes: 13 additions & 0 deletions src/date-picker-dialog/app-date-picker-dialog-base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { customElement } from 'lit/decorators.js';

import { appDatePickerDialogBaseName } from './constants.js';
import { DatePickerDialogBase } from './date-picker-dialog-base.js';

@customElement(appDatePickerDialogBaseName)
export class AppDatePickerDialogBase extends DatePickerDialogBase {}

declare global {
interface HTMLElementTagNameMap {
[appDatePickerDialogBaseName]: AppDatePickerDialogBase;
}
}
2 changes: 2 additions & 0 deletions src/date-picker-dialog/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const appDatePickerDialogBaseName = 'app-date-picker-dialog-base' as const;
export const appDatePickerDialogName = 'app-date-picker-dialog' as const;
10 changes: 10 additions & 0 deletions src/date-picker-dialog/date-picker-dialog-base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Dialog } from '@material/mwc-dialog';

import { datePickerDialogBaseStyling } from './stylings.js';

export class DatePickerDialogBase extends Dialog {
public static override styles = [
...Dialog.styles,
datePickerDialogBaseStyling,
];
}
19 changes: 19 additions & 0 deletions src/date-picker-dialog/stylings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { css, unsafeCSS } from 'lit';

import { appDatePickerDialogName } from './constants.js';

export const datePickerDialogBaseStyling = css`
:host {
display: block;
}
.mdc-dialog__content {
padding: 0;
}
`;

export const datePickerDialogStyling = css`
${unsafeCSS(appDatePickerDialogName)} {
display: block;
}
`;
16 changes: 16 additions & 0 deletions src/date-picker-dialog/typings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Dialog } from '@material/mwc-dialog';

export interface DatePickerDialogProperties extends DialogProperties {
confirmLabel: string;
dismissLabel: string;
resetLabel: string;
show(): void;
}

export interface DialogClosingEventDetail {
action: DialogClosingEventDetailAction;
}

export type DialogClosingEventDetailAction = 'cancel' | 'reset' | 'set';

type DialogProperties = Pick<Dialog, 'open'>;
19 changes: 11 additions & 8 deletions src/date-picker-input/date-picker-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { DatePickerMinMaxMixin } from '../mixins/date-picker-min-max-mixin.js';
import { DatePickerMixin } from '../mixins/date-picker-mixin.js';
import { ElementMixin } from '../mixins/element-mixin.js';
import type { DatePickerMixinProperties } from '../mixins/typings.js';
import type { ChangedProperties, DatePickerProperties, SupportedCustomEventDetail } from '../typings.js';
import type { ChangedProperties, CustomEventDetail, DatePickerProperties } from '../typings.js';
import { datePickerInputStyling } from './stylings.js';

export class DatePickerInput extends ElementMixin(DatePickerMixin(DatePickerMinMaxMixin(TextField))) implements DatePickerMixinProperties {
Expand Down Expand Up @@ -193,21 +193,24 @@ export class DatePickerInput extends ElementMixin(DatePickerMixin(DatePickerMinM
this._open = false;
}

#onDatePickerFirstUpdated(ev: CustomEvent<SupportedCustomEventDetail['first-updated']>): void {
const [focusableElement] = ev.detail.focusableElements;

this.#picker = ev.currentTarget as AppDatePicker;
#onDatePickerFirstUpdated({
currentTarget,
detail: {
focusableElements: [focusableElement],
},
}: CustomEvent<CustomEventDetail['first-updated']['detail']>): void {
this.#picker = currentTarget as AppDatePicker;
this.#focusElement = focusableElement;
}

async #onDatePickerDateUpdated(ev: CustomEvent<SupportedCustomEventDetail['date-updated']>): Promise<void> {
async #onDatePickerDateUpdated(ev: CustomEvent<CustomEventDetail['date-updated']['detail']>): Promise<void> {
const {
isKeypress,
key,
value,
valueAsDate,
} = ev.detail;

this.value = this.#valueFormatter.format(value);
this.value = this.#valueFormatter.format(valueAsDate);

if (isKeypress && (key === 'Enter' || key === ' ')) {
(await this.$inputSurface)?.close();
Expand Down
59 changes: 46 additions & 13 deletions src/date-picker/date-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { toUTCDate } from 'nodemod/dist/calendar/helpers/to-utc-date.js';
import { DateTimeFormat, MAX_DATE, startViews } from '../constants.js';
import { clampValue } from '../helpers/clamp-value.js';
import { dateValidator } from '../helpers/date-validator.js';
import { dispatchCustomEvent } from '../helpers/dispatch-custom-event.js';
import { focusElement } from '../helpers/focus-element.js';
import { isInCurrentMonth } from '../helpers/is-in-current-month.js';
import { splitString } from '../helpers/split-string.js';
Expand All @@ -28,15 +27,20 @@ import { DatePickerMixin } from '../mixins/date-picker-mixin.js';
import type { AppMonthCalendar } from '../month-calendar/app-month-calendar.js';
import { RootElement } from '../root-element/root-element.js';
import { resetShadowRoot, webkitScrollbarStyling } from '../stylings.js';
import type { DatePickerProperties, Formatters, StartView, ValueUpdatedEvent, YearUpdatedEvent } from '../typings.js';
import type { CustomEventDetail, DatePickerProperties, Formatters, StartView, ValueUpdatedEvent } from '../typings.js';
import type { AppYearGrid } from '../year-grid/app-year-grid.js';
import type { YearGridData } from '../year-grid/typings.js';
import { datePickerStyling } from './stylings.js';
import type { DatePickerChangedProperties } from './typings.js';

export class DatePicker extends DatePickerMixin(DatePickerMinMaxMixin(RootElement)) implements DatePickerProperties {
public valueAsDate: Date;
public valueAsNumber: number;
public get valueAsDate(): Date {
return this.#valueAsDate;
}

public get valueAsNumber(): number {
return +this.#valueAsDate;
}

@queryAsync('app-month-calendar') private readonly _monthCalendar!: Promise<AppMonthCalendar | null>;

Expand All @@ -59,6 +63,7 @@ export class DatePicker extends DatePickerMixin(DatePickerMinMaxMixin(RootElemen
#formatters: Formatters;
#focusNavButtonWithKey = false;
#today: Date;
#valueAsDate: Date;

public static override styles = [
resetShadowRoot,
Expand All @@ -77,8 +82,7 @@ export class DatePicker extends DatePickerMixin(DatePickerMinMaxMixin(RootElemen
this._selectedDate = new Date(todayDate);
this._currentDate = new Date(todayDate);
this.#formatters = toFormatters(this.locale);
this.valueAsDate = new Date(todayDate);
this.valueAsNumber = +todayDate;
this.#valueAsDate = new Date(todayDate);
}

public override willUpdate(changedProperties: DatePickerChangedProperties): void {
Expand Down Expand Up @@ -140,9 +144,26 @@ export class DatePicker extends DatePickerMixin(DatePickerMinMaxMixin(RootElemen
this._max = newMax.date;
this._currentDate = new Date(valueDate);
this._selectedDate = new Date(valueDate);
this.valueAsDate = new Date(valueDate);
this.valueAsNumber = +valueDate;
this.value = toDateString(valueDate);
this.#valueAsDate = new Date(valueDate);

/**
* Always override `value` when its value is nullish and dispatch `date-updated` event.
*/
if (this.value === null) {
const valueStr = toDateString(valueDate);

this.value = valueStr;

this.fire<CustomEventDetail['date-updated']>({
detail: {
isKeypress: false,
value: valueStr,
valueAsDate: new Date(valueDate),
valueAsNumber: +valueDate,
},
type: 'date-updated',
});
}
}

if (changedProperties.has('startView')) {
Expand Down Expand Up @@ -173,9 +194,16 @@ export class DatePicker extends DatePickerMixin(DatePickerMinMaxMixin(RootElemen
}

protected override async firstUpdated(): Promise<void> {
dispatchCustomEvent(this, 'first-updated', {
focusableElements: await this.#queryAllFocusable(),
value: this.value,
const valueAsDate = this.#valueAsDate;

this.fire<CustomEventDetail['first-updated']>({
detail: {
focusableElements: await this.#queryAllFocusable(),
value: toDateString(valueAsDate),
valueAsDate: new Date(valueAsDate),
valueAsNumber: +valueAsDate,
},
type: 'first-updated',
});
}

Expand Down Expand Up @@ -385,6 +413,11 @@ export class DatePicker extends DatePickerMixin(DatePickerMinMaxMixin(RootElemen

this._selectedDate = newSelectedDate;
this._currentDate = new Date(newSelectedDate);

/**
* Always update `value` just like other native element such as `input`.
*/
this.value = toDateString(newSelectedDate);
}

#updateSelectedDate({
Expand All @@ -399,7 +432,7 @@ export class DatePicker extends DatePickerMixin(DatePickerMinMaxMixin(RootElemen

#updateYear({
detail: { year },
}: CustomEvent<YearUpdatedEvent>): void {
}: CustomEvent<CustomEventDetail['year-updated']['detail']>): void {
this.#updateSelectedAndCurrentDate(this._selectedDate.setUTCFullYear(year));
this.startView = 'calendar';
}
Expand Down
13 changes: 0 additions & 13 deletions src/helpers/dispatch-custom-event.ts

This file was deleted.

0 comments on commit c411e13

Please sign in to comment.