Skip to content

Commit 821c09b

Browse files
committed
Handle validation for YYYY-MM-DD format
1 parent 5b9182c commit 821c09b

File tree

3 files changed

+79
-30
lines changed

3 files changed

+79
-30
lines changed

src/components/forms/DatePicker/DatePicker.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,12 @@ export const DatePicker = ({
9797
const parsedRangeDate = rangeDate ? parseDateString(rangeDate) : undefined
9898

9999
const validateInput = (): void => {
100-
const isInvalid = isDateInvalid(externalValue, parsedMinDate, parsedMaxDate)
100+
const isInvalid = isDateInvalid(
101+
externalValue,
102+
dateFormat,
103+
parsedMinDate,
104+
parsedMaxDate
105+
)
101106

102107
if (isInvalid && !externalInputEl?.current?.validationMessage) {
103108
externalInputEl?.current?.setCustomValidity(VALIDATION_MESSAGE)
@@ -134,7 +139,10 @@ export const DatePicker = ({
134139

135140
const inputDate = parseDateString(value, dateFormat, true)
136141
let newValue = ''
137-
if (inputDate && !isDateInvalid(value, parsedMinDate, parsedMaxDate)) {
142+
if (
143+
inputDate &&
144+
!isDateInvalid(value, dateFormat, parsedMinDate, parsedMaxDate)
145+
) {
138146
newValue = formatDate(inputDate)
139147
}
140148

src/components/forms/DatePicker/utils.test.ts

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -81,34 +81,63 @@ describe('formatDate', () => {
8181
})
8282

8383
describe('isDateInvalid', () => {
84-
it('returns false if the date is within the min & max', () => {
85-
const testMin = new Date('May 1, 1988')
86-
const testMax = new Date('June 1, 1988')
87-
expect(isDateInvalid('05/16/1988', testMin, testMax)).toEqual(false)
88-
})
89-
90-
it('returns true if the date is not within the min & max', () => {
91-
const testMin = new Date('May 1, 1988')
92-
const testMax = new Date('June 1, 1988')
93-
expect(isDateInvalid('08/16/1988', testMin, testMax)).toEqual(true)
94-
})
95-
96-
it('returns true if the date is not valid', () => {
97-
const testMin = new Date('May 1, 1988')
98-
const testMax = new Date('June 1, 1988')
99-
expect(isDateInvalid('not a date', testMin, testMax)).toEqual(true)
100-
})
84+
it.each([
85+
['05/16/1988', DEFAULT_EXTERNAL_DATE_FORMAT],
86+
['1988-05-16', INTERNAL_DATE_FORMAT],
87+
] as const)(
88+
'returns false if the date is within the min & max',
89+
(date, format) => {
90+
const testMin = new Date('May 1, 1988')
91+
const testMax = new Date('June 1, 1988')
92+
expect(isDateInvalid(date, format, testMin, testMax)).toEqual(false)
93+
}
94+
)
95+
96+
it.each([
97+
['08/16/1988', DEFAULT_EXTERNAL_DATE_FORMAT],
98+
['1988-08-16', INTERNAL_DATE_FORMAT],
99+
] as const)(
100+
'returns true if the date is not within the min & max',
101+
(date, format) => {
102+
const testMin = new Date('May 1, 1988')
103+
const testMax = new Date('June 1, 1988')
104+
expect(isDateInvalid(date, format, testMin, testMax)).toEqual(true)
105+
}
106+
)
107+
108+
it.each([DEFAULT_EXTERNAL_DATE_FORMAT, INTERNAL_DATE_FORMAT] as const)(
109+
'returns true if the date is not valid',
110+
(format) => {
111+
const testMin = new Date('May 1, 1988')
112+
const testMax = new Date('June 1, 1988')
113+
expect(isDateInvalid('not a date', format, testMin, testMax)).toEqual(
114+
true
115+
)
116+
}
117+
)
101118

102119
describe('with no max date', () => {
103-
it('returns false if the date is after the min', () => {
104-
const testMin = new Date('May 1, 1988')
105-
expect(isDateInvalid('05/16/1988', testMin)).toEqual(false)
106-
})
120+
it.each([
121+
['05/16/1988', DEFAULT_EXTERNAL_DATE_FORMAT],
122+
['1988-05-16', INTERNAL_DATE_FORMAT],
123+
] as const)(
124+
'returns false if the date is after the min',
125+
(date, format) => {
126+
const testMin = new Date('May 1, 1988')
127+
expect(isDateInvalid(date, format, testMin)).toEqual(false)
128+
}
129+
)
107130

108-
it('returns true if the date is not after the min', () => {
109-
const testMin = new Date('May 1, 1988')
110-
expect(isDateInvalid('02/16/1988', testMin)).toEqual(true)
111-
})
131+
it.each([
132+
['02/16/1988', DEFAULT_EXTERNAL_DATE_FORMAT],
133+
['1988-02-16', INTERNAL_DATE_FORMAT],
134+
] as const)(
135+
'returns true if the date is not after the min',
136+
(date, format) => {
137+
const testMin = new Date('May 1, 1988')
138+
expect(isDateInvalid(date, format, testMin)).toEqual(true)
139+
}
140+
)
112141
})
113142
})
114143

src/components/forms/DatePicker/utils.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ export const formatDate = (
460460

461461
export const isDateInvalid = (
462462
dateString: string,
463+
dateFormat: DateFormat,
463464
minDate: Date,
464465
maxDate?: Date
465466
): boolean => {
@@ -468,22 +469,33 @@ export const isDateInvalid = (
468469
if (dateString) {
469470
isInvalid = true
470471

471-
const dateStringParts = dateString.split('/')
472-
const [month, day, year] = dateStringParts.map((str) => {
472+
const dateStringParts = dateString.split(
473+
dateFormat === DEFAULT_EXTERNAL_DATE_FORMAT ? '/' : '-'
474+
)
475+
const dateParts = dateStringParts.map((str) => {
473476
let value
474477
const parsed = parseInt(str, 10)
475478
if (!Number.isNaN(parsed)) value = parsed
476479
return value
477480
})
478481

482+
let month, day, year, yearStringPart
483+
if (dateFormat === DEFAULT_EXTERNAL_DATE_FORMAT) {
484+
yearStringPart = dateStringParts[2]
485+
;[month, day, year] = dateParts
486+
} else {
487+
yearStringPart = dateStringParts[0]
488+
;[year, month, day] = dateParts
489+
}
490+
479491
if (month && day && year != null) {
480492
const checkDate = setDate(year, month - 1, day)
481493

482494
if (
483495
checkDate.getMonth() === month - 1 &&
484496
checkDate.getDate() === day &&
485497
checkDate.getFullYear() === year &&
486-
dateStringParts[2].length === 4 &&
498+
yearStringPart.length === 4 &&
487499
isDateWithinMinAndMax(checkDate, minDate, maxDate)
488500
) {
489501
isInvalid = false

0 commit comments

Comments
 (0)