import type { ReactNode } from "react" import { AdaptiveGrid } from "../AdaptiveGrid/AdaptiveGrid.tsx" import { useTrackMeasurements } from "../LaneTimeline/useTrackMeasurements.ts" import { toClassName } from "../toClassName.ts" import { ScheduleDayCards } from "./ScheduleDayCards.tsx" import { ScheduleHourGrid } from "./ScheduleHourGrid.tsx" import { type ScheduleEntry, ScheduleItem, } from "./ScheduleItem.tsx" export type ScheduleDay = { key: string label: string dateLabel: string isCurrent?: boolean isQuiet?: boolean emptyLabel?: string } export type ScheduleBand = { key: string label: string detail?: string startMinute: number endMinute: number } export type ScheduleLayout = "bands" | "hours" | "cards" export type ScheduleBoardProps = { label: string days: readonly ScheduleDay[] items: readonly ScheduleEntry[] bands: readonly ScheduleBand[] layout?: ScheduleLayout className?: string onSelect?: (key: string) => void formatHour?: (minute: number) => string /** Axis height, in pixels. A minimum preserves short appointments. */ hourGridBlockSize?: number } /** Aligned time bands or an exact hour axis; folds to day cards on measured width. */ export const ScheduleBoard = ({ label, days, items, bands, layout = "bands", className, onSelect, formatHour = (minute) => `${Math.floor(minute / 60)}:00`, hourGridBlockSize = 480, }: ScheduleBoardProps): ReactNode => { const { trackRef, inlineSize, fontSize, isMeasured } = useTrackMeasurements() const isFolded = isMeasured && inlineSize < (days.length * 8 + 4) * fontSize const template = `5.5rem ${days.map((day) => (day.isQuiet ? "minmax(0, .65fr)" : "minmax(0, 1fr)")).join(" ")}` const dayHeader = (