Repository: Hacker0x01/react-datepicker (ts)

Issue:
onKeyDown function is not triggered in Month and Year Pickers.
**Describe the bug**
onKeyDown function is not triggered in Month and Year Pickers. It is triggered only in a day selection view.

**Expected behavior**
Function should be triggered in any view.

**Desktop (please complete the following information):**

- OS: Windows 11
- Browser Chrome
- Version 120.0.6099.225 


Pull request:
Fix #4483: Enable onKeyDown handler for the month picker view and the year picker view
Closes #4483

**Description**
This PR addresses the missing event handling to handle the key-press event for the month picker and the year picker.  For the Year Picker component, I added `onKeyDown` and mapped it to the corresponding prop.  However, the MonthPicker (`month.jsx`) is already receiving `onKeyDown` event, but that was mapped to the handler `handleOnDayKeyDown` which is the handler specifically we're using on `day.jsx`.  In `month.jsx` we're not directly using it, but passing that to the `Week` component.  Hence for the month.jsx alone, I didn't change any of its current behavior, and I added a new prop named `handleOnMonthKeyDown` which is linked to the `onKeyDown` event handler we pass from the DatePicker component.  So users can still use `onKeyDown` itself for any datepicker view (day/month/year), but internally `month.jsx` alone is handling it via `handleOnMonthKeyDown`.


**Changes Made**
- Updated Year picker and Month picker to handle the `onKeyDown` event.
- Updated the corresponding test cases.

Patch:
diff --git a/src/calendar.jsx b/src/calendar.jsx
index 0cad3689..0e5795b7 100644
--- a/src/calendar.jsx
+++ b/src/calendar.jsx
@@ -894,6 +894,7 @@ export default class Calendar extends React.Component {
             monthClassName={this.props.monthClassName}
             onDayClick={this.handleDayClick}
             handleOnKeyDown={this.props.handleOnDayKeyDown}
+            handleOnMonthKeyDown={this.props.handleOnKeyDown}
             onDayMouseEnter={this.handleDayMouseEnter}
             onMouseLeave={this.handleMonthMouseLeave}
             onWeekSelect={this.props.onWeekSelect}
diff --git a/src/month.jsx b/src/month.jsx
index c611113a..88092d3d 100644
--- a/src/month.jsx
+++ b/src/month.jsx
@@ -113,6 +113,7 @@ export default class Month extends React.Component {
     showQuarterYearPicker: PropTypes.bool,
     showWeekPicker: PropTypes.bool,
     handleOnKeyDown: PropTypes.func,
+    handleOnMonthKeyDown: PropTypes.func,
     isInputFocused: PropTypes.bool,
     weekAriaLabelPrefix: PropTypes.string,
     containerRef: PropTypes.oneOfType([
@@ -400,6 +401,7 @@ export default class Month extends React.Component {
       showTwoColumnMonthYearPicker,
       showFourColumnMonthYearPicker,
       setPreSelection,
+      handleOnMonthKeyDown,
     } = this.props;
     const eventKey = event.key;
     if (eventKey !== "Tab") {
@@ -451,6 +453,8 @@ export default class Month extends React.Component {
           break;
       }
     }
+
+    handleOnMonthKeyDown && handleOnMonthKeyDown(event);
   };
 
   onQuarterClick = (e, q) => {
diff --git a/src/year.jsx b/src/year.jsx
index 01f78a5a..3ef8da74 100644
--- a/src/year.jsx
+++ b/src/year.jsx
@@ -29,6 +29,7 @@ export default class Year extends React.Component {
     includeDates: PropTypes.array,
     filterDate: PropTypes.func,
     yearItemNumber: PropTypes.number,
+    handleOnKeyDown: PropTypes.func,
   };
 
   constructor(props) {
@@ -157,6 +158,8 @@ export default class Year extends React.Component {
 
   onYearKeyDown = (e, y) => {
     const { key } = e;
+    const { handleOnKeyDown } = this.props;
+
     if (!this.props.disabledKeyboardNavigation) {
       switch (key) {
         case "Enter":
@@ -177,6 +180,8 @@ export default class Year extends React.Component {
           break;
       }
     }
+
+    handleOnKeyDown && handleOnKeyDown(e);
   };
 
   getYearClassNames = (y) => {


Test patch:
diff --git a/test/month_test.test.js b/test/month_test.test.js
index 0d95bfc9..f053e4c9 100644
--- a/test/month_test.test.js
+++ b/test/month_test.test.js
@@ -1,6 +1,8 @@
 import React from "react";
+import { render, fireEvent } from "@testing-library/react";
 import Month from "../src/month";
 import Day from "../src/day";
+import DatePicker from "../src";
 import range from "lodash/range";
 import { mount, shallow } from "enzyme";
 import * as utils from "../src/date_utils";
@@ -935,6 +937,30 @@ describe("Month", () => {
         ).toBe(false);
       });
     });
+
+    it("should call onKeyDown handler on any key press", () => {
+      const onKeyDownSpy = jest.fn();
+
+      const { container } = render(
+        <DatePicker
+          selected={new Date()}
+          dateFormat="MM/yyyy"
+          showMonthYearPicker
+          onKeyDown={onKeyDownSpy}
+        />,
+      );
+
+      const dateInput = container.querySelector("input");
+      fireEvent.focus(dateInput);
+
+      const month = container.querySelector(".react-datepicker__month-0");
+
+      fireEvent.keyDown(month, {
+        key: "ArrowDown",
+      });
+
+      expect(onKeyDownSpy).toHaveBeenCalledTimes(1);
+    });
   });
 
   describe("Keyboard navigation", () => {
diff --git a/test/year_picker_test.test.js b/test/year_picker_test.test.js
index 95ef30da..cbb28cd2 100644
--- a/test/year_picker_test.test.js
+++ b/test/year_picker_test.test.js
@@ -4,6 +4,7 @@ import DatePicker from "../src/index.jsx";
 import Year from "../src/year.jsx";
 import TestUtils from "react-dom/test-utils";
 import ReactDOM from "react-dom";
+import { render, fireEvent } from "@testing-library/react";
 import * as utils from "../src/date_utils.js";
 import Calendar from "../src/calendar.jsx";
 import { getKey } from "./test_utils.js";
@@ -599,6 +600,30 @@ describe("YearPicker", () => {
       expect(utils.getYear(selectedDay)).toBe(2021);
     });
 
+    it("should call onKeyDown handler on any key press", () => {
+      const onKeyDownSpy = jest.fn();
+
+      const { container } = render(
+        <DatePicker
+          selected={new Date()}
+          showYearPicker
+          dateFormat="yyyy"
+          onKeyDown={onKeyDownSpy}
+        />,
+      );
+
+      const dateInput = container.querySelector("input");
+      fireEvent.focus(dateInput);
+
+      const year = container.querySelector(".react-datepicker__year-text");
+
+      fireEvent.keyDown(year, {
+        key: "ArrowDown",
+      });
+
+      expect(onKeyDownSpy).toHaveBeenCalledTimes(1);
+    });
+
     it("should select 2021 when Space key is pressed", () => {
       const yearPicker = getPicker("2021-01-01");