diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..c337c6161 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +Use yarn instead of npm for running commands diff --git a/src/calendar.tsx b/src/calendar.tsx index 6194b0ffe..7e0d8f260 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 ccd6ad996..003e02005 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 31e8890c6..45d0fc5a9 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,45 @@ 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 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 apply the default outsideClickIgnoreClass when prop is falsy", () => { + 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", () => {