Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,7 @@ <h2>range</h2>
</calendar-range>

<h2>date</h2>
<calendar-date
id="date"
value="2020-04-01"
min="2019-11-01"
max="2025-03-20"
months="2"
show-outside-days
page-by="single"
>
<calendar-date id="date" value="2022-03-15" months="2" page-by="single">
<svg
aria-label="Previous"
slot="previous"
Expand Down
24 changes: 18 additions & 6 deletions src/calendar-base/useCalendarBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,27 @@ function usePagination({
return diff >= 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(() => {
Expand Down
41 changes: 41 additions & 0 deletions src/calendar-date/calendar-date.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,47 @@ describe("CalendarDate", () => {
const target = spy.last[0].target as InstanceType<typeof CalendarDate>;
expect(target.value).toBe("2021-12-31");
});

it("clamps focused date to visible range when navigating next", async () => {
const spy = createSpy<(e: CustomEvent<Date>) => void>();
const calendar = await mount(
<Fixture value="2022-01-15" months={2} pageBy="single" onfocusday={spy}>
<CalendarMonth />
<CalendarMonth offset={1} />
</Fixture>
);

// 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<Date>) => void>();
const calendar = await mount(
<Fixture value="2022-03-15" months={2} pageBy="single" onfocusday={spy}>
<CalendarMonth />
<CalendarMonth offset={1} />
</Fixture>
);

// 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", () => {
Expand Down