Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #4446: ✨ Added support for up and down arrow key movement in the year picker #19

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 60 additions & 5 deletions src/year.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { getYear, newDate } from "./date_utils";
import * as utils from "./date_utils";
import { clsx } from "clsx";

const VERTICAL_NAVIGATION_OFFSET = 3;

export default class Year extends React.Component {
static propTypes = {
clearSelectingDate: PropTypes.func,
Expand Down Expand Up @@ -77,10 +79,12 @@ export default class Year extends React.Component {
if (this.isDisabled(newDate) || this.isExcluded(newDate)) return;
this.props.setPreSelection(newDate);

if (newYear - startPeriod === -1) {
this.updateFocusOnPaginate(yearItemNumber - 1);
} else if (newYear - startPeriod === yearItemNumber) {
this.updateFocusOnPaginate(0);
if (newYear - startPeriod < 0) {
this.updateFocusOnPaginate(yearItemNumber - (startPeriod - newYear));
} else if (newYear - startPeriod >= yearItemNumber) {
this.updateFocusOnPaginate(
Math.abs(yearItemNumber - (newYear - startPeriod)),
);
} else this.YEAR_REFS[newYear - startPeriod].current.focus();
};

Expand Down Expand Up @@ -168,7 +172,12 @@ export default class Year extends React.Component {

onYearKeyDown = (e, y) => {
const { key } = e;
const { handleOnKeyDown } = this.props;
const { date, yearItemNumber, handleOnKeyDown } = this.props;

if (key !== "Tab") {
// preventDefault on tab event blocks focus change
e.preventDefault();
}

if (!this.props.disabledKeyboardNavigation) {
switch (key) {
Expand All @@ -188,6 +197,52 @@ export default class Year extends React.Component {
utils.subYears(this.props.preSelection, 1),
);
break;
case "ArrowUp": {
const { startPeriod } = utils.getYearsPeriod(date, yearItemNumber);
let offset = VERTICAL_NAVIGATION_OFFSET;
let newYear = y - offset;

if (newYear < startPeriod) {
const leftOverOffset = yearItemNumber % offset;

if (y >= startPeriod && y < startPeriod + leftOverOffset) {
offset = leftOverOffset;
} else {
offset += leftOverOffset;
}

newYear = y - offset;
}

this.handleYearNavigation(
newYear,
utils.subYears(this.props.preSelection, offset),
);
break;
}
case "ArrowDown": {
const { endPeriod } = utils.getYearsPeriod(date, yearItemNumber);
let offset = VERTICAL_NAVIGATION_OFFSET;
let newYear = y + offset;

if (newYear > endPeriod) {
const leftOverOffset = yearItemNumber % offset;

if (y <= endPeriod && y > endPeriod - leftOverOffset) {
offset = leftOverOffset;
} else {
offset += leftOverOffset;
}

newYear = y + offset;
}

this.handleYearNavigation(
newYear,
utils.addYears(this.props.preSelection, offset),
);
break;
}
}
}

Expand Down
94 changes: 94 additions & 0 deletions test/year_picker_test.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,20 @@ describe("YearPicker", () => {
which: 39,
});

const simulateUp = (target) =>
fireEvent.keyDown(target, {
key: "ArrowUp",
keyCode: 38,
which: 38,
});

const simulateDown = (target) =>
fireEvent.keyDown(target, {
key: "ArrowDown",
keyCode: 40,
which: 40,
});

it("should preSelect and set 2020 on left arrow press", () => {
const yearPicker = getPicker("2021-01-01");

Expand All @@ -657,6 +671,86 @@ describe("YearPicker", () => {

expect(utils.getYear(preSelected)).toBe(2022);
});
it("should preSelect and set 2021 on up arrow press", () => {
const yearPicker = getPicker("2024-01-01");

const target = yearPicker.querySelector(
".react-datepicker__year-text--selected",
);
simulateUp(target);

expect(utils.getYear(preSelected)).toBe(2021);
});
it("should preSelect and set 2027 on down arrow press", () => {
const yearPicker = getPicker("2024-01-01");

const target = yearPicker.querySelector(
".react-datepicker__year-text--selected",
);
simulateDown(target);

expect(utils.getYear(preSelected)).toBe(2027);
});
it("should paginate from 2018 to 2015", () => {
const yearPicker = getPicker("2018-01-01");

const target = yearPicker.querySelector(
".react-datepicker__year-text--selected",
);
simulateUp(target);

expect(utils.getYear(preSelected)).toBe(2015);
});
it("should paginate from 2018 to 2016 with custom yearItemNumber", () => {
const yearPicker = getPicker("2018-01-01", { yearItemNumber: 8 });

const target = yearPicker.querySelector(
".react-datepicker__year-text--selected",
);
simulateUp(target);

expect(utils.getYear(preSelected)).toBe(2016);
});
it("should paginate from 2019 to 2014 with custom yearItemNumber", () => {
const yearPicker = getPicker("2019-01-01", { yearItemNumber: 8 });

const target = yearPicker.querySelector(
".react-datepicker__year-text--selected",
);
simulateUp(target);

expect(utils.getYear(preSelected)).toBe(2014);
});
it("should paginate from 2028 to 2031", () => {
const yearPicker = getPicker("2028-01-01");

const target = yearPicker.querySelector(
".react-datepicker__year-text--selected",
);
simulateDown(target);

expect(utils.getYear(preSelected)).toBe(2031);
});
it("should paginate from 2024 to 2026 with custom yearItemNumber", () => {
const yearPicker = getPicker("2024-01-01", { yearItemNumber: 8 });

const target = yearPicker.querySelector(
".react-datepicker__year-text--selected",
);
simulateDown(target);

expect(utils.getYear(preSelected)).toBe(2026);
});
it("should paginate from 2022 to 2027 with custom yearItemNumber", () => {
const yearPicker = getPicker("2022-01-01", { yearItemNumber: 8 });

const target = yearPicker.querySelector(
".react-datepicker__year-text--selected",
);
simulateDown(target);

expect(utils.getYear(preSelected)).toBe(2027);
});
it("should paginate from 2017 to 2016", () => {
const yearPicker = getPicker("2017-01-01");

Expand Down