Skip to content

Commit ad0a47b

Browse files
fix(datepicker): Add max and min attributes to date input (#2808)
* fix(datepicker): Add max and min attributes to date input * fix(datepicker): Default max and min attributes * fix(datepicker): Add unit tests for max and min attributes Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent c4b942d commit ad0a47b

3 files changed

Lines changed: 59 additions & 7 deletions

File tree

src/__mocks__/pikaday.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const setDate = jest.fn();
22

33
const Pikaday = jest.fn().mockImplementation(() => {
44
return {
5+
el: document.createElement('div'),
56
getDate: () => {},
67
gotoDate: () => {},
78
setDate,

src/components/date-picker/DatePicker.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,8 @@ class DatePicker extends React.Component<DatePickerProps, DatePickerState> {
671671
isRequired,
672672
isTextInputAllowed,
673673
label,
674+
maxDate,
675+
minDate,
674676
name,
675677
onFocus,
676678
placeholder,
@@ -706,6 +708,7 @@ class DatePicker extends React.Component<DatePickerProps, DatePickerState> {
706708
} else {
707709
valueAttr = { value: this.formatDisplay(value) };
708710
}
711+
709712
let onChangeAttr;
710713
if (isAccessible && this.canUseDateInputType) {
711714
onChangeAttr = { onChange: this.handleOnChange };
@@ -717,13 +720,20 @@ class DatePicker extends React.Component<DatePickerProps, DatePickerState> {
717720
onChangeAttr = { onChange: noop };
718721
}
719722

720-
// "name" prop is required for pattern validation to be surfaced on form submit. See components/form-elements/form/Form.js
721-
// "title" prop is shown during constraint validation as a description of the pattern
722-
// See https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/pattern#usability
723-
const additionalAttrs =
724-
isAccessible && !this.canUseDateInputType
725-
? { name, pattern: ISO_DATE_FORMAT_PATTERN.source, title: 'YYYY-MM-DD' }
726-
: {};
723+
let additionalAttrs;
724+
if (isAccessible && this.canUseDateInputType) {
725+
additionalAttrs = {
726+
max: this.formatDisplayDateType(maxDate) || '9999-12-31',
727+
min: this.formatDisplayDateType(minDate) || '0001-01-01',
728+
};
729+
} else if (isAccessible && !this.canUseDateInputType) {
730+
// "name" prop is required for pattern validation to be surfaced on form submit. See components/form-elements/form/Form.js
731+
// "title" prop is shown during constraint validation as a description of the pattern
732+
// See https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/pattern#usability
733+
additionalAttrs = { name, pattern: ISO_DATE_FORMAT_PATTERN.source, title: 'YYYY-MM-DD' };
734+
} else {
735+
additionalAttrs = {};
736+
}
727737

728738
return (
729739
<div className={classes}>

src/components/date-picker/__tests__/DatePicker.test.tsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,47 @@ describe('components/date-picker/DatePicker', () => {
159159
expect(wrapper.find('ClearBadge16').length).toEqual(0);
160160
});
161161

162+
test.each`
163+
maxDate | minDate | maxAttr | minAttr
164+
${new Date('2022-12-31T00:00:00')} | ${new Date('2022-01-01T00:00:00')} | ${'2022-12-31'} | ${'2022-01-01'}
165+
${null} | ${null} | ${'9999-12-31'} | ${'0001-01-01'}
166+
`(
167+
'should pass { max: $maxAttr, min: $minAttr } attributes to date picker input',
168+
({ maxDate, minDate, maxAttr, minAttr }) => {
169+
const wrapper = getWrapper({
170+
isAccessible: true,
171+
maxDate,
172+
minDate,
173+
});
174+
175+
const dateInput = wrapper.find('.date-picker-input');
176+
expect(dateInput.prop('max')).toEqual(maxAttr);
177+
expect(dateInput.prop('min')).toEqual(minAttr);
178+
},
179+
);
180+
181+
test('should show alert icon when date value is after maximum date', () => {
182+
const wrapper = getWrapper({
183+
isAccessible: true,
184+
maxDate: new Date('2021-12-31T00:00:00'),
185+
});
186+
187+
expect(wrapper.find('Alert16').length).toEqual(0);
188+
wrapper.find('.date-picker-input').simulate('change', { target: { value: '2022-01-01' } });
189+
expect(wrapper.find('Alert16').length).toEqual(1);
190+
});
191+
192+
test('should show alert icon when date value is before minimum date', () => {
193+
const wrapper = getWrapper({
194+
isAccessible: true,
195+
minDate: new Date('2022-01-01T00:00:00'),
196+
});
197+
198+
expect(wrapper.find('Alert16').length).toEqual(0);
199+
wrapper.find('.date-picker-input').simulate('change', { target: { value: '2021-12-31' } });
200+
expect(wrapper.find('Alert16').length).toEqual(1);
201+
});
202+
162203
test('should show tooltip when error exists', () => {
163204
const wrapper = mount(
164205
<DatePicker

0 commit comments

Comments
 (0)