From 1856d20a47dc742eea5dccf88f5d0de65d414ea8 Mon Sep 17 00:00:00 2001 From: ajnart Date: Tue, 21 Jul 2026 16:16:07 +0200 Subject: [PATCH] fix(widgets): wrap calendar days in HoverCard.Group for shared delays Uses HoverCard.Group with openDelay={350} and closeDelay={200} so all calendar day hover cards share synchronized delays. The closeDelay gives users time to move from the day cell to the dropdown where interactive link buttons live (per Mantine's interactive elements pattern). --- .../widgets/src/calendar/calender-day.tsx | 1 - packages/widgets/src/calendar/component.tsx | 158 +++++++++--------- 2 files changed, 80 insertions(+), 79 deletions(-) diff --git a/packages/widgets/src/calendar/calender-day.tsx b/packages/widgets/src/calendar/calender-day.tsx index 269cec3d2..dc3f902b8 100644 --- a/packages/widgets/src/calendar/calender-day.tsx +++ b/packages/widgets/src/calendar/calender-day.tsx @@ -35,7 +35,6 @@ export const CalendarDay = ({ date, events, disabled, rootHeight, rootWidth }: C radius="lg" shadow="sm" transitionProps={{ transition: "pop" }} - openDelay={350} disabled={disabled} > diff --git a/packages/widgets/src/calendar/component.tsx b/packages/widgets/src/calendar/component.tsx index 6d309ce42..6bbe91a77 100644 --- a/packages/widgets/src/calendar/component.tsx +++ b/packages/widgets/src/calendar/component.tsx @@ -2,7 +2,7 @@ import { useMemo, useState } from "react"; import { useParams } from "next/navigation"; -import { useMantineTheme } from "@mantine/core"; +import { useMantineTheme, HoverCard } from "@mantine/core"; import { Calendar } from "@mantine/dates"; import { useElementSize } from "@mantine/hooks"; import dayjs from "dayjs"; @@ -67,84 +67,86 @@ const CalendarBase = ({ isEditMode, events, month, setMonth, options }: Calendar const normalizedEvents = useMemo(() => splitEvents(events), [events]); return ( - setMonth(new Date(month))} - onNextMonth={(month) => setMonth(new Date(month))} - highlightToday - locale={locale} - hideWeekdays={false} - date={month} - maxLevel="month" - firstDayOfWeek={firstDayOfWeek} - static={isEditMode} - className={classes.calendar} - w="100%" - h="100%" - ref={ref} - styles={{ - calendarHeaderControl: { - pointerEvents: isEditMode ? "none" : undefined, - borderRadius: "md", - height: isSmall ? "1.5rem" : undefined, - width: isSmall ? "1.5rem" : undefined, - }, - calendarHeaderLevel: { - pointerEvents: "none", - fontSize: isSmall ? "0.75rem" : undefined, - height: "100%", - }, - levelsGroup: { - height: "100%", - padding: "md", - }, - calendarHeader: { - maxWidth: "unset", - marginBottom: 0, - }, - monthCell: { - textAlign: "center", - position: "relative", - }, - day: { - borderRadius: actualItemRadius, - width: "100%", - height: "100%", - position: "absolute", - top: 0, - left: 0, - bottom: 0, - right: 0, - }, - month: { - height: "100%", - }, - weekday: { - padding: 0, - }, - weekdaysRow: { - height: 22, - }, - }} - renderDay={(tileDate) => { - const eventsForDate = normalizedEvents - .filter((event) => dayjs(event.startDate).isSame(tileDate, "day")) - .filter( - (event) => event.metadata?.type !== "radarr" || options.releaseType.includes(event.metadata.releaseType), - ) - .toSorted((eventA, eventB) => eventA.startDate.getTime() - eventB.startDate.getTime()); + + setMonth(new Date(month))} + onNextMonth={(month) => setMonth(new Date(month))} + highlightToday + locale={locale} + hideWeekdays={false} + date={month} + maxLevel="month" + firstDayOfWeek={firstDayOfWeek} + static={isEditMode} + className={classes.calendar} + w="100%" + h="100%" + ref={ref} + styles={{ + calendarHeaderControl: { + pointerEvents: isEditMode ? "none" : undefined, + borderRadius: "md", + height: isSmall ? "1.5rem" : undefined, + width: isSmall ? "1.5rem" : undefined, + }, + calendarHeaderLevel: { + pointerEvents: "none", + fontSize: isSmall ? "0.75rem" : undefined, + height: "100%", + }, + levelsGroup: { + height: "100%", + padding: "md", + }, + calendarHeader: { + maxWidth: "unset", + marginBottom: 0, + }, + monthCell: { + textAlign: "center", + position: "relative", + }, + day: { + borderRadius: actualItemRadius, + width: "100%", + height: "100%", + position: "absolute", + top: 0, + left: 0, + bottom: 0, + right: 0, + }, + month: { + height: "100%", + }, + weekday: { + padding: 0, + }, + weekdaysRow: { + height: 22, + }, + }} + renderDay={(tileDate) => { + const eventsForDate = normalizedEvents + .filter((event) => dayjs(event.startDate).isSame(tileDate, "day")) + .filter( + (event) => event.metadata?.type !== "radarr" || options.releaseType.includes(event.metadata.releaseType), + ) + .toSorted((eventA, eventB) => eventA.startDate.getTime() - eventB.startDate.getTime()); - return ( - - ); - }} - /> + return ( + + ); + }} + /> + ); };