import { type HTMLAttributes } from 'react';
import { type VariantProps } from 'class-variance-authority';
export type SlotGridState = 'default' | 'loading' | 'disabled' | 'empty';
export type SlotGridSize = 'sm' | 'md' | 'lg';
export interface SlotGridSlot {
/** Stable identity — used by consumers to resolve selection. */
id: string;
/** Slot start — ISO string or `Date`. Rendered via `Intl.DateTimeFormat`. */
start: string | Date;
/** Optional slot end — if omitted only the start time is announced. */
end?: string | Date;
/** Defaults to `true`. Unavailable slots render disabled and are not focusable. */
available?: boolean;
/** Override the default `Intl`-formatted time label. */
label?: string;
/** Override the accessible name of the slot button. */
ariaLabel?: string;
}
export interface SlotGridDay {
/** The calendar day the column represents. */
date: string | Date;
/** Slots for this day, in chronological order. Empty array ⇒ empty day. */
slots: SlotGridSlot[];
/** Override the default `Intl`-formatted day header. */
label?: string;
}
export interface SlotGridProps extends Omit, 'aria-label' | 'onSelect'>, VariantProps {
/** Days to render, one column per entry. */
days: SlotGridDay[];
/** Visual / interactive state. Defaults to `'default'`. */
state?: SlotGridState;
/** Localised guidance below the empty title, for an empty day or range. */
emptyDescription?: string;
/** Density of the slot buttons and day headers. Defaults to `'md'`. */
size?: SlotGridSize;
/** Id of the currently selected slot (controlled). */
selectedSlotId?: string;
/**
* Initial number of slots to render per day before the "Show more"
* progressive-disclosure control collapses the rest. Defaults to `6`.
*/
maxInitialSlotsPerDay?: number;
/**
* BCP-47 locale tag for `Intl.DateTimeFormat`. Defaults to the active
* i18next language.
*/
locale?: string;
/** IANA time zone for `Intl.DateTimeFormat`. Optional. */
timeZone?: string;
/** Whether the "previous days" navigation arrow should be enabled. */
hasPrevious?: boolean;
/** Whether the "next days" navigation arrow should be enabled. */
hasNext?: boolean;
/**
* When `true`, renders the "Next available" CTA at the end of the
* toolbar. Only emits a callback — the consumer owns the navigation.
*/
showNextAvailable?: boolean;
/** Accessible label for the outer grid region. */
ariaLabel?: string;
/** Fires when the user selects an available slot. */
onSlotSelect?: (slot: SlotGridSlot, day: SlotGridDay) => void;
/** Fires when the user clicks the "previous days" arrow. */
onPreviousDays?: () => void;
/** Fires when the user clicks the "next days" arrow. */
onNextDays?: () => void;
/** Fires when the user clicks a day's "Show more" button. */
onShowMore?: (day: SlotGridDay) => void;
/** Fires when the user clicks the "Next available" CTA. */
onJumpToNextAvailable?: () => void;
}
/**
* Imperative handle the agent adapter (`slot-grid.agent.ts`) reads and drives.
*
* It is NOT the `ref` — `ref` stays the outer `HTMLDivElement` so existing
* consumers are unaffected. The handle is built with `useMemo` and handed to
* `useAgentRegistration`, the same shape Autocomplete uses.
*
* Every getter returns identifiers and structural state only — availability
* slot ids, calendar day keys, booleans. Never patient data (PRS §26 §7).
*/
export interface SlotGridHandle {
/** Current visual / interactive state (`default` / `loading` / `disabled` / `empty`). */
getStatus: () => SlotGridState;
/** Controlled `selectedSlotId` prop, or `null` when nothing is selected. */
getSelectedSlotId: () => string | null;
/** Day keys (`yyyy-MM-dd`) of the currently-rendered columns, in order. */
getVisibleDays: () => string[];
/** Day key → ids of that day's AVAILABLE slots (collapsed ones included). */
getSlotsByDay: () => Record;
/** Day keys whose "Show more" control has been used. */
getExpandedDays: () => string[];
/** Mirrors the `hasPrevious` prop — whether an earlier window exists. */
getHasPrevious: () => boolean;
/** Mirrors the `hasNext` prop — whether a later window exists. */
getHasNext: () => boolean;
/** Select an available slot by id. Returns `false` when it cannot be selected. */
selectSlot: (slotId: string) => boolean;
/** Page the window forward. Returns `false` when the arrow would be disabled. */
nextDays: () => boolean;
/** Page the window back. Returns `false` when the arrow would be disabled. */
previousDays: () => boolean;
/** Reveal a day's collapsed slots. Returns `false` when the day is not visible. */
showMoreDay: (dayKey: string) => boolean;
}
declare const slotGridVariants: (props?: ({
size?: "sm" | "md" | "lg" | null | undefined;
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
/** Is `a` the same calendar day as `b`? Uses `date-fns`, locale-agnostic. */
export declare function isSameDate(a: string | Date, b: string | Date): boolean;
/** Find the first day in a list that has at least one available slot. */
export declare function findFirstAvailable(days: SlotGridDay[]): {
day: SlotGridDay;
slot: SlotGridSlot;
} | undefined;
export declare const SlotGrid: import("react").ForwardRefExoticComponent>;
export {};
//# sourceMappingURL=slot-grid.d.ts.map