diff --git a/README.md b/README.md index 0fe00c94c..8e19a7c3b 100644 --- a/README.md +++ b/README.md @@ -159,7 +159,9 @@ The examples are hosted within the docs folder and are ran in the simple app tha - _Up_: Move to the previous week. - _Down_: Move to the next week. - _PgUp_: Move to the previous month. +- _Shift+PgUp_: Move to the same day and month of the previous year. If that day does not exist, moves focus to the last day of the month. - _PgDn_: Move to the next month. +- _Shift+PgDn_: Move to the same day and month of the next year. If that day does not exist, moves focus to the last day of the month. - _Home_: Move to the first day (e.g Sunday) of the current week. - _End_: Move to the last day (e.g. Saturday) of the current week. - _Enter/Esc/Tab_: close the calendar. (Enter & Esc calls preventDefault) diff --git a/src/index.jsx b/src/index.jsx index a3700220a..15b44e80c 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -26,6 +26,8 @@ import { subDays, subMonths, subWeeks, + addYears, + subYears, isDayDisabled, isDayInRange, getEffectiveMinDate, @@ -363,10 +365,10 @@ export default class DatePicker extends React.Component { this.props.openToDate ? this.props.openToDate : this.props.selectsEnd && this.props.startDate - ? this.props.startDate - : this.props.selectsStart && this.props.endDate - ? this.props.endDate - : newDate(); + ? this.props.startDate + : this.props.selectsStart && this.props.endDate + ? this.props.endDate + : newDate(); // Convert the date from string format to standard Date format modifyHolidays = () => @@ -387,8 +389,8 @@ export default class DatePicker extends React.Component { minDate && isBefore(defaultPreSelection, startOfDay(minDate)) ? minDate : maxDate && isAfter(defaultPreSelection, endOfDay(maxDate)) - ? maxDate - : defaultPreSelection; + ? maxDate + : defaultPreSelection; return { open: this.props.startOpen || false, preventFocus: false, @@ -843,6 +845,7 @@ export default class DatePicker extends React.Component { onDayKeyDown = (event) => { this.props.onKeyDown(event); const eventKey = event.key; + const isShiftKeyActive = event.shiftKey; const copy = newDate(this.state.preSelection); if (eventKey === "Enter") { @@ -880,10 +883,14 @@ export default class DatePicker extends React.Component { newSelection = addWeeks(copy, 1); break; case "PageUp": - newSelection = subMonths(copy, 1); + newSelection = isShiftKeyActive + ? subYears(copy, 1) + : subMonths(copy, 1); break; case "PageDown": - newSelection = addMonths(copy, 1); + newSelection = isShiftKeyActive + ? addYears(copy, 1) + : addMonths(copy, 1); break; case "Home": newSelection = getStartOfWeek( @@ -1187,14 +1194,14 @@ export default class DatePicker extends React.Component { typeof this.props.value === "string" ? this.props.value : typeof this.state.inputValue === "string" - ? this.state.inputValue - : this.props.selectsRange - ? safeDateRangeFormat( - this.props.startDate, - this.props.endDate, - this.props, - ) - : safeDateFormat(this.props.selected, this.props); + ? this.state.inputValue + : this.props.selectsRange + ? safeDateRangeFormat( + this.props.startDate, + this.props.endDate, + this.props, + ) + : safeDateFormat(this.props.selected, this.props); return React.cloneElement(customInput, { [customInputRef]: (input) => { diff --git a/test/datepicker_test.test.js b/test/datepicker_test.test.js index 994fe4a65..8e13b6133 100644 --- a/test/datepicker_test.test.js +++ b/test/datepicker_test.test.js @@ -931,6 +931,21 @@ describe("DatePicker", () => { utils.formatDate(data.datePicker.state.preSelection, data.testFormat), ).toBe(utils.formatDate(data.copyM, data.testFormat)); }); + it("should handle onDayKeyDown Shift+PageUp", () => { + const data = getOnInputKeyDownStuff(); + + TestUtils.Simulate.keyDown(data.nodeInput, getKey("ArrowDown")); + TestUtils.Simulate.keyDown( + getSelectedDayNode(data.datePicker), + getKey("PageUp", true), + ); + + data.copyM = utils.subYears(data.copyM, 1); + + expect( + utils.formatDate(data.datePicker.state.preSelection, data.testFormat), + ).toBe(utils.formatDate(data.copyM, data.testFormat)); + }); it("should handle onDayKeyDown PageDown", () => { var data = getOnInputKeyDownStuff(); TestUtils.Simulate.keyDown(data.nodeInput, getKey("ArrowDown")); @@ -943,6 +958,21 @@ describe("DatePicker", () => { utils.formatDate(data.datePicker.state.preSelection, data.testFormat), ).toBe(utils.formatDate(data.copyM, data.testFormat)); }); + it("should handle onDayKeyDown Shift+PageDown", () => { + const data = getOnInputKeyDownStuff(); + + TestUtils.Simulate.keyDown(data.nodeInput, getKey("ArrowDown")); + TestUtils.Simulate.keyDown( + getSelectedDayNode(data.datePicker), + getKey("PageDown", true), + ); + + data.copyM = utils.addYears(data.copyM, 1); + + expect( + utils.formatDate(data.datePicker.state.preSelection, data.testFormat), + ).toBe(utils.formatDate(data.copyM, data.testFormat)); + }); it("should handle onDayKeyDown End", () => { const data = getOnInputKeyDownStuff(); TestUtils.Simulate.keyDown(data.nodeInput, getKey("ArrowDown"));