From d8ab66840b718ac83f634827b703a7a501d0eb81 Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Sun, 26 May 2024 21:32:04 -0400 Subject: [PATCH] Handle validation for YYYY-MM-DD format --- .../forms/DatePicker/DatePicker.tsx | 12 +++++- src/components/forms/DatePicker/utils.test.ts | 42 ++++++++++++++++--- src/components/forms/DatePicker/utils.tsx | 14 ++++++- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/components/forms/DatePicker/DatePicker.tsx b/src/components/forms/DatePicker/DatePicker.tsx index f2eeff1bbf..a5f563254d 100644 --- a/src/components/forms/DatePicker/DatePicker.tsx +++ b/src/components/forms/DatePicker/DatePicker.tsx @@ -97,7 +97,12 @@ export const DatePicker = ({ const parsedRangeDate = rangeDate ? parseDateString(rangeDate) : undefined const validateInput = (): void => { - const isInvalid = isDateInvalid(externalValue, parsedMinDate, parsedMaxDate) + const isInvalid = isDateInvalid( + externalValue, + dateFormat, + parsedMinDate, + parsedMaxDate + ) if (isInvalid && !externalInputEl?.current?.validationMessage) { externalInputEl?.current?.setCustomValidity(VALIDATION_MESSAGE) @@ -134,7 +139,10 @@ export const DatePicker = ({ const inputDate = parseDateString(value, dateFormat, true) let newValue = '' - if (inputDate && !isDateInvalid(value, parsedMinDate, parsedMaxDate)) { + if ( + inputDate && + !isDateInvalid(value, dateFormat, parsedMinDate, parsedMaxDate) + ) { newValue = formatDate(inputDate) } diff --git a/src/components/forms/DatePicker/utils.test.ts b/src/components/forms/DatePicker/utils.test.ts index 8b7ee8eefc..7734ec38c4 100644 --- a/src/components/forms/DatePicker/utils.test.ts +++ b/src/components/forms/DatePicker/utils.test.ts @@ -84,32 +84,64 @@ describe('isDateInvalid', () => { it('returns false if the date is within the min & max', () => { const testMin = new Date('May 1, 1988') const testMax = new Date('June 1, 1988') - expect(isDateInvalid('05/16/1988', testMin, testMax)).toEqual(false) + expect( + isDateInvalid( + '05/16/1988', + DEFAULT_EXTERNAL_DATE_FORMAT, + testMin, + testMax + ) + ).toEqual(false) }) it('returns true if the date is not within the min & max', () => { const testMin = new Date('May 1, 1988') const testMax = new Date('June 1, 1988') - expect(isDateInvalid('08/16/1988', testMin, testMax)).toEqual(true) + expect( + isDateInvalid( + '08/16/1988', + DEFAULT_EXTERNAL_DATE_FORMAT, + testMin, + testMax + ) + ).toEqual(true) }) it('returns true if the date is not valid', () => { const testMin = new Date('May 1, 1988') const testMax = new Date('June 1, 1988') - expect(isDateInvalid('not a date', testMin, testMax)).toEqual(true) + expect( + isDateInvalid( + 'not a date', + DEFAULT_EXTERNAL_DATE_FORMAT, + testMin, + testMax + ) + ).toEqual(true) }) describe('with no max date', () => { it('returns false if the date is after the min', () => { const testMin = new Date('May 1, 1988') - expect(isDateInvalid('05/16/1988', testMin)).toEqual(false) + expect( + isDateInvalid('05/16/1988', DEFAULT_EXTERNAL_DATE_FORMAT, testMin) + ).toEqual(false) }) it('returns true if the date is not after the min', () => { const testMin = new Date('May 1, 1988') - expect(isDateInvalid('02/16/1988', testMin)).toEqual(true) + expect( + isDateInvalid('02/16/1988', DEFAULT_EXTERNAL_DATE_FORMAT, testMin) + ).toEqual(true) }) }) + + describe('with YYYY-MM-DD date format', () => { + const testMin = new Date('May 1, 1988') + expect(isDateInvalid('1988-16-02', INTERNAL_DATE_FORMAT, testMin)).toEqual( + true + ) + }) }) describe('isDateWithinMinAndMax', () => { diff --git a/src/components/forms/DatePicker/utils.tsx b/src/components/forms/DatePicker/utils.tsx index a4629ef310..f090df1be8 100644 --- a/src/components/forms/DatePicker/utils.tsx +++ b/src/components/forms/DatePicker/utils.tsx @@ -460,6 +460,7 @@ export const formatDate = ( export const isDateInvalid = ( dateString: string, + dateFormat: DateFormat, minDate: Date, maxDate?: Date ): boolean => { @@ -468,14 +469,23 @@ export const isDateInvalid = ( if (dateString) { isInvalid = true - const dateStringParts = dateString.split('/') - const [month, day, year] = dateStringParts.map((str) => { + const dateStringParts = dateString.split( + dateFormat === DEFAULT_EXTERNAL_DATE_FORMAT ? '/' : '-' + ) + const dateParts = dateStringParts.map((str) => { let value const parsed = parseInt(str, 10) if (!Number.isNaN(parsed)) value = parsed return value }) + let month, day, year + if (dateFormat === DEFAULT_EXTERNAL_DATE_FORMAT) { + ;[month, day, year] = dateParts + } else { + ;[year, month, day] = dateParts + } + if (month && day && year != null) { const checkDate = setDate(year, month - 1, day)