From 01fc9b45116f7ad6ddc56c7fb1535dec798c2b3a Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Mon, 28 Aug 2023 08:39:19 -0500 Subject: [PATCH] fix(datetime): gracefully handle invalid min/max (#28054) Issue number: resolves #28041 --------- ## What is the current behavior? `parseDate` returns `undefined` when given an invalid value. However, our min/max processing functions did not account for this. As a result, we would attempt to destructure an undefined value which resulted in an error. Note regarding linked issue: The developer is calling `setMin(undefined)`. However, this is triggering a React quirk with Custom Elements where `undefined` is being set to `null` inside of React. The type signature on min/max is `string | undefined`, so `null` is being treated as an invalid date value. ## What is the new behavior? - Min/Max processing functions now return `undefined` if the input was invalid. ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information Dev build: `7.3.2-dev.11692887667.1614d10a` --- .../components/datetime/test/parse.spec.ts | 24 +++++++++++++++++ core/src/components/datetime/utils/parse.ts | 26 ++++++++++++++++--- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/core/src/components/datetime/test/parse.spec.ts b/core/src/components/datetime/test/parse.spec.ts index 282ec75a42..ea2e5132b0 100644 --- a/core/src/components/datetime/test/parse.spec.ts +++ b/core/src/components/datetime/test/parse.spec.ts @@ -154,6 +154,18 @@ describe('parseMinParts()', () => { minute: 30, }); }); + it('should return undefined when given invalid info', () => { + const today = { + day: 14, + month: 3, + year: 2022, + minute: 4, + hour: 2, + }; + expect(parseMinParts(undefined, today)).toEqual(undefined); + expect(parseMinParts(null, today)).toEqual(undefined); + expect(parseMinParts('foo', today)).toEqual(undefined); + }); }); describe('parseMaxParts()', () => { @@ -205,4 +217,16 @@ describe('parseMaxParts()', () => { minute: 59, }); }); + it('should return undefined when given invalid info', () => { + const today = { + day: 14, + month: 3, + year: 2022, + minute: 4, + hour: 2, + }; + expect(parseMaxParts(undefined, today)).toEqual(undefined); + expect(parseMaxParts(null, today)).toEqual(undefined); + expect(parseMaxParts('foo', today)).toEqual(undefined); + }); }); diff --git a/core/src/components/datetime/utils/parse.ts b/core/src/components/datetime/utils/parse.ts index fda79085ac..04cd521310 100644 --- a/core/src/components/datetime/utils/parse.ts +++ b/core/src/components/datetime/utils/parse.ts @@ -132,8 +132,17 @@ export const parseAmPm = (hour: number) => { * For example, max="2012" would fill in the missing * month, day, hour, and minute information. */ -export const parseMaxParts = (max: string, todayParts: DatetimeParts): DatetimeParts => { - const { month, day, year, hour, minute } = parseDate(max); +export const parseMaxParts = (max: string, todayParts: DatetimeParts): DatetimeParts | undefined => { + const result = parseDate(max); + + /** + * If min was not a valid date then return undefined. + */ + if (result === undefined) { + return; + } + + const { month, day, year, hour, minute } = result; /** * When passing in `max` or `min`, developers @@ -168,8 +177,17 @@ export const parseMaxParts = (max: string, todayParts: DatetimeParts): DatetimeP * For example, min="2012" would fill in the missing * month, day, hour, and minute information. */ -export const parseMinParts = (min: string, todayParts: DatetimeParts): DatetimeParts => { - const { month, day, year, hour, minute } = parseDate(min); +export const parseMinParts = (min: string, todayParts: DatetimeParts): DatetimeParts | undefined => { + const result = parseDate(min); + + /** + * If min was not a valid date then return undefined. + */ + if (result === undefined) { + return; + } + + const { month, day, year, hour, minute } = result; /** * When passing in `max` or `min`, developers