From 3a7f5f166ee8d8d7e1861313e2bc6f4856e4fbe9 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Tue, 19 Jul 2022 16:41:27 -0400 Subject: [PATCH] fix(datetime): account for previous years with preferWheel (#25656) --- .../test/prefer-wheel/datetime.e2e.ts | 34 ++++++++++++++++ core/src/components/datetime/utils/data.ts | 39 +++++++++++++++---- 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/core/src/components/datetime/test/prefer-wheel/datetime.e2e.ts b/core/src/components/datetime/test/prefer-wheel/datetime.e2e.ts index 2326d87fce4..3072c7fc039 100644 --- a/core/src/components/datetime/test/prefer-wheel/datetime.e2e.ts +++ b/core/src/components/datetime/test/prefer-wheel/datetime.e2e.ts @@ -198,6 +198,23 @@ test.describe('datetime: prefer wheel', () => { expect(dateValues).toHaveText(['2月1日(火)', '2月2日(水)', '2月3日(木)']); }); + test('should respect min and max bounds even across years', async ({ page }) => { + await page.setContent(` + + `); + + await page.waitForSelector('.datetime-ready'); + + const dateValues = page.locator('.date-column .picker-item:not(.picker-item-empty)'); + + expect(await dateValues.count()).toBe(427); + }); }); test.describe('datetime: time-date wheel rendering', () => { test('should not have visual regressions', async ({ page }) => { @@ -286,5 +303,22 @@ test.describe('datetime: prefer wheel', () => { expect(dateValues).toHaveText(['2月1日(火)', '2月2日(水)', '2月3日(木)']); }); + test('should respect min and max bounds even across years', async ({ page }) => { + await page.setContent(` + + `); + + await page.waitForSelector('.datetime-ready'); + + const dateValues = page.locator('.date-column .picker-item:not(.picker-item-empty)'); + + expect(await dateValues.count()).toBe(427); + }); }); }); diff --git a/core/src/components/datetime/utils/data.ts b/core/src/components/datetime/utils/data.ts index c44831c0717..ed11abc0405 100644 --- a/core/src/components/datetime/utils/data.ts +++ b/core/src/components/datetime/utils/data.ts @@ -413,6 +413,19 @@ interface CombinedDateColumnData { items: PickerColumnItem[]; } +/** + * Given a starting date and an upper bound, + * this functions returns an array of all + * month objects in that range. + */ +const getAllMonthsInRange = (currentParts: DatetimeParts, maxParts: DatetimeParts): DatetimeParts[] => { + if (currentParts.month === maxParts.month && currentParts.year === maxParts.year) { + return [currentParts]; + } + + return [currentParts, ...getAllMonthsInRange(getNextMonth(currentParts), maxParts)]; +}; + /** * Creates and returns picker items * that represent the days in a month. @@ -422,16 +435,28 @@ export const getCombinedDateColumnData = ( locale: string, refParts: DatetimeParts, todayParts: DatetimeParts, - minParts?: DatetimeParts, - maxParts?: DatetimeParts, + minParts: DatetimeParts, + maxParts: DatetimeParts, dayValues?: number[], monthValues?: number[] ): CombinedDateColumnData => { let items: PickerColumnItem[] = []; let parts: DatetimeParts[] = []; - // TODO(FW-1693) This does not work when the previous month is in the previous year. - const months = getMonthColumnData(locale, refParts, minParts, maxParts, monthValues, { month: 'short' }); + /** + * Get all month objects from the min date + * to the max date. Note: Do not use getMonthColumnData + * as that function only generates dates within a + * single year. + */ + let months = getAllMonthsInRange(minParts, maxParts); + + /** + * Filter out any disallowed month values. + */ + if (monthValues) { + months = months.filter(({ month }) => monthValues.includes(month)); + } /** * Get all of the days in the month. @@ -440,7 +465,7 @@ export const getCombinedDateColumnData = ( * of work as the text. */ months.forEach((monthObject) => { - const referenceMonth = { month: monthObject.value as number, day: null, year: refParts.year }; + const referenceMonth = { month: monthObject.month, day: null, year: refParts.year }; const monthDays = getDayColumnData(locale, referenceMonth, minParts, maxParts, dayValues, { month: 'short', day: 'numeric', @@ -459,7 +484,7 @@ export const getCombinedDateColumnData = ( */ dateColumnItems.push({ text: isToday ? getTodayLabel(locale) : dayObject.text, - value: `${refParts.year}-${monthObject.value}-${dayObject.value}`, + value: `${refParts.year}-${monthObject.month}-${dayObject.value}`, }); /** @@ -473,7 +498,7 @@ export const getCombinedDateColumnData = ( * updating the picker column value. */ dateParts.push({ - month: monthObject.value as number, + month: monthObject.month, year: refParts.year, day: dayObject.value as number, });