Repository: Hacker0x01/react-datepicker (ts)

Issue:
Incorrect keyboard behavior in the year selection calendar.
**Describe the bug**
The year selector from the keyboard does not work completely. You can use ←→ arrows, but not ↑ ↓ arrows, as in all other calendar states.

**To Reproduce**
Steps to reproduce the behavior:

1. Set property "showYearPicker".
2. Try to use arrows ↑ ↓ from the keyboard.

**Expected behavior**
The focus will move up and down in the year calendar.

**Desktop (please complete the following information):**

- OS: Windows 11
- Browser Chrome
- Version 120.0.6099.200 


Pull request description:
Fix #4446: ✨ Added support for up and down arrow key movement in the year picker
## Description
**Linked issue**: #4446 

**Problem**
The Year Picker doesn't support the up and down key navigation like the month picker and the date picker.

**Changes**
This PR adds support for updating the selected year in the year picker using the up and down arrow keys.  It also blocks the default page movement on the press of arrow keys.

## Contribution checklist
- [x] I have followed the [contributing guidelines](https://github.com/Hacker0x01/react-datepicker/blob/main/CONTRIBUTING.md).
- [x] I have added sufficient test coverage for my changes.
- [x] I have formatted my code with Prettier and checked for linting issues with ESLint for code readability.


Patch:
diff --git a/examples/hello-world/package.json b/examples/hello-world/package.json
index 4c5d07ba..e74013c2 100644
--- a/examples/hello-world/package.json
+++ b/examples/hello-world/package.json
@@ -4,7 +4,7 @@
   "private": true,
   "dependencies": {
     "react": "^18.2.0",
-    "react-datepicker": "^6.8.0",
+    "react-datepicker": "^6.6.0",
     "react-dom": "^18.2.0",
     "react-scripts": "5.0.1"
   },
diff --git a/examples/hello-world/yarn.lock b/examples/hello-world/yarn.lock
index 75c37522..beffe10f 100644
--- a/examples/hello-world/yarn.lock
+++ b/examples/hello-world/yarn.lock
@@ -7340,10 +7340,10 @@ react-app-polyfill@^3.0.0:
     regenerator-runtime "^0.13.9"
     whatwg-fetch "^3.6.2"
 
-react-datepicker@^6.8.0:
-  version "6.8.0"
-  resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-6.8.0.tgz#06d6d3470fd8fb827c14cb80ffa3a3df39fe3662"
-  integrity sha512-/h3IXzAbwXVbhBhsXx57B94in0ECzYayijwHbAbB0QIyXaHTGnICNgldjiYIqQFimROP1h/SunoY1pHkLplJtw==
+react-datepicker@^6.6.0:
+  version "6.6.0"
+  resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-6.6.0.tgz#0128547211c8fece08fef0b5406efffff2d36f1f"
+  integrity sha512-ERC0/Q4pPC9bNIcGUpdCbHc+oCxhkU3WI3UOGHkyJ3A9fqALCYpEmLc5S5xvAd7DuCDdbsyW97oRPM6pWWwjww==
   dependencies:
     "@floating-ui/react" "^0.26.2"
     clsx "^2.1.0"
diff --git a/package.json b/package.json
index 900d1c18..4bb0d4fa 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "HackerOne",
   "name": "react-datepicker",
   "description": "A simple and reusable datepicker component for React",
-  "version": "6.8.0",
+  "version": "6.7.1",
   "license": "MIT",
   "homepage": "https://github.com/Hacker0x01/react-datepicker",
   "main": "dist/index.js",
diff --git a/src/calendar.jsx b/src/calendar.jsx
index dca56b40..6c7c217e 100644
--- a/src/calendar.jsx
+++ b/src/calendar.jsx
@@ -444,7 +444,6 @@ export default class Calendar extends React.Component {
         return (
           <div
             key={offset}
-            aria-label={formatDate(day, "EEEE", this.props.locale)}
             className={clsx("react-datepicker__day-name", weekDayClassName)}
           >
             {weekDayName}
diff --git a/src/date_utils.js b/src/date_utils.js
index 4e58002b..5f094009 100644
--- a/src/date_utils.js
+++ b/src/date_utils.js
@@ -599,8 +599,7 @@ export function isTimeInList(time, times) {
   return times.some(
     (listTime) =>
       getHours(listTime) === getHours(time) &&
-      getMinutes(listTime) === getMinutes(time) &&
-      getSeconds(listTime) === getSeconds(time),
+      getMinutes(listTime) === getMinutes(time),
   );
 }
 
@@ -620,20 +619,16 @@ export function isTimeInDisabledRange(time, { minTime, maxTime }) {
   if (!minTime || !maxTime) {
     throw new Error("Both minTime and maxTime props required");
   }
-  let baseTime = newDate();
-  baseTime = setHours(baseTime, getHours(time));
-  baseTime = setMinutes(baseTime, getMinutes(time));
-  baseTime = setSeconds(baseTime, getSeconds(time));
-
-  let min = newDate();
-  min = setHours(min, getHours(minTime));
-  min = setMinutes(min, getMinutes(minTime));
-  min = setSeconds(min, getSeconds(minTime));
-
-  let max = newDate();
-  max = setHours(max, getHours(maxTime));
-  max = setMinutes(max, getMinutes(maxTime));
-  max = setSeconds(max, getSeconds(maxTime));
+  const base = newDate();
+  const baseTime = setHours(setMinutes(base, getMinutes(time)), getHours(time));
+  const min = setHours(
+    setMinutes(base, getMinutes(minTime)),
+    getHours(minTime),
+  );
+  const max = setHours(
+    setMinutes(base, getMinutes(maxTime)),
+    getHours(maxTime),
+  );
 
   let valid;
   try {
diff --git a/src/index.jsx b/src/index.jsx
index 627ae4e8..9f572cf3 100644
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -838,10 +838,7 @@ export default class DatePicker extends React.Component {
         const selectorString =
           this.props.showWeekPicker && this.props.showWeekNumbers
             ? '.react-datepicker__week-number[tabindex="0"]'
-            : this.props.showFullMonthYearPicker ||
-                this.props.showMonthYearPicker
-              ? '.react-datepicker__month-text[tabindex="0"]'
-              : '.react-datepicker__day[tabindex="0"]';
+            : '.react-datepicker__day[tabindex="0"]';
         const selectedItem =
           this.calendar.componentNode &&
           this.calendar.componentNode.querySelector(selectorString);
diff --git a/src/month.jsx b/src/month.jsx
index 66842f2f..8128fe30 100644
--- a/src/month.jsx
+++ b/src/month.jsx
@@ -622,15 +622,15 @@ export default class Month extends React.Component {
       chooseDayAriaLabelPrefix = "Choose",
       disabledDayAriaLabelPrefix = "Not available",
       day,
-      locale,
     } = this.props;
+
     const labelDate = utils.setMonth(day, month);
     const prefix =
       this.isDisabled(labelDate) || this.isExcluded(labelDate)
         ? disabledDayAriaLabelPrefix
         : chooseDayAriaLabelPrefix;
 
-    return `${prefix} ${utils.formatDate(labelDate, "MMMM yyyy", locale)}`;
+    return `${prefix} ${utils.formatDate(labelDate, "MMMM yyyy")}`;
   };
 
   getQuarterClassNames = (q) => {
@@ -830,7 +830,7 @@ export default class Month extends React.Component {
         onPointerLeave={
           this.props.usePointerEvent ? this.handleMouseLeave : undefined
         }
-        aria-label={`${formattedAriaLabelPrefix}${utils.formatDate(day, "MMMM, yyyy", this.props.locale)}`}
+        aria-label={`${formattedAriaLabelPrefix}${utils.formatDate(day, "MMMM, yyyy")}`}
         role="listbox"
       >
         {showMonthYearPicker
diff --git a/src/year.jsx b/src/year.jsx
index 6b200960..55b82efd 100644
--- a/src/year.jsx
+++ b/src/year.jsx
@@ -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,
@@ -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();
   };
 
@@ -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) {
@@ -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;
+        }
       }
     }
 
diff --git a/yarn.lock b/yarn.lock
index ceb7e697..33f8eda9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1700,85 +1700,80 @@
     estree-walker "^2.0.2"
     picomatch "^2.3.1"
 
-"@rollup/rollup-android-arm-eabi@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.3.tgz#bddf05c3387d02fac04b6b86b3a779337edfed75"
-  integrity sha512-X9alQ3XM6I9IlSlmC8ddAvMSyG1WuHk5oUnXGw+yUBs3BFoTizmG1La/Gr8fVJvDWAq+zlYTZ9DBgrlKRVY06g==
-
-"@rollup/rollup-android-arm64@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.3.tgz#b26bd09de58704c0a45e3375b76796f6eda825e4"
-  integrity sha512-eQK5JIi+POhFpzk+LnjKIy4Ks+pwJ+NXmPxOCSvOKSNRPONzKuUvWE+P9JxGZVxrtzm6BAYMaL50FFuPe0oWMQ==
-
-"@rollup/rollup-darwin-arm64@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.3.tgz#c5f3fd1aa285b6d33dda6e3f3ca395f8c37fd5ca"
-  integrity sha512-Od4vE6f6CTT53yM1jgcLqNfItTsLt5zE46fdPaEmeFHvPs5SjZYlLpHrSiHEKR1+HdRfxuzXHjDOIxQyC3ptBA==
-
-"@rollup/rollup-darwin-x64@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.3.tgz#8e4673734d7dc9d68f6d48e81246055cda0e840f"
-  integrity sha512-0IMAO21axJeNIrvS9lSe/PGthc8ZUS+zC53O0VhF5gMxfmcKAP4ESkKOCwEi6u2asUrt4mQv2rjY8QseIEb1aw==
-
-"@rollup/rollup-linux-arm-gnueabihf@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.3.tgz#53ed38eb13b58ababdb55a7f66f0538a7f85dcba"
-  integrity sha512-ge2DC7tHRHa3caVEoSbPRJpq7azhG+xYsd6u2MEnJ6XzPSzQsTKyXvh6iWjXRf7Rt9ykIUWHtl0Uz3T6yXPpKw==
-
-"@rollup/rollup-linux-arm-musleabihf@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.14.3.tgz#0706ee38330e267a5c9326956820f009cfb21fcd"
-  integrity sha512-ljcuiDI4V3ySuc7eSk4lQ9wU8J8r8KrOUvB2U+TtK0TiW6OFDmJ+DdIjjwZHIw9CNxzbmXY39wwpzYuFDwNXuw==
-
-"@rollup/rollup-linux-arm64-gnu@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.3.tgz#426fce7b8b242ac5abd48a10a5020f5a468c6cb4"
-  integrity sha512-Eci2us9VTHm1eSyn5/eEpaC7eP/mp5n46gTRB3Aar3BgSvDQGJZuicyq6TsH4HngNBgVqC5sDYxOzTExSU+NjA==
-
-"@rollup/rollup-linux-arm64-musl@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.3.tgz#65bf944530d759b50d7ffd00dfbdf4125a43406f"
-  integrity sha512-UrBoMLCq4E92/LCqlh+blpqMz5h1tJttPIniwUgOFJyjWI1qrtrDhhpHPuFxULlUmjFHfloWdixtDhSxJt5iKw==
-
-"@rollup/rollup-linux-powerpc64le-gnu@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.3.tgz#494ba3b31095e9a45df9c3f646d21400fb631a95"
-  integrity sha512-5aRjvsS8q1nWN8AoRfrq5+9IflC3P1leMoy4r2WjXyFqf3qcqsxRCfxtZIV58tCxd+Yv7WELPcO9mY9aeQyAmw==
-
-"@rollup/rollup-linux-riscv64-gnu@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.3.tgz#8b88ed0a40724cce04aa15374ebe5ba4092d679f"
-  integrity sha512-sk/Qh1j2/RJSX7FhEpJn8n0ndxy/uf0kI/9Zc4b1ELhqULVdTfN6HL31CDaTChiBAOgLcsJ1sgVZjWv8XNEsAQ==
-
-"@rollup/rollup-linux-s390x-gnu@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.3.tgz#09c9e5ec57a0f6ec3551272c860bb9a04b96d70f"
-  integrity sha512-jOO/PEaDitOmY9TgkxF/TQIjXySQe5KVYB57H/8LRP/ux0ZoO8cSHCX17asMSv3ruwslXW/TLBcxyaUzGRHcqg==
-
-"@rollup/rollup-linux-x64-gnu@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.3.tgz#197f27fd481ad9c861021d5cbbf21793922a631c"
-  integrity sha512-8ybV4Xjy59xLMyWo3GCfEGqtKV5M5gCSrZlxkPGvEPCGDLNla7v48S662HSGwRd6/2cSneMQWiv+QzcttLrrOA==
-
-"@rollup/rollup-linux-x64-musl@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.3.tgz#5cc0522f4942f2df625e9bfb6fb02c6580ffbce6"
-  integrity sha512-s+xf1I46trOY10OqAtZ5Rm6lzHre/UiLA1J2uOhCFXWkbZrJRkYBPO6FhvGfHmdtQ3Bx793MNa7LvoWFAm93bg==
-
-"@rollup/rollup-win32-arm64-msvc@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.3.tgz#a648122389d23a7543b261fba082e65fefefe4f6"
-  integrity sha512-+4h2WrGOYsOumDQ5S2sYNyhVfrue+9tc9XcLWLh+Kw3UOxAvrfOrSMFon60KspcDdytkNDh7K2Vs6eMaYImAZg==
-
-"@rollup/rollup-win32-ia32-msvc@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.3.tgz#34727b5c7953c35fc6e1ae4f770ad3a2025f8e03"
-  integrity sha512-T1l7y/bCeL/kUwh9OD4PQT4aM7Bq43vX05htPJJ46RTI4r5KNt6qJRzAfNfM+OYMNEVBWQzR2Gyk+FXLZfogGw==
-
-"@rollup/rollup-win32-x64-msvc@4.14.3":
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.3.tgz#5b2fb4d8cd44c05deef8a7b0e6deb9ccb8939d18"
-  integrity sha512-/BypzV0H1y1HzgYpxqRaXGBRqfodgoBBCcsrujT6QRcakDQdfU+Lq9PENPh5jB4I44YWq+0C2eHsHya+nZY1sA==
+"@rollup/rollup-android-arm-eabi@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.2.tgz#9047b5b1ec19f58c0fdf3a072bd977bcec056576"
+  integrity sha512-ahxSgCkAEk+P/AVO0vYr7DxOD3CwAQrT0Go9BJyGQ9Ef0QxVOfjDZMiF4Y2s3mLyPrjonchIMH/tbWHucJMykQ==
+
+"@rollup/rollup-android-arm64@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.2.tgz#08a2d2705193ebb3054941994e152808beb5254e"
+  integrity sha512-lAarIdxZWbFSHFSDao9+I/F5jDaKyCqAPMq5HqnfpBw8dKDiCaaqM0lq5h1pQTLeIqueeay4PieGR5jGZMWprw==
+
+"@rollup/rollup-darwin-arm64@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.2.tgz#bf746c610f337b104408ec001549d825a91eca57"
+  integrity sha512-SWsr8zEUk82KSqquIMgZEg2GE5mCSfr9sE/thDROkX6pb3QQWPp8Vw8zOq2GyxZ2t0XoSIUlvHDkrf5Gmf7x3Q==
+
+"@rollup/rollup-darwin-x64@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.2.tgz#59ebe3b858a44680d5f87546ea2df1c7e3135f6a"
+  integrity sha512-o/HAIrQq0jIxJAhgtIvV5FWviYK4WB0WwV91SLUnsliw1lSAoLsmgEEgRWzDguAFeUEUUoIWXiJrPqU7vGiVkA==
+
+"@rollup/rollup-linux-arm-gnueabihf@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.2.tgz#44cffc07d04d659cb635aec11bef530d5757ee6a"
+  integrity sha512-nwlJ65UY9eGq91cBi6VyDfArUJSKOYt5dJQBq8xyLhvS23qO+4Nr/RreibFHjP6t+5ap2ohZrUJcHv5zk5ju/g==
+
+"@rollup/rollup-linux-arm64-gnu@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.2.tgz#9901e2288fb192b74a2f8428c507d43cc2739ceb"
+  integrity sha512-Pg5TxxO2IVlMj79+c/9G0LREC9SY3HM+pfAwX7zj5/cAuwrbfj2Wv9JbMHIdPCfQpYsI4g9mE+2Bw/3aeSs2rQ==
+
+"@rollup/rollup-linux-arm64-musl@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.2.tgz#8a2c55a72e0c716a15d830fee3bf5a1a756f13ec"
+  integrity sha512-cAOTjGNm84gc6tS02D1EXtG7tDRsVSDTBVXOLbj31DkwfZwgTPYZ6aafSU7rD/4R2a34JOwlF9fQayuTSkoclA==
+
+"@rollup/rollup-linux-powerpc64le-gnu@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.2.tgz#71bf99c8017476ac85b09d21b3fa2eacbad96100"
+  integrity sha512-4RyT6v1kXb7C0fn6zV33rvaX05P0zHoNzaXI/5oFHklfKm602j+N4mn2YvoezQViRLPnxP8M1NaY4s/5kXO5cw==
+
+"@rollup/rollup-linux-riscv64-gnu@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.2.tgz#48ee7fe5fee7b6d0028b6dda4fab95238208a0cd"
+  integrity sha512-KNUH6jC/vRGAKSorySTyc/yRYlCwN/5pnMjXylfBniwtJx5O7X17KG/0efj8XM3TZU7raYRXJFFReOzNmL1n1w==
+
+"@rollup/rollup-linux-s390x-gnu@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.2.tgz#65ad6f82729ef9d8634847189214e3205892f42f"
+  integrity sha512-xPV4y73IBEXToNPa3h5lbgXOi/v0NcvKxU0xejiFw6DtIYQqOTMhZ2DN18/HrrP0PmiL3rGtRG9gz1QE8vFKXQ==
+
+"@rollup/rollup-linux-x64-gnu@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.2.tgz#2ab802ce25c0d0d44a0ea55b0068f79e462d22cd"
+  integrity sha512-QBhtr07iFGmF9egrPOWyO5wciwgtzKkYPNLVCFZTmr4TWmY0oY2Dm/bmhHjKRwZoGiaKdNcKhFtUMBKvlchH+Q==
+
+"@rollup/rollup-linux-x64-musl@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.2.tgz#85dcd3f549c2fdbcf1cb1f1b5f501933ed590880"
+  integrity sha512-8zfsQRQGH23O6qazZSFY5jP5gt4cFvRuKTpuBsC1ZnSWxV8ZKQpPqOZIUtdfMOugCcBvFGRa1pDC/tkf19EgBw==
+
+"@rollup/rollup-win32-arm64-msvc@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.2.tgz#10f608dfc1e5bb96aca18c7784cc4a94d890c03c"
+  integrity sha512-H4s8UjgkPnlChl6JF5empNvFHp77Jx+Wfy2EtmYPe9G22XV+PMuCinZVHurNe8ggtwoaohxARJZbaH/3xjB/FA==
+
+"@rollup/rollup-win32-ia32-msvc@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.2.tgz#f27f9fb64b7e10b04121e0054d9145ee21589267"
+  integrity sha512-djqpAjm/i8erWYF0K6UY4kRO3X5+T4TypIqw60Q8MTqSBaQNpNXDhxdjpZ3ikgb+wn99svA7jxcXpiyg9MUsdw==
+
+"@rollup/rollup-win32-x64-msvc@4.14.2":
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.2.tgz#5d2d9dc96b436469dc74ef93de069b14fb12aace"
+  integrity sha512-teAqzLT0yTYZa8ZP7zhFKEx4cotS8Tkk5XiqNMJhD4CpaWB1BHARE4Qy+RzwnXvSAYv+Q3jAqCVBS+PS+Yee8Q==
 
 "@sigstore/protobuf-specs@^0.1.0":
   version "0.1.0"
@@ -1827,9 +1822,9 @@
     pretty-format "^27.0.2"
 
 "@testing-library/react@^15.0.0":
-  version "15.0.2"
-  resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-15.0.2.tgz#d0fd7e9c41b819557639acf5f18e4cd1007ec295"
-  integrity sha512-5mzIpuytB1ctpyywvyaY2TAAUQVCZIGqwiqFQf6u9lvj/SJQepGUzNV18Xpk+NLCaCE2j7CWrZE0tEf9xLZYiQ==
+  version "15.0.1"
+  resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-15.0.1.tgz#d67258ddc7b175e00aa9d8ddeada60ff8ac03ff8"
+  integrity sha512-I8u4qqGAuBg7C1/kRB9n7Oz9Pc/UHEkmiQRbJziSG8B13eZfAcAUn8TSP26ZIvfSeb68CngmtZbKKcRqcQKa3g==
   dependencies:
     "@babel/runtime" "^7.12.5"
     "@testing-library/dom" "^10.0.0"
@@ -6266,28 +6261,27 @@ rollup-plugin-filesize@^10.0.0:
     terser "^5.6.0"
 
 rollup@^4.13.0:
-  version "4.14.3"
-  resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.14.3.tgz#bcbb7784b35826d3164346fa6d5aac95190d8ba9"
-  integrity sha512-ag5tTQKYsj1bhrFC9+OEWqb5O6VYgtQDO9hPDBMmIbePwhfSr+ExlcU741t8Dhw5DkPCQf6noz0jb36D6W9/hw==
+  version "4.14.2"
+  resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.14.2.tgz#992df3c3bb4ca84ce6b00d51aacb1e5a62d0a14c"
+  integrity sha512-WkeoTWvuBoFjFAhsEOHKRoZ3r9GfTyhh7Vff1zwebEFLEFjT1lG3784xEgKiTa7E+e70vsC81roVL2MP4tgEEQ==
   dependencies:
     "@types/estree" "1.0.5"
   optionalDependencies:
-    "@rollup/rollup-android-arm-eabi" "4.14.3"
-    "@rollup/rollup-android-arm64" "4.14.3"
-    "@rollup/rollup-darwin-arm64" "4.14.3"
-    "@rollup/rollup-darwin-x64" "4.14.3"
-    "@rollup/rollup-linux-arm-gnueabihf" "4.14.3"
-    "@rollup/rollup-linux-arm-musleabihf" "4.14.3"
-    "@rollup/rollup-linux-arm64-gnu" "4.14.3"
-    "@rollup/rollup-linux-arm64-musl" "4.14.3"
-    "@rollup/rollup-linux-powerpc64le-gnu" "4.14.3"
-    "@rollup/rollup-linux-riscv64-gnu" "4.14.3"
-    "@rollup/rollup-linux-s390x-gnu" "4.14.3"
-    "@rollup/rollup-linux-x64-gnu" "4.14.3"
-    "@rollup/rollup-linux-x64-musl" "4.14.3"
-    "@rollup/rollup-win32-arm64-msvc" "4.14.3"
-    "@rollup/rollup-win32-ia32-msvc" "4.14.3"
-    "@rollup/rollup-win32-x64-msvc" "4.14.3"
+    "@rollup/rollup-android-arm-eabi" "4.14.2"
+    "@rollup/rollup-android-arm64" "4.14.2"
+    "@rollup/rollup-darwin-arm64" "4.14.2"
+    "@rollup/rollup-darwin-x64" "4.14.2"
+    "@rollup/rollup-linux-arm-gnueabihf" "4.14.2"
+    "@rollup/rollup-linux-arm64-gnu" "4.14.2"
+    "@rollup/rollup-linux-arm64-musl" "4.14.2"
+    "@rollup/rollup-linux-powerpc64le-gnu" "4.14.2"
+    "@rollup/rollup-linux-riscv64-gnu" "4.14.2"
+    "@rollup/rollup-linux-s390x-gnu" "4.14.2"
+    "@rollup/rollup-linux-x64-gnu" "4.14.2"
+    "@rollup/rollup-linux-x64-musl" "4.14.2"
+    "@rollup/rollup-win32-arm64-msvc" "4.14.2"
+    "@rollup/rollup-win32-ia32-msvc" "4.14.2"
+    "@rollup/rollup-win32-x64-msvc" "4.14.2"
     fsevents "~2.3.2"
 
 run-parallel@^1.1.9:
@@ -6634,7 +6628,16 @@ string-length@^4.0.1:
     char-regex "^1.0.2"
     strip-ansi "^6.0.0"
 
-"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
+"string-width-cjs@npm:string-width@^4.2.0":
+  version "4.2.3"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+  integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+  dependencies:
+    emoji-regex "^8.0.0"
+    is-fullwidth-code-point "^3.0.0"
+    strip-ansi "^6.0.1"
+
+"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
   version "4.2.3"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
   integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -6737,7 +6740,14 @@ string_decoder@^1.1.1:
   dependencies:
     safe-buffer "~5.2.0"
 
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+  version "6.0.1"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+  integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+  dependencies:
+    ansi-regex "^5.0.1"
+
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
   version "6.0.1"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
   integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -7392,7 +7402,16 @@ widest-line@^3.1.0:
   dependencies:
     string-width "^4.0.0"
 
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
+  integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+  dependencies:
+    ansi-styles "^4.0.0"
+    string-width "^4.1.0"
+    strip-ansi "^6.0.0"
+
+wrap-ansi@^7.0.0:
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
   integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==


Test patch:
diff --git a/test/calendar_test.test.js b/test/calendar_test.test.js
index 8b70b1fd..f3fbf465 100644
--- a/test/calendar_test.test.js
+++ b/test/calendar_test.test.js
@@ -1882,37 +1882,6 @@ describe("Calendar", () => {
     });
   });
 
-  it("should add the aria-label correctly to day names", () => {
-    const expectedAriaLabels = [
-      "Sunday",
-      "Monday",
-      "Tuesday",
-      "Wednesday",
-      "Thursday",
-      "Friday",
-      "Saturday",
-    ];
-
-    const { container } = render(
-      <Calendar
-        dateFormat={DATE_FORMAT}
-        onSelect={() => {}}
-        onClickOutside={() => {}}
-      />,
-    );
-
-    const header = container.querySelector(".react-datepicker__header");
-    const dayNameElements = header.querySelectorAll(
-      ".react-datepicker__day-name",
-    );
-
-    dayNameElements.forEach((element, index) => {
-      expect(element.getAttribute("aria-label")).toBe(
-        expectedAriaLabels[index],
-      );
-    });
-  });
-
   it("should have a next-button with the provided aria-label for year", () => {
     const ariaLabel = "A label in my native language for next year";
     const { container } = render(
diff --git a/test/date_utils_test.test.js b/test/date_utils_test.test.js
index 9659654b..e77adceb 100644
--- a/test/date_utils_test.test.js
+++ b/test/date_utils_test.test.js
@@ -49,7 +49,7 @@ import { setHours } from "date-fns/setHours";
 import { addQuarters } from "date-fns/addQuarters";
 import { ptBR } from "date-fns/locale/pt-BR";
 import { registerLocale } from "../src/date_utils";
-import { addYears, setSeconds } from "date-fns";
+import { addYears } from "date-fns";
 
 registerLocale("pt-BR", ptBR);
 
@@ -888,12 +888,9 @@ describe("date_utils", () => {
   describe("isTimeInDisabledRange", () => {
     it("should tell if time is in disabled range", () => {
       const date = newDate("2016-03-15");
-      let time = setHours(date, 1);
-      time = setMinutes(time, 30);
-      time = setSeconds(time, 30); // 2016-03-15 01:30:30
-
-      const minTime = setHours(setMinutes(date, 30), 0); //2016-03-15 00:30:00
-      const maxTime = setHours(setMinutes(setSeconds(date, 35), 30), 1); //2016-03-15 01:30:35
+      const time = setHours(setMinutes(date, 30), 1);
+      const minTime = setHours(setMinutes(date, 30), 0);
+      const maxTime = setHours(setMinutes(date, 30), 5);
       expect(isTimeInDisabledRange(time, { minTime, maxTime })).toBe(false);
     });
 
diff --git a/test/datepicker_test.test.js b/test/datepicker_test.test.js
index 5bf1d8af..efca1537 100644
--- a/test/datepicker_test.test.js
+++ b/test/datepicker_test.test.js
@@ -1285,25 +1285,6 @@ describe("DatePicker", () => {
     fireEvent.keyDown(data.dateInput, getKey("ArrowDown"));
     expect(data.instance.state.open).toBe(true);
   });
-  it("should focus first month when the down arrow key is pressed", async () => {
-    const div = document.createElement("div");
-    document.body.appendChild(div);
-    render(<DatePicker showMonthYearPicker />, {
-      container: div,
-    });
-
-    // user focuses the input field, the calendar opens
-    const dateInput = div.querySelector("input");
-    fireEvent.focus(dateInput);
-    fireEvent.keyDown(dateInput, getKey("ArrowDown"));
-
-    await waitFor(() => {
-      const selectedMonth = div.querySelector(
-        '.react-datepicker__month-text[tabindex="0"]',
-      );
-      expect(document.activeElement).toBe(selectedMonth);
-    });
-  });
   it("should not open the calendar when the left arrow key is pressed", () => {
     const data = getOnInputKeyDownStuff();
     act(() => {
diff --git a/test/include_times_test.test.js b/test/include_times_test.test.js
index 533e1811..758c0236 100644
--- a/test/include_times_test.test.js
+++ b/test/include_times_test.test.js
@@ -54,29 +54,4 @@ describe("TimeComponent", () => {
     });
     expect(enabledTimeItemsHasNoAriaDisabled).toBe(true);
   });
-
-  it("should factor in seconds", () => {
-    const includeHoursMinutesSeconds = [
-      utils.addHours(utils.addSeconds(today, 30), 1), //01:00:30
-      utils.addSeconds(today, 30), //00:00:30
-    ];
-    const { container: timeComponent } = render(
-      <TimeComponent
-        format="HH:mm:ss"
-        includeTimes={includeHoursMinutesSeconds}
-      />,
-    );
-
-    const disabledTimeItems = timeComponent.querySelectorAll(
-      ".react-datepicker__time-list-item--disabled",
-    );
-
-    // 01:00:00 and 00:00:00 should be correctly disabled because they are not included
-    expect(
-      Array.from(disabledTimeItems).map((node) => node.textContent),
-    ).toContain("01:00:00");
-    expect(
-      Array.from(disabledTimeItems).map((node) => node.textContent),
-    ).toContain("00:00:00");
-  });
 });
diff --git a/test/month_test.test.js b/test/month_test.test.js
index b8d5a30b..5b99ebcc 100644
--- a/test/month_test.test.js
+++ b/test/month_test.test.js
@@ -6,7 +6,6 @@ import range from "lodash/range";
 import * as utils from "../src/date_utils";
 import { runAxe } from "./run_axe";
 import { getKey } from "./test_utils";
-import { es } from "date-fns/locale";
 
 describe("Month", () => {
   function assertDateRangeInclusive(month, start, end) {
@@ -60,36 +59,6 @@ describe("Month", () => {
     ).toContain(expectedAriaLabel);
   });
 
-  it("should display month listbox aria-label in Spanish if Spanish locale is provided", () => {
-    utils.registerLocale("es", es);
-    const date = utils.newDate("2015-12-01");
-    const { container } = render(
-      <Month day={date} locale="es" showMonthYearPicker />,
-    );
-    const expectedAriaLabel = utils.formatDate(date, "MMMM, yyyy", "es");
-
-    expect(
-      container
-        .querySelector(".react-datepicker__month")
-        .getAttribute("aria-label"),
-    ).toContain(expectedAriaLabel);
-  });
-
-  it("should display month options aria-label in Spanish if Spanish locale is provided", () => {
-    utils.registerLocale("es", es);
-    const date = utils.newDate("2015-01-01");
-    const { container } = render(
-      <Month day={date} locale="es" showMonthYearPicker />,
-    );
-    const expectedAriaLabel = utils.formatDate(date, "MMMM yyyy", "es");
-
-    expect(
-      container
-        .querySelectorAll(".react-datepicker__month-text")[0]
-        .getAttribute("aria-label"),
-    ).toContain(expectedAriaLabel);
-  });
-
   it("should have the month aria-label with the specified prefix", () => {
     const date = utils.newDate("2015-12-01");
     const ariaLabelPrefix = "Selected Month";
diff --git a/test/year_picker_test.test.js b/test/year_picker_test.test.js
index 0d54815b..6b58e57a 100644
--- a/test/year_picker_test.test.js
+++ b/test/year_picker_test.test.js
@@ -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");
 
@@ -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");