import { type HTMLAttributes, type ReactNode } from 'react'; import { type VariantProps } from 'class-variance-authority'; import { type AppointmentItem } from '../appointment-card'; /** Curated imperative handle — identifiers + lifecycle state only. */ export interface AppointmentTimelineHandle { getItems: () => Array<{ id: string; state: string; }>; selectItem: (id: string) => void; jumpToToday: () => void; } export interface AppointmentTimelineProps extends Omit, 'onClick' | 'id' | 'title'> { /** Stable instance id, surfaced as `data-component-id`. */ id?: string; /** Appointments to render — any order; grouped + sorted internally. */ items: AppointmentItem[]; /** * ISO-8601 "now" anchor — the timeline scrolls to this day on mount and the * "Today" preset returns to it. Defaults to the current instant. Stories pass * a fixed value for deterministic snapshots. */ nowIso?: string; /** Panel heading. Defaults to the localised "Appointments". */ title?: string; /** BCP-47 locale override for day headers + each AppointmentCard. */ locale?: string; /** ISO-4217 currency code passed to each AppointmentCard. */ currency?: string; /** Visual density passed to each AppointmentCard. */ size?: 'sm' | 'md'; /** * Lead each row with the PATIENT (avatar + name as the row title) rather * than the operator. Default `false`: the timeline was built for a * patient-scoped rail, where repeating the name on every row is noise. A * clinic-wide agenda — "who is coming in next" across the practice — * passes `true`, and rows with no patient read as "No patient". */ showPatient?: boolean; /** Fires when a row is activated. */ onOpenAppointment?: (item: AppointmentItem) => void; /** * The id of the currently selected appointment. The matching card * renders with `selected` (info-tinted accent + `aria-current`) so the * eye keeps its place in the list after a click. */ selectedId?: string; /** Load earlier (past) appointments — fired when the top edge is reached. */ onLoadEarlier?: () => void; /** Load later (future) appointments — fired when the bottom edge is reached. */ onLoadLater?: () => void; /** Whether more past appointments exist. Defaults to `true` when `onLoadEarlier` is set. */ hasMoreEarlier?: boolean; /** Whether more future appointments exist. Defaults to `true` when `onLoadLater` is set. */ hasMoreLater?: boolean; /** Show a loading row at the top edge. */ loadingEarlier?: boolean; /** Show a loading row at the bottom edge. */ loadingLater?: boolean; /** Show the date-filter row (presets + jump-to-date). Default `true`. */ showFilters?: boolean; /** * Fired when a jump-to-date / preset targets a day outside the loaded range, * so the consumer can load it. The timeline scrolls to the nearest rendered * day until then. */ onJumpToDate?: (dateIso: string) => void; emptyTitle?: string; emptyDescription?: string; /** Accessible name for the panel region (defaults to `title`). */ 'aria-label'?: string; /** * Content rendered between the header/filter row and the scroll region — * a summary strip, a "happening now" band, anything the host needs * ahead of the day-grouped list. Omitted by default (no change to * today's layout). Not part of the scroll region: it stays fixed like * the header above it. */ headerExtra?: ReactNode; /** * Forwarded to every row's `AppointmentCard`: withhold the lifecycle * badge for the default/expected state (`confirmed`). Default `false` * (today's behaviour — every state shows its badge). */ hideDefaultStatus?: boolean; } declare const rootVariants: (props?: ({ size?: "sm" | "md" | null | undefined; } & import("class-variance-authority/types").ClassProp) | undefined) => string; export declare const AppointmentTimeline: import("react").ForwardRefExoticComponent>; /** Re-export of the size variant union for downstream typing. */ export type AppointmentTimelineSize = NonNullable['size']>; export {}; //# sourceMappingURL=appointment-timeline.d.ts.map