diff --git a/apps/web/app/shared/ui/calendar.tsx b/apps/web/app/shared/ui/calendar.tsx index a7b6f4a..0a19a55 100644 --- a/apps/web/app/shared/ui/calendar.tsx +++ b/apps/web/app/shared/ui/calendar.tsx @@ -2,6 +2,8 @@ import * as React from "react"; import { DayPicker, getDefaultClassNames, + useDayPicker, + type CustomComponents, type DayButton, type Locale, } from "react-day-picker"; @@ -14,6 +16,74 @@ import { ChevronDownIcon, } from "lucide-react"; +/** + * The `components` overrides live out here rather than inline in `Calendar`'s + * render, which is where shadcn's generator puts them. + * + * An arrow function written inside the render body is a new component type on + * every pass, and DayPicker keys its subtree on these identities: re-rendering + * the calendar unmounts and remounts the whole grid rather than updating it. + * That is not only wasted work — `CalendarDayButton` holds a ref and an effect + * that focuses the day matching `modifiers.focused`, and a remount drops the + * focus it had just moved. The range picker re-renders on every click, so this + * ran on the path a keyboard user is actually using. + */ +const CalendarRoot: CustomComponents["Root"] = ({ + className, + rootRef, + ...props +}) => { + return ( +
+ ); +}; + +const CalendarChevron: CustomComponents["Chevron"] = ({ + className, + orientation, + ...props +}) => { + if (orientation === "left") { + return