From 68337b12a0f02b6e197ef56697698a9e271393fd Mon Sep 17 00:00:00 2001 From: Kyle Pope Date: Tue, 17 Mar 2026 20:14:00 +0800 Subject: [PATCH] Fix: clear mini-cal selection on Today click even when month unchanged MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit datesSet fires but currentDate stays the same value when already on the current month, so the useEffect didn't re-run. Added navKey counter that increments on every datesSet call — MiniCalendar watches it in a separate useEffect to reliably clear selectedDate. Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/components/calendar/CalendarPage.tsx | 7 +++++-- frontend/src/components/calendar/CalendarSidebar.tsx | 4 +++- frontend/src/components/calendar/MiniCalendar.tsx | 12 +++++++++--- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/calendar/CalendarPage.tsx b/frontend/src/components/calendar/CalendarPage.tsx index 00d0ade..fbf4a9f 100644 --- a/frontend/src/components/calendar/CalendarPage.tsx +++ b/frontend/src/components/calendar/CalendarPage.tsx @@ -54,6 +54,7 @@ export default function CalendarPage() { const firstDayOfWeek = settings?.first_day_of_week ?? 0; const { data: calendars = [], sharedData, allCalendarIds } = useCalendars({ pollingEnabled: true }); const [currentDate, setCurrentDate] = useState(() => format(new Date(), 'yyyy-MM-dd')); + const [navKey, setNavKey] = useState(0); const [visibleSharedIds, setVisibleSharedIds] = useState>(new Set()); const calendarContainerRef = useRef(null); @@ -521,6 +522,8 @@ export default function CalendarPage() { ); // Track current date anchor for mini calendar sync setCurrentDate(format(arg.view.currentStart, 'yyyy-MM-dd')); + // Increment nav key so mini calendar clears selection even when month doesn't change + setNavKey((k) => k + 1); }; const navigatePrev = () => calendarRef.current?.getApi().prev(); @@ -599,7 +602,7 @@ export default function CalendarPage() { return (
- +
setMobileSidebarOpen(false)} /> - { setMobileSidebarOpen(false); handleUseTemplate(tmpl); }} onSharedVisibilityChange={setVisibleSharedIds} width={288} onDateClick={handleMiniCalClick} currentDate={currentDate} firstDayOfWeek={firstDayOfWeek} /> + { setMobileSidebarOpen(false); handleUseTemplate(tmpl); }} onSharedVisibilityChange={setVisibleSharedIds} width={288} onDateClick={handleMiniCalClick} currentDate={currentDate} firstDayOfWeek={firstDayOfWeek} navKey={navKey} /> )} diff --git a/frontend/src/components/calendar/CalendarSidebar.tsx b/frontend/src/components/calendar/CalendarSidebar.tsx index 7cac30a..a09c2e5 100644 --- a/frontend/src/components/calendar/CalendarSidebar.tsx +++ b/frontend/src/components/calendar/CalendarSidebar.tsx @@ -19,9 +19,10 @@ interface CalendarSidebarProps { onDateClick?: (dateStr: string) => void; currentDate?: string; firstDayOfWeek?: number; + navKey?: number; } -const CalendarSidebar = forwardRef(function CalendarSidebar({ onUseTemplate, onSharedVisibilityChange, width, onDateClick, currentDate, firstDayOfWeek }, ref) { +const CalendarSidebar = forwardRef(function CalendarSidebar({ onUseTemplate, onSharedVisibilityChange, width, onDateClick, currentDate, firstDayOfWeek, navKey }, ref) { const queryClient = useQueryClient(); const { data: calendars = [], sharedData: sharedCalendars = [] } = useCalendars(); const [showForm, setShowForm] = useState(false); @@ -108,6 +109,7 @@ const CalendarSidebar = forwardRef(functio onDateClick={onDateClick} currentDate={currentDate} firstDayOfWeek={firstDayOfWeek} + navKey={navKey} />
)} diff --git a/frontend/src/components/calendar/MiniCalendar.tsx b/frontend/src/components/calendar/MiniCalendar.tsx index ca04921..369793c 100644 --- a/frontend/src/components/calendar/MiniCalendar.tsx +++ b/frontend/src/components/calendar/MiniCalendar.tsx @@ -11,6 +11,7 @@ interface MiniCalendarProps { onDateClick: (dateStr: string) => void; currentDate?: string; firstDayOfWeek?: number; + navKey?: number; } const DAY_LABELS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']; @@ -31,6 +32,7 @@ const MiniCalendar = memo(function MiniCalendar({ onDateClick, currentDate, firstDayOfWeek = 0, + navKey, }: MiniCalendarProps) { const REF_DATE = useMemo(() => new Date(), []); @@ -44,17 +46,21 @@ const MiniCalendar = memo(function MiniCalendar({ ); const [selectedDate, setSelectedDate] = useState(null); - // Sync displayed month when main calendar navigates (toolbar prev/next/today) - // Also clear selected date — avoids stale highlight after "Today" click + // Sync displayed month when main calendar navigates across months useEffect(() => { if (!currentDate) return; const incoming = startOfMonth(parseDate(currentDate)); setDisplayedMonth((prev) => prev.getTime() === incoming.getTime() ? prev : incoming ); - setSelectedDate(null); }, [currentDate, parseDate]); + // Clear selection on any toolbar navigation (today/prev/next) + // navKey increments on every datesSet, even when the month doesn't change + useEffect(() => { + setSelectedDate(null); + }, [navKey]); + const days = useMemo( () => buildGrid(displayedMonth, firstDayOfWeek), [displayedMonth, firstDayOfWeek]