Repository: Hacker0x01/react-datepicker
Pull request #4979 (2024-07-16 21:52:41)

Remove usages of react-onclickoutside to support React 19
## Description
Closes https://github.com/Hacker0x01/react-datepicker/issues/4801
Closes https://github.com/Hacker0x01/react-datepicker/issues/4605

**Problem**
React 19 removed `findDOMNode` and `react-onclickoutside` is not supported

**Changes**

- Remove `react-onclickoutside` and replace with custom wrapper
- Update the `onClickOutside` to use `MouseEvent` instead of `React.MouseEvent` since it's a document event listener

## Screenshots
<!-- If applicable, add screenshots to help explain your improvements -->

## To reviewers
<!-- Additional comments for reviewers -->

## 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/docs-site/package.json b/docs-site/package.json
index 29bc7353..f929374e 100644
--- a/docs-site/package.json
+++ b/docs-site/package.json
@@ -3,7 +3,7 @@
   "version": "0.1.0",
   "private": true,
   "dependencies": {
-    "highlight.js": "^11.10.0",
+    "highlight.js": "^11.9.0",
     "react": "^18.3.1",
     "react-dom": "^18.3.1",
     "react-live": "^4.1.7"
@@ -33,7 +33,7 @@
     "raw-loader": "^4.0.2",
     "react-app-rewired": "^2.2.1",
     "react-scripts": "5.0.1",
-    "sass": "^1.77.8"
+    "sass": "^1.77.6"
   },
   "resolutions": {
     "strip-ansi": "6.0.1"
diff --git a/docs-site/yarn.lock b/docs-site/yarn.lock
index 275dc7f4..77e54846 100644
--- a/docs-site/yarn.lock
+++ b/docs-site/yarn.lock
@@ -4808,10 +4808,10 @@ he@^1.2.0:
   resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
   integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
 
-highlight.js@^11.10.0:
-  version "11.10.0"
-  resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.10.0.tgz#6e3600dc4b33d6dc23d5bd94fbf72405f5892b92"
-  integrity sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==
+highlight.js@^11.9.0:
+  version "11.9.0"
+  resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.9.0.tgz#04ab9ee43b52a41a047432c8103e2158a1b8b5b0"
+  integrity sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==
 
 hoopy@^0.1.4:
   version "0.1.4"
@@ -7804,10 +7804,10 @@ sass-loader@^12.3.0:
     klona "^2.0.4"
     neo-async "^2.6.2"
 
-sass@^1.77.8:
-  version "1.77.8"
-  resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.8.tgz#9f18b449ea401759ef7ec1752a16373e296b52bd"
-  integrity sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==
+sass@^1.77.6:
+  version "1.77.6"
+  resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.6.tgz#898845c1348078c2e6d1b64f9ee06b3f8bd489e4"
+  integrity sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==
   dependencies:
     chokidar ">=3.0.0 <4.0.0"
     immutable "^4.0.0"
diff --git a/examples/hello-world/package.json b/examples/hello-world/package.json
index 17be9a02..ba165be6 100644
--- a/examples/hello-world/package.json
+++ b/examples/hello-world/package.json
@@ -4,7 +4,7 @@
   "private": true,
   "dependencies": {
     "react": "^18.3.1",
-    "react-datepicker": "^7.3.0",
+    "react-datepicker": "^7.2.0",
     "react-dom": "^18.3.1",
     "react-scripts": "5.0.1"
   },
diff --git a/examples/hello-world/yarn.lock b/examples/hello-world/yarn.lock
index e7356a7b..fa0ae456 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@^7.3.0:
-  version "7.3.0"
-  resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-7.3.0.tgz#666664a609d4b57b095083fe29d080943fa7b3ed"
-  integrity sha512-EqRKLAtLZUTztiq6a+tjSjQX9ES0Xd229JPckAtyZZ4GoY3rtvNWAzkYZnQUf6zTWT50Ki0+t+W9VRQIkSJLfg==
+react-datepicker@^7.2.0:
+  version "7.2.0"
+  resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-7.2.0.tgz#2d430caebb5c8b0fb988286d004aa2676ace665f"
+  integrity sha512-Hhs1Fk6/ZqpGGg9QX/JjzvgEJoSFKYCAvRVdBbjxvOjflsXutFprAl/E0ZOm1J+/b/jQqU03WMTTNLcw5nXcuw==
   dependencies:
     "@floating-ui/react" "^0.26.2"
     clsx "^2.1.0"
diff --git a/package.json b/package.json
index 4418802b..2e25a045 100644
--- a/package.json
+++ b/package.json
@@ -40,7 +40,6 @@
     "@types/eslint": "^8.56.10",
     "@types/jest": "^29.5.12",
     "@types/node": "20",
-    "@types/react-onclickoutside": "^6.7.10",
     "@typescript-eslint/eslint-plugin": "^7.9.0",
     "@typescript-eslint/parser": "^7.9.0",
     "axe-core": "^4.4.1",
@@ -83,8 +82,7 @@
     "@floating-ui/react": "^0.26.2",
     "clsx": "^2.1.0",
     "date-fns": "^3.3.1",
-    "prop-types": "^15.7.2",
-    "react-onclickoutside": "^6.13.0"
+    "prop-types": "^15.7.2"
   },
   "scripts": {
     "eslint": "eslint --ext .js,.jsx,.ts,.tsx ./src",
diff --git a/rollup.config.mjs b/rollup.config.mjs
index 872cb788..6b631e86 100644
--- a/rollup.config.mjs
+++ b/rollup.config.mjs
@@ -46,7 +46,6 @@ const dateFnsSubpackages = Object.keys(dateFnsPackageJson.exports)
 const globals = {
   react: "React",
   "prop-types": "PropTypes",
-  "react-onclickoutside": "onClickOutside",
 };
 
 // NOTE:https://rollupjs.org/migration/#changed-defaults
diff --git a/src/@types/react-onclickoutside/index.d.ts b/src/@types/react-onclickoutside/index.d.ts
deleted file mode 100644
index 2f400d15..00000000
--- a/src/@types/react-onclickoutside/index.d.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import type { findDOMNode } from "react-dom";
-
-declare module "react-onclickoutside" {
-  // eslint-disable-next-line unused-imports/no-unused-vars
-  interface WrapperInstance<P, C> {
-    componentNode: ReturnType<typeof findDOMNode>;
-  }
-}
diff --git a/src/calendar.tsx b/src/calendar.tsx
index 86f3ea58..bff1a703 100644
--- a/src/calendar.tsx
+++ b/src/calendar.tsx
@@ -2,6 +2,7 @@ import { clsx } from "clsx";
 import React, { Component, createRef } from "react";
 
 import CalendarContainer from "./calendar_container";
+import { ClickOutsideWrapper } from "./click_outside_wrapper";
 import {
   newDate,
   setMonth,
@@ -48,6 +49,7 @@ import Time from "./time";
 import Year from "./year";
 import YearDropdown from "./year_dropdown";
 
+import type { ClickOutsideHandler } from "./click_outside_wrapper";
 import type { Day } from "date-fns/types";
 
 interface YearDropdownProps
@@ -154,7 +156,8 @@ type CalendarProps = React.PropsWithChildren &
     onDayMouseEnter?: (date: Date) => void;
     onMonthMouseLeave?: VoidFunction;
     weekLabel?: string;
-    onClickOutside: React.MouseEventHandler<HTMLElement>;
+    onClickOutside: ClickOutsideHandler;
+    outsideClickIgnoreClass?: string;
     previousMonthButtonLabel?: React.ReactNode;
     previousYearButtonLabel?: string;
     previousMonthAriaLabel?: string;
@@ -279,7 +282,7 @@ export default class Calendar extends Component<CalendarProps, CalendarState> {
 
   assignMonthContainer: void | undefined;
 
-  handleClickOutside = (event: React.MouseEvent<HTMLElement>): void => {
+  handleClickOutside = (event: MouseEvent): void => {
     this.props.onClickOutside(event);
   };
 
@@ -1082,7 +1085,12 @@ export default class Calendar extends Component<CalendarProps, CalendarState> {
   render(): JSX.Element {
     const Container = this.props.container || CalendarContainer;
     return (
-      <div style={{ display: "contents" }} ref={this.containerRef}>
+      <ClickOutsideWrapper
+        onClickOutside={this.handleClickOutside}
+        style={{ display: "contents" }}
+        containerRef={this.containerRef}
+        ignoreClass={this.props.outsideClickIgnoreClass}
+      >
         <Container
           className={clsx("react-datepicker", this.props.className, {
             "react-datepicker--time-only": this.props.showTimeSelectOnly,
@@ -1100,7 +1108,7 @@ export default class Calendar extends Component<CalendarProps, CalendarState> {
           {this.renderInputTimeSection()}
           {this.renderChildren()}
         </Container>
-      </div>
+      </ClickOutsideWrapper>
     );
   }
 }
diff --git a/src/click_outside_wrapper.tsx b/src/click_outside_wrapper.tsx
new file mode 100644
index 00000000..25203465
--- /dev/null
+++ b/src/click_outside_wrapper.tsx
@@ -0,0 +1,69 @@
+import React, { useCallback, useEffect, useRef } from "react";
+
+export type ClickOutsideHandler = (event: MouseEvent) => void;
+
+interface ClickOutsideWrapperProps {
+  onClickOutside: ClickOutsideHandler;
+  className?: string;
+  children: React.ReactNode;
+  containerRef?: React.MutableRefObject<HTMLDivElement | null>;
+  style?: React.CSSProperties;
+  ignoreClass?: string;
+}
+
+const useDetectClickOutside = (
+  onClickOutside: ClickOutsideHandler,
+  ignoreClass?: string,
+) => {
+  const ref = useRef<HTMLDivElement | null>(null);
+  const onClickOutsideRef = useRef(onClickOutside);
+  onClickOutsideRef.current = onClickOutside;
+  const handleClickOutside = useCallback(
+    (event: MouseEvent) => {
+      if (ref.current && !ref.current.contains(event.target as Node)) {
+        if (
+          !(
+            ignoreClass &&
+            event.target instanceof HTMLElement &&
+            event.target.classList.contains(ignoreClass)
+          )
+        ) {
+          onClickOutsideRef.current?.(event);
+        }
+      }
+    },
+    [ignoreClass],
+  );
+  useEffect(() => {
+    document.addEventListener("mousedown", handleClickOutside);
+    return () => {
+      document.removeEventListener("mousedown", handleClickOutside);
+    };
+  }, [handleClickOutside]);
+  return ref;
+};
+
+export const ClickOutsideWrapper: React.FC<ClickOutsideWrapperProps> = ({
+  children,
+  onClickOutside,
+  className,
+  containerRef,
+  style,
+  ignoreClass,
+}) => {
+  const detectRef = useDetectClickOutside(onClickOutside, ignoreClass);
+  return (
+    <div
+      className={className}
+      style={style}
+      ref={(node: HTMLDivElement | null) => {
+        detectRef.current = node;
+        if (containerRef) {
+          containerRef.current = node;
+        }
+      }}
+    >
+      {children}
+    </div>
+  );
+};
diff --git a/src/index.tsx b/src/index.tsx
index fbceec1e..e19ceef7 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,9 +1,5 @@
 import { clsx } from "clsx";
 import React, { Component, cloneElement } from "react";
-import onClickOutside, {
-  type WrapperInstance,
-  type AdditionalProps,
-} from "react-onclickoutside";
 
 import Calendar from "./calendar";
 import CalendarIcon from "./calendar_icon";
@@ -59,12 +55,13 @@ import PopperComponent from "./popper_component";
 import Portal from "./portal";
 import TabLoop from "./tab_loop";
 
+import type { ClickOutsideHandler } from "./click_outside_wrapper";
+
 export { default as CalendarContainer } from "./calendar_container";
 
 export { registerLocale, setDefaultLocale, getDefaultLocale };
 
 const outsideClickIgnoreClass = "react-datepicker-ignore-onclickoutside";
-const WrappedCalendar = onClickOutside(Calendar);
 
 export { ReactDatePickerCustomHeaderProps } from "./calendar";
 
@@ -102,7 +99,10 @@ interface PortalProps extends React.ComponentPropsWithoutRef<typeof Portal> {}
 interface PopperComponentProps
   extends React.ComponentPropsWithoutRef<typeof PopperComponent> {}
 
-export type DatePickerProps = Omit<
+// see https://github.com/microsoft/TypeScript/issues/31501
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+type OmitUnion<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
+export type DatePickerProps = OmitUnion<
   CalendarProps,
   | "setOpen"
   | "dateFormat"
@@ -126,10 +126,9 @@ export type DatePickerProps = Omit<
   | "selectsMultiple"
   | "dropdownMode"
 > &
-  Partial<Pick<AdditionalProps, "excludeScrollbar">> &
   Pick<CalendarIconProps, "icon"> &
-  Omit<PortalProps, "children" | "portalId"> &
-  Omit<
+  OmitUnion<PortalProps, "children" | "portalId"> &
+  OmitUnion<
     PopperComponentProps,
     | "className"
     | "hidePopper"
@@ -151,7 +150,7 @@ export type DatePickerProps = Omit<
     startOpen?: boolean;
     onFocus?: React.FocusEventHandler<HTMLElement>;
     onBlur?: React.FocusEventHandler<HTMLElement>;
-    onClickOutside?: React.MouseEventHandler<HTMLElement>;
+    onClickOutside?: ClickOutsideHandler;
     onInputClick?: VoidFunction;
     preventOpenOnFocus?: boolean;
     closeOnScroll?: boolean | ((event: Event) => boolean);
@@ -383,7 +382,7 @@ export default class DatePicker extends Component<
 
   inputFocusTimeout: ReturnType<typeof setTimeout> | undefined;
 
-  calendar: WrapperInstance<CalendarProps, typeof Calendar> | null = null;
+  calendar: Calendar | null = null;
 
   input: HTMLElement | null = null;
 
@@ -568,7 +567,7 @@ export default class DatePicker extends Component<
     this.setState({ focused: false });
   };
 
-  handleCalendarClickOutside = (event: React.MouseEvent<HTMLElement>) => {
+  handleCalendarClickOutside = (event: MouseEvent) => {
     if (!this.props.inline) {
       this.setOpen(false);
     }
@@ -932,8 +931,8 @@ export default class DatePicker extends Component<
               ? '.react-datepicker__month-text[tabindex="0"]'
               : '.react-datepicker__day[tabindex="0"]';
         const selectedItem =
-          this.calendar?.componentNode instanceof Element &&
-          this.calendar.componentNode.querySelector(selectorString);
+          this.calendar?.containerRef.current instanceof Element &&
+          this.calendar.containerRef.current.querySelector(selectorString);
         selectedItem instanceof HTMLElement &&
           selectedItem.focus({ preventScroll: true });
 
@@ -1214,7 +1213,8 @@ export default class DatePicker extends Component<
       return null;
     }
     return (
-      <WrappedCalendar
+      <Calendar
+        showMonthYearDropdown={undefined}
         ref={(elem) => {
           this.calendar = elem;
         }}
@@ -1241,7 +1241,7 @@ export default class DatePicker extends Component<
         }
       >
         {this.props.children}
-      </WrappedCalendar>
+      </Calendar>
     );
   };
 
diff --git a/src/month_dropdown.tsx b/src/month_dropdown.tsx
index fb7825f9..8a0ed183 100644
--- a/src/month_dropdown.tsx
+++ b/src/month_dropdown.tsx
@@ -1,5 +1,4 @@
 import React, { Component } from "react";
-import onClickOutside from "react-onclickoutside";
 
 import {
   getMonthShortInLocale,
@@ -11,8 +10,6 @@ import MonthDropdownOptions from "./month_dropdown_options";
 interface MonthDropdownOptionsProps
   extends React.ComponentPropsWithoutRef<typeof MonthDropdownOptions> {}
 
-const WrappedMonthDropdownOptions = onClickOutside(MonthDropdownOptions);
-
 interface MonthDropdownProps
   extends Omit<
     MonthDropdownOptionsProps,
@@ -70,7 +67,7 @@ export default class MonthDropdown extends Component<
   );
 
   renderDropdown = (monthNames: string[]): JSX.Element => (
-    <WrappedMonthDropdownOptions
+    <MonthDropdownOptions
       key="dropdown"
       {...this.props}
       monthNames={monthNames}
diff --git a/src/month_dropdown_options.tsx b/src/month_dropdown_options.tsx
index 319e4725..fd8a270a 100644
--- a/src/month_dropdown_options.tsx
+++ b/src/month_dropdown_options.tsx
@@ -1,5 +1,7 @@
 import React, { Component } from "react";
 
+import { ClickOutsideWrapper } from "./click_outside_wrapper";
+
 interface MonthDropdownOptionsProps {
   onCancel: VoidFunction;
   onChange: (month: number) => void;
@@ -40,9 +42,12 @@ export default class MonthDropdownOptions extends Component<MonthDropdownOptions
 
   render(): JSX.Element {
     return (
-      <div className="react-datepicker__month-dropdown">
+      <ClickOutsideWrapper
+        className="react-datepicker__month-dropdown"
+        onClickOutside={this.handleClickOutside}
+      >
         {this.renderOptions()}
-      </div>
+      </ClickOutsideWrapper>
     );
   }
 }
diff --git a/src/month_year_dropdown.tsx b/src/month_year_dropdown.tsx
index 148416c5..6367f9dd 100644
--- a/src/month_year_dropdown.tsx
+++ b/src/month_year_dropdown.tsx
@@ -1,5 +1,4 @@
 import React, { Component } from "react";
-import onClickOutside from "react-onclickoutside";
 
 import {
   addMonths,
@@ -17,10 +16,6 @@ import MonthYearDropdownOptions from "./month_year_dropdown_options";
 interface MonthYearDropdownOptionsProps
   extends React.ComponentPropsWithoutRef<typeof MonthYearDropdownOptions> {}
 
-const WrappedMonthYearDropdownOptions = onClickOutside(
-  MonthYearDropdownOptions,
-);
-
 interface MonthYearDropdownProps
   extends Omit<MonthYearDropdownOptionsProps, "onChange" | "onCancel"> {
   dropdownMode: "scroll" | "select";
@@ -96,7 +91,7 @@ export default class MonthYearDropdown extends Component<
   };
 
   renderDropdown = (): JSX.Element => (
-    <WrappedMonthYearDropdownOptions
+    <MonthYearDropdownOptions
       key="dropdown"
       {...this.props}
       onChange={this.onChange}
diff --git a/src/month_year_dropdown_options.tsx b/src/month_year_dropdown_options.tsx
index 49b5a7a4..615c5ced 100644
--- a/src/month_year_dropdown_options.tsx
+++ b/src/month_year_dropdown_options.tsx
@@ -1,6 +1,7 @@
 import { clsx } from "clsx";
 import React, { Component } from "react";
 
+import { ClickOutsideWrapper } from "./click_outside_wrapper";
 import {
   addMonths,
   formatDate,
@@ -103,6 +104,13 @@ export default class MonthYearDropdownOptions extends Component<
         this.props.scrollableMonthYearDropdown,
     });
 
-    return <div className={dropdownClass}>{this.renderOptions()}</div>;
+    return (
+      <ClickOutsideWrapper
+        className={dropdownClass}
+        onClickOutside={this.handleClickOutside}
+      >
+        {this.renderOptions()}
+      </ClickOutsideWrapper>
+    );
   }
 }
diff --git a/src/year_dropdown.tsx b/src/year_dropdown.tsx
index 695f55b3..f079dca3 100644
--- a/src/year_dropdown.tsx
+++ b/src/year_dropdown.tsx
@@ -1,5 +1,4 @@
 import React, { Component } from "react";
-import onClickOutside from "react-onclickoutside";
 
 import { getYear } from "./date_utils";
 import YearDropdownOptions from "./year_dropdown_options";
@@ -7,8 +6,6 @@ import YearDropdownOptions from "./year_dropdown_options";
 interface YearDropdownOptionsProps
   extends React.ComponentPropsWithoutRef<typeof YearDropdownOptions> {}
 
-const WrappedYearDropdownOptions = onClickOutside(YearDropdownOptions);
-
 interface YearDropdownProps
   extends Omit<YearDropdownOptionsProps, "onChange" | "onCancel"> {
   adjustDateOnChange?: boolean;
@@ -81,7 +78,7 @@ export default class YearDropdown extends Component<
   );
 
   renderDropdown = (): JSX.Element => (
-    <WrappedYearDropdownOptions
+    <YearDropdownOptions
       key="dropdown"
       {...this.props}
       onChange={this.onChange}
diff --git a/src/year_dropdown_options.tsx b/src/year_dropdown_options.tsx
index 36a81df8..dff93e1e 100644
--- a/src/year_dropdown_options.tsx
+++ b/src/year_dropdown_options.tsx
@@ -1,6 +1,7 @@
 import { clsx } from "clsx";
 import React, { Component, createRef } from "react";
 
+import { ClickOutsideWrapper } from "./click_outside_wrapper";
 import { getYear } from "./date_utils";
 
 function generateYears(
@@ -174,9 +175,13 @@ export default class YearDropdownOptions extends Component<
     });
 
     return (
-      <div className={dropdownClass} ref={this.dropdownRef}>
+      <ClickOutsideWrapper
+        className={dropdownClass}
+        containerRef={this.dropdownRef}
+        onClickOutside={this.handleClickOutside}
+      >
         {this.renderOptions()}
-      </div>
+      </ClickOutsideWrapper>
     );
   }
 }
diff --git a/yarn.lock b/yarn.lock
index 98a1708b..4fe1b96c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1749,85 +1749,85 @@
     estree-walker "^2.0.2"
     picomatch "^2.3.1"
 
-"@rollup/rollup-android-arm-eabi@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz#f0da481244b7d9ea15296b35f7fe39cd81157396"
-  integrity sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==
-
-"@rollup/rollup-android-arm64@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz#82ab3c575f4235fb647abea5e08eec6cf325964e"
-  integrity sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==
-
-"@rollup/rollup-darwin-arm64@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz#6a530452e68a9152809ce58de1f89597632a085b"
-  integrity sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==
-
-"@rollup/rollup-darwin-x64@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz#47727479f5ca292cf434d7e75af2725b724ecbc7"
-  integrity sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==
-
-"@rollup/rollup-linux-arm-gnueabihf@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz#46193c498aa7902a8db89ac00128060320e84fef"
-  integrity sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==
-
-"@rollup/rollup-linux-arm-musleabihf@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz#22d831fe239643c1d05c98906420325cee439d85"
-  integrity sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==
-
-"@rollup/rollup-linux-arm64-gnu@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz#19abd33695ec9d588b4a858d122631433084e4a3"
-  integrity sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==
-
-"@rollup/rollup-linux-arm64-musl@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz#d60af8c0b9be424424ff96a0ba19fce65d26f6ab"
-  integrity sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==
-
-"@rollup/rollup-linux-powerpc64le-gnu@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz#b1194e5ed6d138fdde0842d126fccde74a90f457"
-  integrity sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==
-
-"@rollup/rollup-linux-riscv64-gnu@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz#f5a635c017b9bff8b856b0221fbd5c0e3373b7ec"
-  integrity sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==
-
-"@rollup/rollup-linux-s390x-gnu@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz#f1043d9f4026bf6995863cb3f8dd4732606e4baa"
-  integrity sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==
-
-"@rollup/rollup-linux-x64-gnu@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz#1e781730be445119f06c9df5f185e193bc82c610"
-  integrity sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==
-
-"@rollup/rollup-linux-x64-musl@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz#08f12e1965d6f27d6898ff932592121cca6abc4b"
-  integrity sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==
-
-"@rollup/rollup-win32-arm64-msvc@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz#4a5dcbbe7af7d41cac92b09798e7c1831da1f599"
-  integrity sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==
-
-"@rollup/rollup-win32-ia32-msvc@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz#075b0713de627843a73b4cf0e087c56b53e9d780"
-  integrity sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==
-
-"@rollup/rollup-win32-x64-msvc@4.18.1":
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz#0cb240c147c0dfd0e3eaff4cc060a772d39e155c"
-  integrity sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==
+"@rollup/rollup-android-arm-eabi@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz#bbd0e616b2078cd2d68afc9824d1fadb2f2ffd27"
+  integrity sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==
+
+"@rollup/rollup-android-arm64@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz#97255ef6384c5f73f4800c0de91f5f6518e21203"
+  integrity sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==
+
+"@rollup/rollup-darwin-arm64@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz#b6dd74e117510dfe94541646067b0545b42ff096"
+  integrity sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==
+
+"@rollup/rollup-darwin-x64@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz#e07d76de1cec987673e7f3d48ccb8e106d42c05c"
+  integrity sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==
+
+"@rollup/rollup-linux-arm-gnueabihf@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz#9f1a6d218b560c9d75185af4b8bb42f9f24736b8"
+  integrity sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==
+
+"@rollup/rollup-linux-arm-musleabihf@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz#53618b92e6ffb642c7b620e6e528446511330549"
+  integrity sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==
+
+"@rollup/rollup-linux-arm64-gnu@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz#99a7ba5e719d4f053761a698f7b52291cefba577"
+  integrity sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==
+
+"@rollup/rollup-linux-arm64-musl@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz#f53db99a45d9bc00ce94db8a35efa7c3c144a58c"
+  integrity sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==
+
+"@rollup/rollup-linux-powerpc64le-gnu@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz#cbb0837408fe081ce3435cf3730e090febafc9bf"
+  integrity sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==
+
+"@rollup/rollup-linux-riscv64-gnu@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz#8ed09c1d1262ada4c38d791a28ae0fea28b80cc9"
+  integrity sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==
+
+"@rollup/rollup-linux-s390x-gnu@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz#938138d3c8e0c96f022252a28441dcfb17afd7ec"
+  integrity sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==
+
+"@rollup/rollup-linux-x64-gnu@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz#1a7481137a54740bee1ded4ae5752450f155d942"
+  integrity sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==
+
+"@rollup/rollup-linux-x64-musl@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz#f1186afc601ac4f4fc25fac4ca15ecbee3a1874d"
+  integrity sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==
+
+"@rollup/rollup-win32-arm64-msvc@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz#ed6603e93636a96203c6915be4117245c1bd2daf"
+  integrity sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==
+
+"@rollup/rollup-win32-ia32-msvc@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz#14e0b404b1c25ebe6157a15edb9c46959ba74c54"
+  integrity sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==
+
+"@rollup/rollup-win32-x64-msvc@4.18.0":
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz#5d694d345ce36b6ecf657349e03eb87297e68da4"
+  integrity sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==
 
 "@sigstore/protobuf-specs@^0.1.0":
   version "0.1.0"
@@ -2030,13 +2030,6 @@
   dependencies:
     "@types/react" "*"
 
-"@types/react-onclickoutside@^6.7.10":
-  version "6.7.10"
-  resolved "https://registry.yarnpkg.com/@types/react-onclickoutside/-/react-onclickoutside-6.7.10.tgz#aeaf56aac4b67185a69038d22c55bd0726f13123"
-  integrity sha512-Do2eOuqlJ9amXAuQO5gbhp5MAPnzZ7cknmYqX4U44tX22eAAnHgQKjp3SaNhSAuUHBTANWEqn1N+nWd3ea8FyQ==
-  dependencies:
-    "@types/react" "*"
-
 "@types/react@*":
   version "18.2.21"
   resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.21.tgz#774c37fd01b522d0b91aed04811b58e4e0514ed9"
@@ -2084,61 +2077,61 @@
     "@types/yargs-parser" "*"
 
 "@typescript-eslint/eslint-plugin@^7.9.0":
-  version "7.16.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz#f5f5da52db674b1f2cdb9d5f3644e5b2ec750465"
-  integrity sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz#8eaf396ac2992d2b8f874b68eb3fcd6b179cb7f3"
+  integrity sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==
   dependencies:
     "@eslint-community/regexpp" "^4.10.0"
-    "@typescript-eslint/scope-manager" "7.16.1"
-    "@typescript-eslint/type-utils" "7.16.1"
-    "@typescript-eslint/utils" "7.16.1"
-    "@typescript-eslint/visitor-keys" "7.16.1"
+    "@typescript-eslint/scope-manager" "7.15.0"
+    "@typescript-eslint/type-utils" "7.15.0"
+    "@typescript-eslint/utils" "7.15.0"
+    "@typescript-eslint/visitor-keys" "7.15.0"
     graphemer "^1.4.0"
     ignore "^5.3.1"
     natural-compare "^1.4.0"
     ts-api-utils "^1.3.0"
 
 "@typescript-eslint/parser@^7.9.0":
-  version "7.16.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.16.1.tgz#84c581cf86c8b2becd48d33ddc41a6303d57b274"
-  integrity sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==
-  dependencies:
-    "@typescript-eslint/scope-manager" "7.16.1"
-    "@typescript-eslint/types" "7.16.1"
-    "@typescript-eslint/typescript-estree" "7.16.1"
-    "@typescript-eslint/visitor-keys" "7.16.1"
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.15.0.tgz#f4a536e5fc6a1c05c82c4d263a2bfad2da235c80"
+  integrity sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==
+  dependencies:
+    "@typescript-eslint/scope-manager" "7.15.0"
+    "@typescript-eslint/types" "7.15.0"
+    "@typescript-eslint/typescript-estree" "7.15.0"
+    "@typescript-eslint/visitor-keys" "7.15.0"
     debug "^4.3.4"
 
-"@typescript-eslint/scope-manager@7.16.1":
-  version "7.16.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz#2b43041caabf8ddd74512b8b550b9fc53ca3afa1"
-  integrity sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==
+"@typescript-eslint/scope-manager@7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz#201b34b0720be8b1447df17b963941bf044999b2"
+  integrity sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==
   dependencies:
-    "@typescript-eslint/types" "7.16.1"
-    "@typescript-eslint/visitor-keys" "7.16.1"
+    "@typescript-eslint/types" "7.15.0"
+    "@typescript-eslint/visitor-keys" "7.15.0"
 
-"@typescript-eslint/type-utils@7.16.1":
-  version "7.16.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz#4d7ae4f3d9e3c8cbdabae91609b1a431de6aa6ca"
-  integrity sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==
+"@typescript-eslint/type-utils@7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz#5b83c904c6de91802fb399305a50a56d10472c39"
+  integrity sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==
   dependencies:
-    "@typescript-eslint/typescript-estree" "7.16.1"
-    "@typescript-eslint/utils" "7.16.1"
+    "@typescript-eslint/typescript-estree" "7.15.0"
+    "@typescript-eslint/utils" "7.15.0"
     debug "^4.3.4"
     ts-api-utils "^1.3.0"
 
-"@typescript-eslint/types@7.16.1":
-  version "7.16.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.16.1.tgz#bbab066276d18e398bc64067b23f1ce84dfc6d8c"
-  integrity sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==
+"@typescript-eslint/types@7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.15.0.tgz#fb894373a6e3882cbb37671ffddce44f934f62fc"
+  integrity sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==
 
-"@typescript-eslint/typescript-estree@7.16.1":
-  version "7.16.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz#9b145ba4fd1dde1986697e1ce57dc501a1736dd3"
-  integrity sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==
+"@typescript-eslint/typescript-estree@7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.15.0.tgz#e323bfa3966e1485b638ce751f219fc1f31eba37"
+  integrity sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==
   dependencies:
-    "@typescript-eslint/types" "7.16.1"
-    "@typescript-eslint/visitor-keys" "7.16.1"
+    "@typescript-eslint/types" "7.15.0"
+    "@typescript-eslint/visitor-keys" "7.15.0"
     debug "^4.3.4"
     globby "^11.1.0"
     is-glob "^4.0.3"
@@ -2146,22 +2139,22 @@
     semver "^7.6.0"
     ts-api-utils "^1.3.0"
 
-"@typescript-eslint/utils@7.16.1", "@typescript-eslint/utils@^6.0.0 || ^7.0.0":
-  version "7.16.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.16.1.tgz#df42dc8ca5a4603016fd102db0346cdab415cdb7"
-  integrity sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==
+"@typescript-eslint/utils@7.15.0", "@typescript-eslint/utils@^6.0.0 || ^7.0.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.15.0.tgz#9e6253c4599b6e7da2fb64ba3f549c73eb8c1960"
+  integrity sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==
   dependencies:
     "@eslint-community/eslint-utils" "^4.4.0"
-    "@typescript-eslint/scope-manager" "7.16.1"
-    "@typescript-eslint/types" "7.16.1"
-    "@typescript-eslint/typescript-estree" "7.16.1"
+    "@typescript-eslint/scope-manager" "7.15.0"
+    "@typescript-eslint/types" "7.15.0"
+    "@typescript-eslint/typescript-estree" "7.15.0"
 
-"@typescript-eslint/visitor-keys@7.16.1":
-  version "7.16.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz#4287bcf44c34df811ff3bb4d269be6cfc7d8c74b"
-  integrity sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==
+"@typescript-eslint/visitor-keys@7.15.0":
+  version "7.15.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz#1da0726201a859343fe6a05742a7c1792fff5b66"
+  integrity sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==
   dependencies:
-    "@typescript-eslint/types" "7.16.1"
+    "@typescript-eslint/types" "7.15.0"
     eslint-visitor-keys "^3.4.3"
 
 "@ungap/structured-clone@^1.2.0":
@@ -2471,11 +2464,6 @@ astral-regex@^2.0.0:
   resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
   integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
 
-async@^3.2.3:
-  version "3.2.5"
-  resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66"
-  integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==
-
 asynckit@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -2781,7 +2769,7 @@ chalk@^2.4.2:
     escape-string-regexp "^1.0.5"
     supports-color "^5.3.0"
 
-chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0:
+chalk@^4.0.0, chalk@^4.1.0:
   version "4.1.2"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
   integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
@@ -3241,13 +3229,6 @@ eastasianwidth@^0.2.0:
   resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
   integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
 
-ejs@^3.0.0:
-  version "3.1.10"
-  resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b"
-  integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==
-  dependencies:
-    jake "^10.8.5"
-
 electron-to-chromium@^1.4.648:
   version "1.4.652"
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.652.tgz#1591c7542d43c990de786374c07a9d6ad2b63787"
@@ -3927,13 +3908,6 @@ file-entry-cache@^9.0.0:
   dependencies:
     flat-cache "^5.0.0"
 
-filelist@^1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5"
-  integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==
-  dependencies:
-    minimatch "^5.0.1"
-
 filesize@^6.1.0:
   version "6.4.0"
   resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.4.0.tgz#914f50471dd66fdca3cefe628bd0cde4ef769bcd"
@@ -4894,16 +4868,6 @@ jackspeak@^3.1.2:
   optionalDependencies:
     "@pkgjs/parseargs" "^0.11.0"
 
-jake@^10.8.5:
-  version "10.9.1"
-  resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.1.tgz#8dc96b7fcc41cb19aa502af506da4e1d56f5e62b"
-  integrity sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==
-  dependencies:
-    async "^3.2.3"
-    chalk "^4.0.2"
-    filelist "^1.0.4"
-    minimatch "^3.1.2"
-
 jest-canvas-mock@^2.5.2:
   version "2.5.2"
   resolved "https://registry.yarnpkg.com/jest-canvas-mock/-/jest-canvas-mock-2.5.2.tgz#7e21ebd75e05ab41c890497f6ba8a77f915d2ad6"
@@ -5669,13 +5633,6 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
   dependencies:
     brace-expansion "^1.1.7"
 
-minimatch@^5.0.1:
-  version "5.1.6"
-  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
-  integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
-  dependencies:
-    brace-expansion "^2.0.1"
-
 minimatch@^9.0.0, minimatch@^9.0.4:
   version "9.0.4"
   resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51"
@@ -6392,11 +6349,6 @@ react-is@^18.0.0:
   resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
   integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
 
-react-onclickoutside@^6.13.0:
-  version "6.13.1"
-  resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.13.1.tgz#1f5e0241c08784b6e65745d91aca0d700c548a89"
-  integrity sha512-LdrrxK/Yh9zbBQdFbMTXPp3dTSN9B+9YJQucdDu3JNKRrbdU+H+/TVONJoWtOwy4II8Sqf1y/DTI6w/vGPYW0w==
-
 react@^18.2.0:
   version "18.3.1"
   resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891"
@@ -6622,28 +6574,28 @@ rollup-plugin-filesize@^10.0.0:
     terser "^5.6.0"
 
 rollup@^4.13.0:
-  version "4.18.1"
-  resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.18.1.tgz#18a606df5e76ca53b8a69f2d8eab256d69dda851"
-  integrity sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==
+  version "4.18.0"
+  resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.18.0.tgz#497f60f0c5308e4602cf41136339fbf87d5f5dda"
+  integrity sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==
   dependencies:
     "@types/estree" "1.0.5"
   optionalDependencies:
-    "@rollup/rollup-android-arm-eabi" "4.18.1"
-    "@rollup/rollup-android-arm64" "4.18.1"
-    "@rollup/rollup-darwin-arm64" "4.18.1"
-    "@rollup/rollup-darwin-x64" "4.18.1"
-    "@rollup/rollup-linux-arm-gnueabihf" "4.18.1"
-    "@rollup/rollup-linux-arm-musleabihf" "4.18.1"
-    "@rollup/rollup-linux-arm64-gnu" "4.18.1"
-    "@rollup/rollup-linux-arm64-musl" "4.18.1"
-    "@rollup/rollup-linux-powerpc64le-gnu" "4.18.1"
-    "@rollup/rollup-linux-riscv64-gnu" "4.18.1"
-    "@rollup/rollup-linux-s390x-gnu" "4.18.1"
-    "@rollup/rollup-linux-x64-gnu" "4.18.1"
-    "@rollup/rollup-linux-x64-musl" "4.18.1"
-    "@rollup/rollup-win32-arm64-msvc" "4.18.1"
-    "@rollup/rollup-win32-ia32-msvc" "4.18.1"
-    "@rollup/rollup-win32-x64-msvc" "4.18.1"
+    "@rollup/rollup-android-arm-eabi" "4.18.0"
+    "@rollup/rollup-android-arm64" "4.18.0"
+    "@rollup/rollup-darwin-arm64" "4.18.0"
+    "@rollup/rollup-darwin-x64" "4.18.0"
+    "@rollup/rollup-linux-arm-gnueabihf" "4.18.0"
+    "@rollup/rollup-linux-arm-musleabihf" "4.18.0"
+    "@rollup/rollup-linux-arm64-gnu" "4.18.0"
+    "@rollup/rollup-linux-arm64-musl" "4.18.0"
+    "@rollup/rollup-linux-powerpc64le-gnu" "4.18.0"
+    "@rollup/rollup-linux-riscv64-gnu" "4.18.0"
+    "@rollup/rollup-linux-s390x-gnu" "4.18.0"
+    "@rollup/rollup-linux-x64-gnu" "4.18.0"
+    "@rollup/rollup-linux-x64-musl" "4.18.0"
+    "@rollup/rollup-win32-arm64-msvc" "4.18.0"
+    "@rollup/rollup-win32-ia32-msvc" "4.18.0"
+    "@rollup/rollup-win32-x64-msvc" "4.18.0"
     fsevents "~2.3.2"
 
 run-parallel@^1.1.9:
@@ -7425,12 +7377,11 @@ ts-api-utils@^1.3.0:
   integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==
 
 ts-jest@^29.1.1:
-  version "29.2.2"
-  resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.2.2.tgz#0d2387bb04d39174b20a05172a968f258aedff4d"
-  integrity sha512-sSW7OooaKT34AAngP6k1VS669a0HdLxkQZnlC7T76sckGCokXFnvJ3yRlQZGRTAoV5K19HfSgCiSwWOSIfcYlg==
+  version "29.1.5"
+  resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.5.tgz#d6c0471cc78bffa2cb4664a0a6741ef36cfe8f69"
+  integrity sha512-UuClSYxM7byvvYfyWdFI+/2UxMmwNyJb0NPkZPQE2hew3RurV7l7zURgOHAd/1I1ZdPpe3GUsXNXAcN8TFKSIg==
   dependencies:
     bs-logger "0.x"
-    ejs "^3.0.0"
     fast-json-stable-stringify "2.x"
     jest-util "^29.0.0"
     json5 "^2.2.3"


Test patch:
diff --git a/src/test/calendar_test.test.tsx b/src/test/calendar_test.test.tsx
index c11857a7..0e55b3b8 100644
--- a/src/test/calendar_test.test.tsx
+++ b/src/test/calendar_test.test.tsx
@@ -2051,9 +2051,7 @@ describe("Calendar", () => {
     it("calls onClickOutside prop when handles click outside", () => {
       const { instance } = renderCalendar();
       act(() => {
-        instance.handleClickOutside(
-          "__event__" as unknown as React.MouseEvent<HTMLElement>,
-        );
+        instance.handleClickOutside("__event__" as unknown as MouseEvent);
       });
 
       expect(clickOutsideSpy).toHaveBeenCalledWith("__event__");
@@ -2185,7 +2183,7 @@ describe("Calendar", () => {
       expect(instance!.input).not.toBeFalsy();
       const dateInput = instance!.input!;
       fireEvent.focus(dateInput);
-      const calendar = instance!.calendar?.getInstance().containerRef.current;
+      const calendar = instance!.calendar?.containerRef.current;
       const navigation = calendar?.querySelector(
         ".react-datepicker__navigation--next",
       );
@@ -2213,7 +2211,7 @@ describe("Calendar", () => {
       expect(instance!.input).not.toBeFalsy();
       const dateInput = instance!.input!;
       fireEvent.focus(dateInput);
-      const calendar = instance!.calendar?.getInstance().containerRef.current;
+      const calendar = instance!.calendar?.containerRef.current;
       expect(calendar).not.toBeFalsy();
       const navigation = calendar!.querySelector(
         ".react-datepicker__navigation--previous",
@@ -2385,7 +2383,7 @@ describe("Calendar", () => {
       fireEvent.focus(dateInput);
 
       expect((instance as DatePicker | null)?.calendar).not.toBeFalsy();
-      const calendar = instance!.calendar!.getInstance().containerRef.current;
+      const calendar = instance!.calendar!.containerRef.current;
       const yearDropdown = calendar?.querySelector(
         ".react-datepicker__year-read-view",
       );
@@ -2406,9 +2404,9 @@ describe("Calendar", () => {
         expect((instance as DatePicker | null)?.calendar).not.toBeFalsy();
         expect(ariaLiveMessage).toBe(
           `${getMonthInLocale(
-            getMonth(instance!.calendar!.getInstance().state.date),
+            getMonth(instance!.calendar!.state.date),
             instance!.props.locale,
-          )} ${getYear(instance!.calendar!.getInstance().state.date)}`,
+          )} ${getYear(instance!.calendar!.state.date)}`,
         );
       });
     });
diff --git a/src/test/datepicker_test.test.tsx b/src/test/datepicker_test.test.tsx
index e92e4a4a..d395e82b 100644
--- a/src/test/datepicker_test.test.tsx
+++ b/src/test/datepicker_test.test.tsx
@@ -524,9 +524,9 @@ describe("DatePicker", () => {
     expect(anyOtherDay).toBeTruthy();
     fireEvent.click(anyOtherDay!); // will update the preSelection to next or previous day
 
-    const todayBtn = instance!.calendar
-      ?.getInstance()
-      .containerRef.current?.querySelector(".react-datepicker__today-button");
+    const todayBtn = instance!.calendar?.containerRef.current?.querySelector(
+      ".react-datepicker__today-button",
+    );
     expect(anyOtherDay).toBeTruthy();
     fireEvent.click(todayBtn!); // will update the preSelection
 
@@ -1014,9 +1014,9 @@ describe("DatePicker", () => {
     ).not.toBeNull();
     expect(instance!.calendar).toBeDefined();
 
-    const header = instance!.calendar
-      ?.getInstance()
-      .containerRef.current?.querySelector(".react-datepicker__current-month");
+    const header = instance!.calendar?.containerRef.current?.querySelector(
+      ".react-datepicker__current-month",
+    );
 
     expect(header).toBeTruthy();
     fireEvent.click(header!);
@@ -2289,10 +2289,42 @@ describe("DatePicker", () => {
     act(() => {
       instance!.handleCalendarClickOutside({
         preventDefault: jest.fn(),
-      } as unknown as React.MouseEvent<HTMLElement, MouseEvent>);
+      } as unknown as MouseEvent);
     });
     expect(openSpy).toHaveBeenCalledWith(false);
   });
+
+  it("should close date picker on outside click", () => {
+    const onClickOutsideSpy = jest.fn();
+    const { container } = render(
+      <div>
+        <span className="testText">test text</span>
+        <DatePicker onClickOutside={onClickOutsideSpy} />
+      </div>,
+    );
+    expect(container.querySelector(".react-datepicker")).toBeNull();
+    fireEvent.focus(container.querySelector("input") ?? new HTMLElement());
+    expect(container.querySelector(".react-datepicker")).not.toBeNull();
+    fireEvent.mouseDown(
+      container.querySelector(".testText") ?? new HTMLElement(),
+    );
+    expect(container.querySelector(".react-datepicker")).toBeNull();
+    expect(onClickOutsideSpy).toHaveBeenCalledTimes(1);
+  });
+
+  it("should not close date picker on input click", () => {
+    const onClickOutsideSpy = jest.fn();
+    const { container } = render(
+      <DatePicker onClickOutside={onClickOutsideSpy} />,
+    );
+    expect(container.querySelector(".react-datepicker")).toBeNull();
+    fireEvent.focus(container.querySelector("input") ?? new HTMLElement());
+    expect(container.querySelector(".react-datepicker")).not.toBeNull();
+    fireEvent.mouseDown(container.querySelector("input") ?? new HTMLElement());
+    expect(container.querySelector(".react-datepicker")).not.toBeNull();
+    expect(onClickOutsideSpy).not.toHaveBeenCalled();
+  });
+
   it("should default to the currently selected date", () => {
     let instance: DatePicker | null = null;
     render(
@@ -3295,11 +3327,9 @@ describe("DatePicker", () => {
       expect(instance!.input).toBeTruthy();
       fireEvent.click(instance!.input!);
       const headers =
-        instance!.calendar
-          ?.getInstance()
-          .containerRef.current?.querySelectorAll(
-            ".react-datepicker__header",
-          ) ?? [];
+        instance!.calendar?.containerRef.current?.querySelectorAll(
+          ".react-datepicker__header",
+        ) ?? [];
       expect(headers).toHaveLength(2);
       expect(headers[0]!.textContent).toBe("2023");
       expect(headers[1]!.textContent).toBe("2024");
@@ -3318,11 +3348,9 @@ describe("DatePicker", () => {
       expect(instance!.input).toBeTruthy();
       fireEvent.click(instance!.input!);
       const headersMore =
-        instance!.calendar
-          ?.getInstance()
-          .containerRef.current?.querySelectorAll(
-            ".react-datepicker__header",
-          ) ?? [];
+        instance!.calendar?.containerRef.current?.querySelectorAll(
+          ".react-datepicker__header",
+        ) ?? [];
       expect(headersMore).toHaveLength(4);
       expect(headersMore[0]!.textContent).toBe("2023");
       expect(headersMore[1]!.textContent).toBe("2024");
@@ -3351,11 +3379,9 @@ describe("DatePicker", () => {
       expect(instance!.input).toBeTruthy();
       fireEvent.click(instance!.input!);
       const headers =
-        instance!.calendar
-          ?.getInstance()
-          .containerRef.current?.querySelectorAll(
-            ".react-datepicker__header",
-          ) ?? [];
+        instance!.calendar?.containerRef.current?.querySelectorAll(
+          ".react-datepicker__header",
+        ) ?? [];
       expect(headers).toHaveLength(2);
       expect(headers[0]!.textContent).toBe("2023");
       expect(headers[1]!.textContent).toBe("2024");
@@ -3374,11 +3400,9 @@ describe("DatePicker", () => {
       expect(instance!.input).toBeTruthy();
       fireEvent.click(instance!.input!);
       const headersMore =
-        instance!.calendar
-          ?.getInstance()
-          .containerRef.current?.querySelectorAll(
-            ".react-datepicker__header",
-          ) ?? [];
+        instance!.calendar?.containerRef.current?.querySelectorAll(
+          ".react-datepicker__header",
+        ) ?? [];
       expect(headersMore).toHaveLength(4);
       expect(headersMore[0]!.textContent).toBe("2023");
       expect(headersMore[1]!.textContent).toBe("2024");
diff --git a/src/test/min_time_test.test.tsx b/src/test/min_time_test.test.tsx
index 65456b15..c73051bd 100644
--- a/src/test/min_time_test.test.tsx
+++ b/src/test/min_time_test.test.tsx
@@ -5,11 +5,15 @@ import DatePicker from "../index";
 
 import type { DatePickerProps } from "../index";
 
+// see https://github.com/microsoft/TypeScript/issues/31501
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+type OmitUnion<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
+
 const DatePickerWithState = (
   props: Partial<
     Pick<DatePickerProps, "open" | "selected" | "showTimeSelect" | "dateFormat">
   > &
-    Omit<
+    OmitUnion<
       DatePickerProps,
       | "open"
       | "selected"
diff --git a/src/test/month_dropdown_test.test.tsx b/src/test/month_dropdown_test.test.tsx
index e1c1ce5c..a6344719 100644
--- a/src/test/month_dropdown_test.test.tsx
+++ b/src/test/month_dropdown_test.test.tsx
@@ -3,7 +3,6 @@ import { el } from "date-fns/locale/el";
 import { ru } from "date-fns/locale/ru";
 import { zhCN } from "date-fns/locale/zh-CN";
 import React from "react";
-import onClickOutside from "react-onclickoutside";
 
 import { getMonthInLocale, registerLocale } from "../date_utils";
 import MonthDropdown from "../month_dropdown";
@@ -124,9 +123,8 @@ describe("MonthDropdown", () => {
       const monthNames = range(0, 12).map((M) => getMonthInLocale(M));
 
       const onCancelSpy = jest.fn();
-      const WrappedMonthDropdownOptions = onClickOutside(MonthDropdownOptions);
       render(
-        <WrappedMonthDropdownOptions
+        <MonthDropdownOptions
           onCancel={onCancelSpy}
           onChange={onCancelSpy}
           month={11}
@@ -135,7 +133,7 @@ describe("MonthDropdown", () => {
       );
       fireEvent.mouseDown(document.body);
       fireEvent.touchStart(document.body);
-      expect(onCancelSpy).toHaveBeenCalledTimes(2);
+      expect(onCancelSpy).toHaveBeenCalledTimes(1);
     });
 
     it("does not call the supplied onChange function when the same month is clicked", () => {
diff --git a/src/test/month_year_dropdown_test.test.tsx b/src/test/month_year_dropdown_test.test.tsx
index 0a8e226e..916e12d9 100644
--- a/src/test/month_year_dropdown_test.test.tsx
+++ b/src/test/month_year_dropdown_test.test.tsx
@@ -1,7 +1,6 @@
 import { render, fireEvent } from "@testing-library/react";
 import { fi } from "date-fns/locale/fi";
 import React from "react";
-import onClickOutside from "react-onclickoutside";
 
 import {
   newDate,
@@ -116,11 +115,8 @@ describe("MonthYearDropdown", () => {
       const dateFormatCalendar = "LLLL yyyy";
 
       const onCancelSpy = jest.fn();
-      const WrappedMonthYearDropdownOptions = onClickOutside(
-        MonthYearDropdownOptions,
-      );
       render(
-        <WrappedMonthYearDropdownOptions
+        <MonthYearDropdownOptions
           onCancel={onCancelSpy}
           onChange={jest.fn()}
           dateFormat={dateFormatCalendar}
@@ -131,7 +127,7 @@ describe("MonthYearDropdown", () => {
       );
       fireEvent.mouseDown(document.body);
       fireEvent.touchStart(document.body);
-      expect(onCancelSpy).toHaveBeenCalledTimes(2);
+      expect(onCancelSpy).toHaveBeenCalledTimes(1);
     });
 
     it("does not call the supplied onChange function when the same month year is clicked", () => {
diff --git a/src/test/multiple_selected_dates.test.tsx b/src/test/multiple_selected_dates.test.tsx
index 1a210544..63f430d7 100644
--- a/src/test/multiple_selected_dates.test.tsx
+++ b/src/test/multiple_selected_dates.test.tsx
@@ -5,6 +5,10 @@ import DatePicker from "../";
 
 import type { DatePickerProps } from "../index";
 
+// see https://github.com/microsoft/TypeScript/issues/31501
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+type OmitUnion<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
+
 describe("Multiple Dates Selected", function () {
   function getDatePicker(
     extraProps: Partial<
@@ -16,7 +20,7 @@ describe("Multiple Dates Selected", function () {
         | "onSelect"
       >
     > &
-      Omit<
+      OmitUnion<
         DatePickerProps,
         | "selectsMultiple"
         | "onChange"
diff --git a/src/test/year_dropdown_options_test.test.tsx b/src/test/year_dropdown_options_test.test.tsx
index 29431425..b9ce438f 100644
--- a/src/test/year_dropdown_options_test.test.tsx
+++ b/src/test/year_dropdown_options_test.test.tsx
@@ -1,6 +1,5 @@
 import { render, fireEvent } from "@testing-library/react";
 import React from "react";
-import onClickOutside from "react-onclickoutside";
 
 import { addYears, getYear, newDate, subYears } from "../date_utils";
 import YearDropdownOptions from "../year_dropdown_options";
@@ -128,9 +127,8 @@ describe("YearDropdownOptions", () => {
   });
 
   it("calls the supplied onCancel function on handleClickOutside", () => {
-    const WrappedYearDropdownOptions = onClickOutside(YearDropdownOptions);
     render(
-      <WrappedYearDropdownOptions
+      <YearDropdownOptions
         year={2015}
         onChange={mockHandleChange}
         onCancel={onCancelSpy}