diff --git a/web/src/components/CalendarView/CalendarDayCell.tsx b/web/src/components/CalendarView/CalendarDayCell.tsx
index f62a5231..4881f0f5 100644
--- a/web/src/components/CalendarView/CalendarDayCell.tsx
+++ b/web/src/components/CalendarView/CalendarDayCell.tsx
@@ -4,6 +4,7 @@ import type { MemoTimeBasis } from "@/contexts/ViewContext";
import { cn } from "@/lib/utils";
import { useTranslate } from "@/utils/i18n";
import { CalendarLink } from "./CalendarLink";
+import { CALENDAR_FOCUS_CLASSES } from "./controls";
import type { CalendarDaySummary } from "./dayModel";
import { buildCalendarPath, getMonthOfDate } from "./paths";
@@ -38,7 +39,7 @@ const CORNER_CLASSES = { ss: "rounded-ss-lg", se: "rounded-se-lg", es: "rounded-
export const CalendarDayCell = memo(
({ day, summary, visibleRows, pending, timeBasis, tabIndex, isLastColumn, isLastRow, corner }: CalendarDayCellProps) => {
const t = useTranslate();
- const count = summary?.count ?? day.count;
+ const count = summary ? summary.memos.length : day.count;
const entries = summary?.entries ?? [];
// The "+N more" line takes a row of its own, so an overflowing day shows one fewer memo.
const overflows = count > visibleRows;
@@ -58,7 +59,7 @@ export const CalendarDayCell = memo(
!isLastColumn && "border-e",
!isLastRow && "border-b",
corner && CORNER_CLASSES[corner],
- "focus-visible:outline-2 focus-visible:outline-solid focus-visible:-outline-offset-2 focus-visible:outline-ring/60",
+ CALENDAR_FOCUS_CLASSES,
// The open day is the place you are, so it takes the fill the sidebar gives a current row.
day.isSelected ? "bg-accent" : day.isCurrentMonth ? "bg-card hover:bg-muted/40" : "bg-muted/25 hover:bg-muted/45",
)}
diff --git a/web/src/components/CalendarView/CalendarHeader.tsx b/web/src/components/CalendarView/CalendarHeader.tsx
index 67d3c3c6..90fa4193 100644
--- a/web/src/components/CalendarView/CalendarHeader.tsx
+++ b/web/src/components/CalendarView/CalendarHeader.tsx
@@ -1,9 +1,10 @@
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
-import { buttonVariants } from "@/components/ui/button";
+import { useLocation, useNavigate } from "react-router-dom";
import { addMonths } from "@/lib/calendar-utils";
import { cn } from "@/lib/utils";
import { useTranslate } from "@/utils/i18n";
import { CalendarLink } from "./CalendarLink";
+import { CALENDAR_CONTROL_ACTIVE_CLASSES, CALENDAR_ICON_CONTROL_CLASSES, CALENDAR_TEXT_CONTROL_CLASSES } from "./controls";
import { MonthPicker } from "./MonthPicker";
import { buildCalendarPath, getMonthOfDate } from "./paths";
@@ -12,28 +13,28 @@ export interface CalendarHeaderProps {
monthLabel: string;
/** `YYYY-MM-DD` */
today: string;
- /** `YYYY-MM-DD` of the open day, if any. */
- date?: string;
+ /** `YYYY-MM-DD` of the day being shown, whether the URL names it or the layout defaulted to it. */
+ activeDate?: string;
+ /** Whether the shown day can be dismissed: a panel or sheet can, the phone's inline list cannot. */
+ closable: boolean;
}
/**
- * Where "Today" goes: from another month it returns to this month; within this month it
- * toggles today's panel, so the button is also the quickest way to today's memos.
+ * Where "Today" goes: from another month it returns to this month; within this month it opens
+ * today, and where the day can be dismissed a second press closes it again. On phones a day is
+ * always shown, so Today simply keeps today selected and reads as pressed while it is.
*/
-export const getTodayPath = (month: string, date: string | undefined, today: string): string => {
+export const getTodayPath = (month: string, activeDate: string | undefined, today: string, closable: boolean): string => {
const currentMonth = getMonthOfDate(today);
if (month !== currentMonth) return buildCalendarPath(currentMonth);
- return date === today ? buildCalendarPath(currentMonth) : buildCalendarPath(currentMonth, today);
+ return closable && activeDate === today ? buildCalendarPath(currentMonth) : buildCalendarPath(currentMonth, today);
};
-const NAV_LINK_CLASSES = cn(
- buttonVariants({ variant: "ghost", size: "icon-sm" }),
- "size-7 rounded-md text-muted-foreground/70 no-underline hover:bg-muted/60 hover:text-foreground",
-);
-
-export const CalendarHeader = ({ month, monthLabel, today, date }: CalendarHeaderProps) => {
+export const CalendarHeader = ({ month, monthLabel, today, activeDate, closable }: CalendarHeaderProps) => {
const t = useTranslate();
- const todayOpen = date === today;
+ const navigate = useNavigate();
+ const { search } = useLocation();
+ const todayOpen = activeDate === today;
return (
// The title's text starts on the grid's text axis (border + cell padding); the month
@@ -41,23 +42,29 @@ export const CalendarHeader = ({ month, monthLabel, today, date }: CalendarHeade
{t("calendar.no-memos-in-month", { month: monthLabel })} @@ -135,7 +139,7 @@ export const CalendarView = ({ month, date }: CalendarViewProps) => { )} {activeDate && !md && (