From b1150b11e53a0cb1fa79d180bfc6f7fc34e50fc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20M=C3=A9riouma-Caron?= Date: Thu, 22 May 2025 14:14:24 -0400 Subject: [PATCH 1/2] feat: expose outsideClickIgnoreClass --- src/calendar.tsx | 4 ++++ src/index.tsx | 11 +++++------ src/test/datepicker_test.test.tsx | 23 +++++++++++++++-------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/calendar.tsx b/src/calendar.tsx index 6194b0ffe4..7e0d8f260d 100644 --- a/src/calendar.tsx +++ b/src/calendar.tsx @@ -80,6 +80,9 @@ const DROPDOWN_FOCUS_CLASSNAMES = [ "react-datepicker__month-year-select", ]; +export const OUTSIDE_CLICK_IGNORE_CLASS = + "react-datepicker-ignore-onclickoutside"; + const isDropdownSelect = (element: HTMLDivElement) => { const classNames = (element.className || "").split(/\s+/); return DROPDOWN_FOCUS_CLASSNAMES.some( @@ -221,6 +224,7 @@ export default class Calendar extends Component { return { monthsShown: 1, forceShowMonthNavigation: false, + outsideClickIgnoreClass: OUTSIDE_CLICK_IGNORE_CLASS, timeCaption: "Time", previousYearButtonLabel: "Previous Year", nextYearButtonLabel: "Next Year", diff --git a/src/index.tsx b/src/index.tsx index ccd6ad996a..003e02005c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,7 +1,7 @@ import { clsx } from "clsx"; import React, { Component, cloneElement } from "react"; -import Calendar from "./calendar"; +import Calendar, { OUTSIDE_CLICK_IGNORE_CLASS } from "./calendar"; import CalendarIcon from "./calendar_icon"; import { newDate, @@ -61,8 +61,6 @@ export { default as CalendarContainer } from "./calendar_container"; export { registerLocale, setDefaultLocale, getDefaultLocale }; -const outsideClickIgnoreClass = "react-datepicker-ignore-onclickoutside"; - export { ReactDatePickerCustomHeaderProps } from "./calendar"; // Compares dates year+month combinations @@ -112,7 +110,6 @@ export type DatePickerProps = OmitUnion< | "highlightDates" | "holidays" | "shouldFocusDayInline" - | "outsideClickIgnoreClass" | "monthSelectedIn" | "onDropdownFocus" | "onTimeChange" @@ -266,6 +263,7 @@ export default class DatePicker extends Component< dropdownMode: "scroll" as const, preventOpenOnFocus: false, monthsShown: 1, + outsideClickIgnoreClass: OUTSIDE_CLICK_IGNORE_CLASS, readOnly: false, withPortal: false, selectsDisabledDaysInRange: false, @@ -1236,7 +1234,7 @@ export default class DatePicker extends Component< onSelect={this.handleSelect} onClickOutside={this.handleCalendarClickOutside} holidays={getHolidaysMap(this.modifyHolidays())} - outsideClickIgnoreClass={outsideClickIgnoreClass} + outsideClickIgnoreClass={this.props.outsideClickIgnoreClass} onDropdownFocus={this.handleDropdownFocus} onTimeChange={this.handleTimeChange} className={this.props.calendarClassName} @@ -1325,7 +1323,8 @@ export default class DatePicker extends Component< renderDateInput = () => { const className = clsx(this.props.className, { - [outsideClickIgnoreClass]: this.state.open, + [this.props.outsideClickIgnoreClass || + DatePicker.defaultProps.outsideClickIgnoreClass]: this.state.open, }); const customInput = this.props.customInput || ; diff --git a/src/test/datepicker_test.test.tsx b/src/test/datepicker_test.test.tsx index 31e8890c6b..6d88351ac3 100644 --- a/src/test/datepicker_test.test.tsx +++ b/src/test/datepicker_test.test.tsx @@ -2,6 +2,7 @@ import { render, act, waitFor, fireEvent } from "@testing-library/react"; import { userEvent } from "@testing-library/user-event"; import { enUS, enGB } from "date-fns/locale"; import React, { useState } from "react"; +import { OUTSIDE_CLICK_IGNORE_CLASS } from "../calendar"; import { KeyType, @@ -687,21 +688,27 @@ describe("DatePicker", () => { }); }); - it("should not apply the react-datepicker-ignore-onclickoutside class to the date input when closed", () => { + it("should not apply the default outsideClickIgnoreClass class to the date input when closed", () => { const { container } = render(); const input = safeQuerySelector(container, "input"); - expect( - input?.classList.contains("react-datepicker-ignore-onclickoutside"), - ).toBeFalsy(); + expect(input?.classList.contains(OUTSIDE_CLICK_IGNORE_CLASS)).toBe(false); }); - it("should apply the react-datepicker-ignore-onclickoutside class to date input when open", () => { + it("should apply the default outsideClickIgnoreClass class to date input when open", () => { const { container } = render(); const input = safeQuerySelector(container, "input"); fireEvent.focus(input); - expect( - input?.classList.contains("react-datepicker-ignore-onclickoutside"), - ).toBeTruthy(); + expect(input?.classList.contains(OUTSIDE_CLICK_IGNORE_CLASS)).toBe(true); + }); + + it("should apply the outsideClickIgnoreClass class to date input when open", () => { + const outsideClickIgnoreClass = "ignore-onclickoutside"; + const { container } = render( + , + ); + const input = safeQuerySelector(container, "input"); + fireEvent.focus(input); + expect(input?.classList.contains(outsideClickIgnoreClass)).toBe(true); }); it("should toggle the open status of calendar on click of the icon when toggleCalendarOnIconClick is set to true", () => { From f1c6da0ff889d36dea7fa99c5051f000cea22e4a Mon Sep 17 00:00:00 2001 From: Martijn Russchen Date: Sun, 25 May 2025 14:38:09 +0200 Subject: [PATCH 2/2] test: add coverage for outsideClickIgnoreClass undefined fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds test case to cover the scenario where outsideClickIgnoreClass is explicitly set to undefined, ensuring the fallback to default props is properly tested and improves test coverage for line 1327 in index.tsx. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/test/datepicker_test.test.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/datepicker_test.test.tsx b/src/test/datepicker_test.test.tsx index 6d88351ac3..9efe68b1b9 100644 --- a/src/test/datepicker_test.test.tsx +++ b/src/test/datepicker_test.test.tsx @@ -711,6 +711,15 @@ describe("DatePicker", () => { expect(input?.classList.contains(outsideClickIgnoreClass)).toBe(true); }); + it("should apply the default outsideClickIgnoreClass when prop is undefined", () => { + const { container } = render( + , + ); + const input = safeQuerySelector(container, "input"); + fireEvent.focus(input); + expect(input?.classList.contains(OUTSIDE_CLICK_IGNORE_CLASS)).toBe(true); + }); + it("should toggle the open status of calendar on click of the icon when toggleCalendarOnIconClick is set to true", () => { const { container } = render(