diff --git a/src/Expense/ExpenseList.tsx b/src/Expense/ExpenseList.tsx index 93b00c2..801ca1f 100644 --- a/src/Expense/ExpenseList.tsx +++ b/src/Expense/ExpenseList.tsx @@ -8,6 +8,7 @@ import { } from "@mui/material"; import { alpha } from "@mui/material/styles"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; +import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; import { ListCellRenderer, CurrencyField, applyDisplayFormat, formatCurrency } from "../../react-openapi"; import type { ExpenseItem, ExpenseFieldConfigs } from "./types"; import { isExpense, monthKey, monthLabel, parseOccurredAt } from "./types"; @@ -139,6 +140,27 @@ export function ExpenseList({ items, fields }: ExpenseListProps) { setExpandedId((prev) => (prev === id ? null : id)); }, []); + const jumpToActiveMonth = useCallback(() => { + if (!activeMonth) return; + const anchor = listRef.current?.querySelector( + `[data-month-anchor="${activeMonth}"]`, + ); + if (!anchor) return; + const offset = window.matchMedia("(min-width: 900px)").matches ? 64 : 56; + const top = anchor.getBoundingClientRect().top + window.scrollY - offset; + window.scrollTo({ top, behavior: "smooth" }); + }, [activeMonth]); + + const handlePillKeyDown = useCallback( + (event: React.KeyboardEvent) => { + if (event.key === "Enter" || event.key === " ") { + event.preventDefault(); + jumpToActiveMonth(); + } + }, + [jumpToActiveMonth], + ); + useEffect(() => { const root = listRef.current; if (!root || groups.length === 0) return; @@ -179,6 +201,7 @@ export function ExpenseList({ items, fields }: ExpenseListProps) { {groups.map((group) => ( +