import { CSSProperties, HTMLAttributes, KeyboardEvent, ReactNode, SyntheticEvent } from 'react';
export type AutocompleteChangeReason = 'createOption' | 'selectOption' | 'removeOption' | 'clear' | 'blur';
export type AutocompleteInputChangeReason = 'input' | 'reset' | 'clear';
export interface AutocompleteRenderOptionState {
selected: boolean;
index: number;
inputValue: string;
}
/** Props the combobox hands to `renderInput`; spread straight onto `StyledInputField`. */
export interface AutocompleteRenderInputParams {
disabled?: boolean;
size?: 'small' | 'medium';
fullWidth?: boolean;
error?: boolean;
helperText?: ReactNode;
value: string;
onChange: (event: React.ChangeEvent) => void;
onFocus?: () => void;
onKeyDown: (event: KeyboardEvent) => void;
slotProps: {
htmlInput: Record & {
ref?: React.Ref;
};
input: {
ref: React.Ref;
startAdornment?: ReactNode;
endAdornment?: ReactNode;
};
};
}
type OptionLiProps = HTMLAttributes & {
key?: string;
ref?: React.Ref;
[dataAttr: `data-${string}`]: unknown;
};
type SingleValue = T | null;
type MultiValue = T[];
type AutocompleteValue = Multiple extends true ? MultiValue : FreeSolo extends true ? T | string | null : DisableClearable extends true ? T : SingleValue;
/**
* @figmaNode wXrXt5uKNNzV2DnQCgyYZH#20474-29075
* Figma "Autocomplete". The trigger is the outlined **Input field** (shared `field-styles`: 40px,
* border enabled delta-500/`#7a899e`, hover gama-300, focus gama-400 `#1ca1a1`, error error-500),
* so the field **State** (Enabled/Hovered/Focused/Error/Read-only) ← focus/open + `error`/`readOnly`/
* `disabled`. **Filled** ← selected value(s): single fills the input text, multiple renders **Tag
* chips** (`StyledChip`: h32, radius25, label 16/delta-700 — node 20475-29954). The dropdown is the
* **Menus** surface (node 16073-19226): rounded-lg, border delta-300, Menus shadow. Popup indicator =
* `+` (`PlusIconCircle`, multiple) or chevron (single); clear = `CloseIcon`. Non-annotated props are
*/
export interface StyledSelectAutocompleteProps {
/** @figmaProp none — test hook */
dataTest: string;
/** @figmaProp options → dropdown list rows (Menus items / Recipient list items) */
options: readonly T[];
/** @figmaProp none — renders the Figma "Input field" trigger (field State/Filled live here) */
renderInput: (params: AutocompleteRenderInputParams) => ReactNode;
/** @figmaProp Filled — single: input text; multiple: Tag chips (StyledChip) */
value?: SingleValue | MultiValue | string | undefined;
defaultValue?: SingleValue | MultiValue | string | undefined;
onChange?: (event: SyntheticEvent, value: AutocompleteValue, reason: AutocompleteChangeReason, details?: {
option: T;
}) => void;
getOptionLabel?: (option: T) => string;
/** Stable React key per option, independent of the label — required when labels can collide. */
getOptionKey?: (option: T) => string | number;
isOptionEqualToValue?: (option: T, value: T) => boolean;
renderOption?: (props: OptionLiProps, option: T, state: AutocompleteRenderOptionState) => ReactNode;
renderValue?: (value: MultiValue, getItemProps: (opts: {
index: number;
}) => OptionLiProps) => ReactNode;
filterOptions?: (options: T[], state: {
inputValue: string;
}) => T[];
groupBy?: (option: T) => string;
loading?: boolean;
loadingText?: ReactNode;
noOptionsText?: ReactNode;
/** @figmaProp State = true→"Disabled" */
disabled?: boolean;
/** @figmaProp State = true→"Read-only" (chips lose their delete button; no popup/clear icons) */
readOnly?: boolean;
error?: boolean;
helperText?: ReactNode;
/** @figmaProp none — FieldSize (both render the 40px field) */
size?: 'small' | 'medium';
/** @figmaProp Clear (trigger clear button) */
disableClearable?: boolean;
freeSolo?: boolean;
open?: boolean;
onOpen?: (event?: SyntheticEvent) => void;
onClose?: (event?: SyntheticEvent, reason?: string) => void;
disableCloseOnSelect?: boolean;
inputValue?: string;
onInputChange?: (event: SyntheticEvent | null, value: string, reason: AutocompleteInputChangeReason) => void;
/** @figmaProp popup indicator — defaults to `+` (PlusIconCircle) when multiple, else chevron */
popupIcon?: ReactNode;
autoHeight?: boolean;
/** @figmaProp Filled shape — true renders Tag chips + `+` indicator (Figma "multiple select") */
multiple?: Multiple;
allowSelectAll?: boolean;
selectAllLabel?: string;
fullWidth?: boolean;
/** Accepted for MUI parity; single-select already omits selected options via filtering. */
filterSelectedOptions?: boolean;
getOptionDisabled?: (option: T) => boolean;
classes?: {
root?: string;
paper?: string;
listbox?: string;
};
className?: string;
wrapperClassName?: string;
/** Style/class the portalled listbox (MUI `slotProps.popper` parity); e.g. raise its z-index above an overlay. */
slotProps?: {
popper?: {
className?: string;
style?: CSSProperties;
};
};
sx?: unknown;
}
/**
* single + multiple selection (with tag chips + optional select-all), type-ahead filtering,
* async `loading`, grouping, and the MUI `renderInput`/`renderOption`/`renderValue` callback
*
* ponytail: `freeSolo` is accepted (arbitrary input is emitted via onInputChange) but not turned
* into option values; exact keyboard-parity edge cases are Chromatic/axe-gated.
*/
export declare function StyledSelectAutocomplete({ dataTest, options, renderInput, value, onChange, getOptionLabel, getOptionKey, isOptionEqualToValue, renderOption, renderValue, filterOptions, loading, loadingText, noOptionsText, disabled, readOnly, error, helperText, size, disableClearable, disableCloseOnSelect, popupIcon, autoHeight, multiple, allowSelectAll, selectAllLabel, fullWidth, classes, inputValue: controlledInput, onInputChange, open: controlledOpen, onOpen, onClose, className, wrapperClassName, getOptionDisabled, slotProps, }: StyledSelectAutocompleteProps): JSX.Element;
export {};