diff --git a/src/index.tsx b/src/index.tsx index 0e845da7b..78cc24bcd 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -716,7 +716,17 @@ export class DatePicker extends Component { monthSelectedIn?: number, ) => { if (this.props.readOnly) return; - if (this.props.shouldCloseOnSelect && !this.props.showTimeSelect) { + + const { selectsRange, startDate, endDate, swapRange } = this.props; + const isDateSelectionComplete = + !selectsRange || + (startDate && !endDate && (swapRange || !isDateBefore(date, startDate))); + + if ( + this.props.shouldCloseOnSelect && + !this.props.showTimeSelect && + isDateSelectionComplete + ) { // Preventing onFocus event to fix issue // https://github.com/Hacker0x01/react-datepicker/issues/628 this.sendFocusBackToInput(); @@ -730,20 +740,8 @@ export class DatePicker extends Component { } if (!this.props.shouldCloseOnSelect || this.props.showTimeSelect) { this.setPreSelection(date); - } else if (!this.props.inline) { - if (!this.props.selectsRange) { - this.setOpen(false); - } - - const { startDate, endDate } = this.props; - - if ( - startDate && - !endDate && - (this.props.swapRange || !isDateBefore(date, startDate)) - ) { - this.setOpen(false); - } + } else if (isDateSelectionComplete) { + this.setOpen(false); } }; diff --git a/src/test/datepicker_test.test.tsx b/src/test/datepicker_test.test.tsx index 790b19c95..d44a3607b 100644 --- a/src/test/datepicker_test.test.tsx +++ b/src/test/datepicker_test.test.tsx @@ -4642,4 +4642,179 @@ describe("DatePicker", () => { ); }); }); + + describe("Refocus Input", () => { + it("should refocus the date input when a date is selected", async () => { + const selectedDate = newDate("2025-11-01"); + const onChangeSpy = jest.fn(); + const { container } = render( + , + ); + + const input = safeQuerySelector(container, "input"); + fireEvent.focus(input); + + expect(container.querySelector(".react-datepicker")).toBeTruthy(); + + const newSelectedDateEl = safeQuerySelector( + container, + ".react-datepicker__day--002", + ); + fireEvent.click(newSelectedDateEl); + + await waitFor(() => { + expect(document.activeElement).not.toBe(newSelectedDateEl); + expect(document.activeElement).toBe(input); + }); + }); + + describe("Date Range", () => { + it("should not refocus the input when the endDate is not selected in the Date Range", async () => { + const selectedDate = newDate("2025-11-01"); + let startDate, endDate; + const onChangeSpy = jest.fn((dates) => { + [startDate, endDate] = dates; + }); + + const { container } = render( + , + ); + const input = safeQuerySelector(container, "input"); + fireEvent.focus(input); + + expect(container.querySelector(".react-datepicker")).toBeTruthy(); + const newStartDateEl = safeQuerySelector( + container, + ".react-datepicker__day--002", + ); + fireEvent.click(newStartDateEl); + + expect(onChangeSpy).toHaveBeenCalledTimes(1); + + await waitFor(() => { + expect(document.activeElement).not.toBe(input); + expect(document.activeElement).toBe(newStartDateEl); + }); + }); + + it("should refocus the input when the endDate is selected in the Date Range (if the end date is after the start date)", async () => { + const selectedDate = newDate("2025-11-01"); + let startDate = selectedDate, + endDate; + const onChangeSpy = jest.fn((dates) => { + [startDate, endDate] = dates; + }); + + const { container } = render( + , + ); + const input = safeQuerySelector(container, "input"); + fireEvent.focus(input); + + expect(container.querySelector(".react-datepicker")).toBeTruthy(); + const endDateEl = safeQuerySelector( + container, + ".react-datepicker__day--005", + ); + fireEvent.click(endDateEl); + + expect(onChangeSpy).toHaveBeenCalledTimes(1); + + await waitFor(() => { + expect(document.activeElement).toBe(input); + }); + }); + + it("should not refocus the input when the selected endDate is before the startDate", async () => { + const selectedDate = newDate("2025-11-05"); + let startDate = selectedDate, + endDate; + const onChangeSpy = jest.fn((dates) => { + [startDate, endDate] = dates; + }); + + const { container } = render( + , + ); + const input = safeQuerySelector(container, "input"); + fireEvent.focus(input); + + expect(container.querySelector(".react-datepicker")).toBeTruthy(); + const endDateEl = safeQuerySelector( + container, + ".react-datepicker__day--002", + ); + fireEvent.click(endDateEl); + + expect(onChangeSpy).toHaveBeenCalledTimes(1); + + await waitFor(() => { + expect(document.activeElement).not.toBe(input); + expect(document.activeElement).toBe(endDateEl); + }); + }); + + it('should refocus the input when the selected endDate is before the startDate when the "swapRange" prop is set', async () => { + const selectedDate = newDate("2025-11-05"); + let startDate = selectedDate, + endDate; + const onChangeSpy = jest.fn((dates) => { + [startDate, endDate] = dates; + }); + + const { container } = render( + , + ); + const input = safeQuerySelector(container, "input"); + fireEvent.focus(input); + + expect(container.querySelector(".react-datepicker")).toBeTruthy(); + const endDateEl = safeQuerySelector( + container, + ".react-datepicker__day--002", + ); + fireEvent.click(endDateEl); + + expect(onChangeSpy).toHaveBeenCalledTimes(1); + + await waitFor(() => { + expect(document.activeElement).not.toBe(endDateEl); + expect(document.activeElement).toBe(input); + }); + }); + }); + }); });