Skip to content

Commit 9dacf81

Browse files
authored
fix: DisabledDate should not crash by user typing (#300)
* test: test driven * fix: Not crash when disabled by typing
1 parent 11fb165 commit 9dacf81

File tree

3 files changed

+45
-31
lines changed

3 files changed

+45
-31
lines changed

.eslintrc.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,5 @@ module.exports = {
1414
'no-confusing-arrow': 0,
1515
'jsx-a11y/no-autofocus': 0,
1616
'jsx-a11y/heading-has-content': 0,
17-
'import/no-extraneous-dependencies': ['error', { packageDir: './' }],
1817
},
1918
};

src/Picker.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,12 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
300300
target as HTMLElement,
301301
),
302302
onSubmit: () => {
303-
if (disabledDate && disabledDate(selectedValue)) {
303+
if (
304+
// When user typing disabledDate with keyboard and enter, this value will be empty
305+
!selectedValue ||
306+
// Normal disabled check
307+
(disabledDate && disabledDate(selectedValue))
308+
) {
304309
return false;
305310
}
306311

tests/picker.spec.tsx

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { act } from 'react-dom/test-utils';
44
import { spyElementPrototypes } from 'rc-util/lib/test/domHook';
55
import KeyCode from 'rc-util/lib/KeyCode';
66
import { resetWarned } from 'rc-util/lib/warning';
7+
import moment from 'moment';
78
import type { Moment } from 'moment';
89
import type { PanelMode, PickerMode } from '../src/interface';
910
import { mount, getMoment, isSame, MomentPicker } from './util/commonUtil';
@@ -52,7 +53,7 @@ describe('Picker.Basic', () => {
5253
modeList.forEach(({ mode, componentNames }) => {
5354
it(mode, () => {
5455
const wrapper = mount(<MomentPicker mode={mode} open />);
55-
componentNames.forEach(componentName => {
56+
componentNames.forEach((componentName) => {
5657
expect(wrapper.find(componentName).length).toBeTruthy();
5758
});
5859
});
@@ -90,7 +91,7 @@ describe('Picker.Basic', () => {
9091
modeList.forEach(({ picker, componentNames }) => {
9192
it(picker, () => {
9293
const wrapper = mount(<MomentPicker picker={picker as any} open />);
93-
componentNames.forEach(componentName => {
94+
componentNames.forEach((componentName) => {
9495
expect(wrapper.find(componentName).length).toBeTruthy();
9596
});
9697
});
@@ -309,10 +310,7 @@ describe('Picker.Basic', () => {
309310
wrapper.openPicker();
310311

311312
const preventDefault = jest.fn();
312-
wrapper
313-
.find('td')
314-
.first()
315-
.simulate('mouseDown', { preventDefault });
313+
wrapper.find('td').first().simulate('mouseDown', { preventDefault });
316314

317315
expect(preventDefault).toHaveBeenCalled();
318316
});
@@ -415,12 +413,7 @@ describe('Picker.Basic', () => {
415413
wrapper.openPicker();
416414

417415
function selectColumn(colIndex: number, rowIndex: number) {
418-
wrapper
419-
.find('ul')
420-
.at(colIndex)
421-
.find('li')
422-
.at(rowIndex)
423-
.simulate('click');
416+
wrapper.find('ul').at(colIndex).find('li').at(rowIndex).simulate('click');
424417
}
425418

426419
selectColumn(0, 13);
@@ -435,7 +428,7 @@ describe('Picker.Basic', () => {
435428
});
436429

437430
it('renderExtraFooter', () => {
438-
const renderExtraFooter = jest.fn(mode => <div>{mode}</div>);
431+
const renderExtraFooter = jest.fn((mode) => <div>{mode}</div>);
439432
const wrapper = mount(<MomentPicker renderExtraFooter={renderExtraFooter} />);
440433

441434
function matchFooter(mode: string) {
@@ -482,7 +475,7 @@ describe('Picker.Basic', () => {
482475
expect(onSelect).not.toHaveBeenCalled();
483476
});
484477

485-
['decade', 'year', 'quarter', 'month', 'week'].forEach(name => {
478+
['decade', 'year', 'quarter', 'month', 'week'].forEach((name) => {
486479
it(`not works on ${name}`, () => {
487480
const wrapper = mount(<MomentPicker picker={name as any} showToday />);
488481
wrapper.openPicker();
@@ -623,7 +616,7 @@ describe('Picker.Basic', () => {
623616
it('click outside should also focus', () => {
624617
const onMouseUp = jest.fn();
625618
const wrapper = mount(<MomentPicker onMouseUp={onMouseUp} />);
626-
const inputElement = (wrapper.find('input').instance() as any) as HTMLInputElement;
619+
const inputElement = wrapper.find('input').instance() as any as HTMLInputElement;
627620
inputElement.focus = jest.fn();
628621

629622
wrapper.find('.rc-picker').simulate('mouseUp');
@@ -706,13 +699,8 @@ describe('Picker.Basic', () => {
706699
});
707700

708701
it('dateRender', () => {
709-
const wrapper = mount(<MomentPicker open dateRender={date => date.format('YYYY-MM-DD')} />);
710-
expect(
711-
wrapper
712-
.find('tbody td')
713-
.last()
714-
.text(),
715-
).toEqual('1990-10-06');
702+
const wrapper = mount(<MomentPicker open dateRender={(date) => date.format('YYYY-MM-DD')} />);
703+
expect(wrapper.find('tbody td').last().text()).toEqual('1990-10-06');
716704
});
717705

718706
it('format', () => {
@@ -898,10 +886,16 @@ describe('Picker.Basic', () => {
898886
function disabledDate(current: Moment) {
899887
return current <= getMoment('2020-12-28 00:00:00').endOf('day');
900888
}
901-
const wrapper = mount(<MomentPicker open defaultValue={getMoment('2020-12-29 12:00:00')} disabledDate={disabledDate} />);
889+
const wrapper = mount(
890+
<MomentPicker
891+
open
892+
defaultValue={getMoment('2020-12-29 12:00:00')}
893+
disabledDate={disabledDate}
894+
/>,
895+
);
902896
// Date Panel
903897
Array.from({
904-
length: 31
898+
length: 31,
905899
}).forEach((v, i) => {
906900
const cell = wrapper.findCell(`${i + 1}`);
907901
// >= 29
@@ -914,7 +908,7 @@ describe('Picker.Basic', () => {
914908
wrapper.find('.rc-picker-month-btn').simulate('click');
915909
// Month Panel
916910
Array.from({
917-
length: 12
911+
length: 12,
918912
}).forEach((v, i) => {
919913
const cell = wrapper.find('.rc-picker-cell-in-view').at(i);
920914
// >= 12
@@ -927,25 +921,32 @@ describe('Picker.Basic', () => {
927921
wrapper.find('.rc-picker-year-btn').simulate('click');
928922
// Year Panel
929923
Array.from({
930-
length: 10
924+
length: 10,
931925
}).forEach((v, i) => {
932926
const cell = wrapper.find('.rc-picker-cell-in-view').at(i);
933927
// >= 2020
934928
expect(cell.hasClass('rc-picker-cell-disabled')).toBeFalsy();
935929
});
936930
// Decade Panel
937931
Array.from({
938-
length: 8
932+
length: 8,
939933
}).forEach((v, i) => {
940934
const cell = wrapper.find('.rc-picker-cell-in-view').at(i);
941935
// >= 2020
942936
expect(cell.hasClass('rc-picker-cell-disabled')).toBeFalsy();
943937
});
944938

945-
const quarterWrapper = mount(<MomentPicker picker="quarter" open defaultValue={getMoment('2020-12-29 12:00:00')} disabledDate={disabledDate} />);
939+
const quarterWrapper = mount(
940+
<MomentPicker
941+
picker="quarter"
942+
open
943+
defaultValue={getMoment('2020-12-29 12:00:00')}
944+
disabledDate={disabledDate}
945+
/>,
946+
);
946947
// quarter Panel
947948
Array.from({
948-
length: 4
949+
length: 4,
949950
}).forEach((v, i) => {
950951
const cell = quarterWrapper.find('.rc-picker-cell-in-view').at(i);
951952
// >= 4
@@ -956,4 +957,13 @@ describe('Picker.Basic', () => {
956957
}
957958
});
958959
});
960+
961+
it('disabledDate should not crash', () => {
962+
const wrapper = mount(<MomentPicker open disabledDate={(d) => d.isAfter(Date.now())} />);
963+
wrapper
964+
.find('input')
965+
.simulate('change', { target: { value: moment().add(1, 'year').format('YYYY-MM-DD') } });
966+
967+
wrapper.find('input').simulate('keyDown', { which: KeyCode.ENTER });
968+
});
959969
});

0 commit comments

Comments
 (0)