import { type KeyboardEvent as ReactKeyboardEvent } from 'react'; export type VariablesMenuGroup = 'patient' | 'appointment' | 'practice' | 'operator' | 'document'; /** A single merge variable the menu can insert. */ export interface VariablesMenuVariable { /** Inserted as `[[token]]`. Letters, digits and underscores only. */ token: string; /** Localised label shown at the start of the row. */ label: string; /** Optional second line (reserved for a future resolved-value preview). */ description?: string; /** One of the fixed catalogue groups. Ungrouped variables land in "Other". */ group?: VariablesMenuGroup | string; } export type VariablesMenuCloseReason = 'escape' | 'select' | 'outside' | 'backspace'; /** Imperative surface for a host that owns its own keydown handling (the * caret anchor forwards key events from the editor's contenteditable region, * which sits outside this component's own DOM subtree). */ export interface VariablesMenuHandle { /** Forward a keydown from the host. Returns true when the menu consumed * it — the host should then call `preventDefault`/`stopPropagation`. */ handleKeyDown: (event: ReactKeyboardEvent | KeyboardEvent) => boolean; /** Focus the search field (button anchor only — the caret anchor keeps * focus in the editor and never calls this). */ focusSearch: () => void; } export interface VariablesMenuProps { /** Stable id for agent registration / DOM addressing. */ id?: string; className?: string; /** The full catalogue on offer. */ variables: VariablesMenuVariable[]; /** Most-recently-used tokens, most recent first. Only the first 3 render. */ recentTokens?: string[]; /** Current filter text. Always controlled — the caret anchor mirrors the * text the reader is typing into the document; the button anchor mirrors * its own search field. */ query: string; onQueryChange: (query: string) => void; onSelect: (variable: VariablesMenuVariable) => void; onClose: (reason: VariablesMenuCloseReason) => void; /** False for the caret anchor: no search field at all — the text typed * after `[[` in the document is the filter, the host's contenteditable * keeps focus and forwards keys via the imperative handle. Default true. */ searchFocusable?: boolean; 'aria-label'?: string; /** Fires whenever the active row's DOM id changes (including to * `undefined` when the list is empty). The caret anchor mirrors this onto * the editor's own `aria-activedescendant`, since focus — and so the * combobox role — lives on the contenteditable, not in this component. */ onActiveDescendantChange?: (id: string | undefined) => void; } export declare const VariablesMenu: import("react").ForwardRefExoticComponent>; //# sourceMappingURL=variables-menu.d.ts.map