Repository: Hacker0x01/react-datepicker (ts)

Issue:
Month in Month Picker and Year in Year Picker cannot be selected by pressing the "Space" on keyboard.
**Describe the bug**
Month in Month Picker and Year in Year Picker cannot be selected by pressing the "Space" on keyboard. Only "Enter" works.

**To Reproduce**
1. Navigate through the Month or Year Picker using keyboard.
2. Try to select any new value using "Space".

**Expected behavior**
New value is selected according to the https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/datepicker-dialog/

**Desktop (please complete the following information):**

- OS: Windows 11
- Browser Chrome
- Version 120.0.6099.225 


Pull request:
Fix #4482: Update Month Picker and Year Picker to select dates also on press of "SPACE" key
Closes #4482

## Description
This PR addresses the date selection behavior in the calendar component to enhance accessibility based on W3C WAI-ARIA principles.  Previously, the `Enter` key alone is used to select a Month picker and a Year Picker.   But As per the W3C WAI-ARIA principle, both the `Enter` & `Space` keys should be able to select a date.  Currently, only the date selector is selecting a date on both the `Enter` and the `Space` key.  Hence I updated the Year Picker and the Month Picker to work like the date picker to select a date both by `Space` and `Enter` keys.

[Reference Link](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/datepicker-dialog/#:~:text=Select%20the%20date%2C%20close%20the%20dialog%2C%20and%20move%20focus%20to%20the%20%22Choose%20Date%22%20button.)

## Changes Made
- Updated Year picker and Month picker to select values also on a click of the "Space" key in a similar way we handled on the date picker
- Updated the corresponding test cases.

Patch:
diff --git a/src/date_utils.js b/src/date_utils.js
index 83b835ec..1a6cd81b 100644
--- a/src/date_utils.js
+++ b/src/date_utils.js
@@ -917,3 +917,8 @@ export function isDateBefore(date, dateToCompare) {
 
   return isBefore(midnightDate, midnightDateToCompare);
 }
+
+export function isSpaceKeyDown(event) {
+  const SPACE_KEY = " ";
+  return event.key === SPACE_KEY;
+}
diff --git a/src/month.jsx b/src/month.jsx
index c97979de..c611113a 100644
--- a/src/month.jsx
+++ b/src/month.jsx
@@ -669,6 +669,11 @@ export default class Month extends React.Component {
               this.onMonthClick(ev, m);
             }}
             onKeyDown={(ev) => {
+              if (utils.isSpaceKeyDown(ev)) {
+                ev.preventDefault();
+                ev.key = "Enter";
+              }
+
               this.onMonthKeyDown(ev, m);
             }}
             onMouseEnter={() => this.onMonthMouseEnter(m)}
diff --git a/src/year.jsx b/src/year.jsx
index 74ce4fc3..01f78a5a 100644
--- a/src/year.jsx
+++ b/src/year.jsx
@@ -245,6 +245,11 @@ export default class Year extends React.Component {
             this.onYearClick(ev, y);
           }}
           onKeyDown={(ev) => {
+            if (utils.isSpaceKeyDown(ev)) {
+              ev.preventDefault();
+              ev.key = "Enter";
+            }
+
             this.onYearKeyDown(ev, y);
           }}
           tabIndex={this.getYearTabIndex(y)}


Test patch:
diff --git a/test/month_test.test.js b/test/month_test.test.js
index ac5f55af..0d95bfc9 100644
--- a/test/month_test.test.js
+++ b/test/month_test.test.js
@@ -1509,6 +1509,38 @@ describe("Month", () => {
       );
     });
 
+    it("should select March when Space is pressed", () => {
+      const SPACE_KEY = " ";
+      let preSelected = false;
+      let selectedDate = null;
+      const setPreSelection = () => {
+        preSelected = true;
+      };
+      const setSelectedDate = (param) => {
+        selectedDate = param;
+      };
+
+      const monthComponent = renderMonth({
+        selected: utils.newDate("2015-02-01"),
+        day: utils.newDate("2015-02-01"),
+        setPreSelection: setPreSelection,
+        preSelection: utils.newDate("2015-02-01"),
+        onDayClick: setSelectedDate,
+      });
+
+      monthComponent
+        .find(".react-datepicker__month-1")
+        .simulate("keydown", getKey("ArrowLeft"));
+      monthComponent
+        .find(".react-datepicker__month-2")
+        .simulate("keydown", getKey(SPACE_KEY));
+
+      expect(preSelected).toBe(true);
+      expect(selectedDate.toString()).toBe(
+        utils.newDate("2015-03-01").toString(),
+      );
+    });
+
     it("should prevent navigation to disabled month", () => {
       let preSelected = utils.newDate("2015-08-01");
       const setPreSelection = (param) => {
diff --git a/test/year_picker_test.test.js b/test/year_picker_test.test.js
index e4ff357d..95ef30da 100644
--- a/test/year_picker_test.test.js
+++ b/test/year_picker_test.test.js
@@ -6,6 +6,7 @@ import TestUtils from "react-dom/test-utils";
 import ReactDOM from "react-dom";
 import * as utils from "../src/date_utils.js";
 import Calendar from "../src/calendar.jsx";
+import { getKey } from "./test_utils.js";
 
 describe("YearPicker", () => {
   it("should show year picker component when showYearPicker prop is present", () => {
@@ -597,6 +598,20 @@ describe("YearPicker", () => {
       TestUtils.Simulate.keyDown(target, { key: "Enter", code: 13, which: 13 });
       expect(utils.getYear(selectedDay)).toBe(2021);
     });
+
+    it("should select 2021 when Space key is pressed", () => {
+      const yearPicker = getPicker("2021-01-01");
+
+      const target = TestUtils.findRenderedDOMComponentWithClass(
+        yearPicker,
+        "react-datepicker__year-text--selected",
+      );
+
+      const SPACE_KEY = " ";
+      TestUtils.Simulate.keyDown(target, getKey(SPACE_KEY));
+      expect(utils.getYear(selectedDay)).toBe(2021);
+    });
+
     it("should disable keyboard navigation", () => {
       const yearPicker = getPicker("2021-01-01", {
         disabledKeyboardNavigation: true,