diff --git a/index.html b/index.html index 8b32460..bd826eb 100644 --- a/index.html +++ b/index.html @@ -99,15 +99,7 @@

range

date

- + = 0 && diff < months; }; - // page change -> update focused date + // page change -> clamp focused date to visible range useEffect(() => { - if (contains(focusedDate)) { - return; + const focusedMonth = focusedDate.toPlainYearMonth(); + + // Clamp the focused month to the page range + let clampedMonth = focusedMonth; + const startDiff = diffInMonths(focusedMonth, page.start); + const endDiff = diffInMonths(focusedMonth, page.end); + + if (startDiff > 0) { + clampedMonth = page.start; + } else if (endDiff < 0) { + clampedMonth = page.end; } - const diff = diffInMonths(focusedDate.toPlainYearMonth(), page.start); - goto(focusedDate.add({ months: diff })); - }, [page.start]); + // If clamping changed the month, update the focused date + if (!focusedMonth.equals(clampedMonth)) { + const monthsToAdd = diffInMonths(focusedMonth, clampedMonth); + goto(focusedDate.add({ months: monthsToAdd })); + } + }, [page]); // focused date change -> update page useEffect(() => { diff --git a/src/calendar-date/calendar-date.test.tsx b/src/calendar-date/calendar-date.test.tsx index a6fcb85..3a31f27 100644 --- a/src/calendar-date/calendar-date.test.tsx +++ b/src/calendar-date/calendar-date.test.tsx @@ -594,6 +594,47 @@ describe("CalendarDate", () => { const target = spy.last[0].target as InstanceType; expect(target.value).toBe("2021-12-31"); }); + + it("clamps focused date to visible range when navigating next", async () => { + const spy = createSpy<(e: CustomEvent) => void>(); + const calendar = await mount( + + + + + ); + + // Starting at Jan-Feb, focused on Feb 15 + // Click next → page Feb-Mar, Feb 15 is still in range, no change + await getNextPageButton(calendar).click(); + expect(spy.count).toBe(1); + expect(spy.last[0].detail).toEqual(new Date("2022-02-15")); + + // Click next → page Mar-Apr, Feb 15 is before range, clamps to Mar 15 + await getNextPageButton(calendar).click(); + expect(spy.count).toBe(2); + expect(spy.last[0].detail).toEqual(new Date("2022-03-15")); + }); + + it("clamps focused date to visible range when navigating previous", async () => { + const spy = createSpy<(e: CustomEvent) => void>(); + const calendar = await mount( + + + + + ); + + // Starting at Mar-Apr, focused on Mar 15 + // Click previous → page Feb-Mar, Mar 15 is in range, no focusday + await getPrevPageButton(calendar).click(); + expect(spy.count).toBe(0); + + // Click previous → page Jan-Feb, Feb 15 is after range, clamps to Feb 15 + await getPrevPageButton(calendar).click(); + expect(spy.count).toBe(1); + expect(spy.last[0].detail).toEqual(new Date("2022-02-15")); + }); }); describe("focus management", () => {