import * as React from 'react'; import { AutocompleteChangeDetails, AutocompleteChangeReason, AutocompleteCloseReason, AutocompleteFreeSoloValueMapping, AutocompleteInputChangeReason, AutocompleteValue, useAutocomplete, UseAutocompleteProps } from '../internal/hooks/useAutocomplete'; import type { ChipProps } from '../Chip/Chip.types'; import type { IconButtonProps } from '../IconButton/IconButton.types'; import type { ListItemProps } from '../ListItem/ListItem.types'; import type { ListSubheaderProps } from '../ListSubheader/ListSubheader.types'; import type { MenuProps } from '../Menu/Menu.types'; import type { MenuItemProps } from '../MenuItem/MenuItem.types'; import { PopperProps } from '../Popper'; import { SxProps } from '../styles'; import { HTMLInputExtraProps } from '../TextField/TextField.types'; import { CreateSlotsAndSlotProps, SlotProps } from '../types/slot'; export type AutocompleteSlot = 'root' | 'listbox' | 'option' | 'groupLabel' | 'clearIndicator' | 'popupIndicator' | 'loading' | 'noOptions' | 'limitTag' | 'chip'; export interface AutocompleteSlots { /** * The component that renders the root. * @default 'div' */ root?: React.ElementType; /** * The component that renders the listbox. * @default 'ul' */ listbox?: React.ElementType; /** * The component used to position the popup. * @default Popper */ popper?: React.ElementType; /** * The component that renders the option. * @default 'li' */ option?: React.ElementType; /** * The component that renders the group label. * @default 'li' */ groupLabel?: React.ElementType; /** * The component that renders the clear indicator. * @default 'button' */ clearIndicator?: React.ElementType; /** * The component that renders the popup indicator. * @default 'button' */ popupIndicator?: React.ElementType; /** * The component that renders the loading. * @default 'li' */ loading?: React.ElementType; /** * The component that renders the no-options. * @default 'li' */ noOptions?: React.ElementType; /** * The component that renders the limit tag. * @default 'span' */ limitTag?: React.ElementType; /** * The component that renders the chip. * @default 'div' */ chip?: React.ElementType; } export type { AutocompleteChangeDetails, AutocompleteChangeReason, AutocompleteCloseReason, AutocompleteInputChangeReason, AutocompleteValue, }; export type AutocompleteRenderGetTagProps = ({ index }: { index: number; }) => { key: number; className: string; disabled: boolean; 'data-tag-index'?: number; tabIndex: number; onDelete: (event: any) => void; }; export type AutocompleteRenderValueGetItemProps = Multiple extends true ? (args: { index: number; }) => { key: number; className: string; disabled: boolean; 'data-item-index': number; tabIndex: -1; onDelete: (event: any) => void; } : (args?: { index?: number; }) => { className: string; disabled: boolean; 'data-item-index': number; tabIndex: -1; onDelete: (event: any) => void; }; export type AutocompleteRenderValue = Multiple extends true ? Array> : NonNullable>; export interface AutocompleteRenderOptionState { inputValue: string; index: number; selected: boolean; } export interface AutocompleteRenderGroupParams { key: string; group: string; children?: React.ReactNode; } export interface AutocompleteRenderInputParams { id?: string; disabled: boolean; fullWidth: boolean; size: 'small' | 'medium' | 'large'; className: string; children?: React.ReactNode; startDecorator?: React.ReactNode; endDecorator?: React.ReactNode; onMouseDown: React.MouseEventHandler; slotProps: { label: ReturnType['getInputLabelProps']>; htmlInput: HTMLInputExtraProps; }; } export type AutocompleteSlotsAndSlotProps = CreateSlotsAndSlotProps>; listbox: SlotProps<'ul', MenuProps, AutocompleteOwnerState>; popper: SlotProps<'div', PopperProps, AutocompleteOwnerState>; option: SlotProps<'li', MenuItemProps, AutocompleteOwnerState>; groupLabel: SlotProps<'li', ListSubheaderProps, AutocompleteOwnerState>; clearIndicator: SlotProps<'button', IconButtonProps, AutocompleteOwnerState>; popupIndicator: SlotProps<'button', IconButtonProps, AutocompleteOwnerState>; loading: SlotProps<'li', ListItemProps, AutocompleteOwnerState>; noOptions: SlotProps<'li', ListItemProps, AutocompleteOwnerState>; limitTag: SlotProps<'div', object, AutocompleteOwnerState>; chip: SlotProps<'div', ChipProps, AutocompleteOwnerState>; }>; export interface AutocompleteLocale { /** * Override the default text for the *clear* icon button. * * @default 'Clear' */ clearText?: string; /** * Override the default text for the *close popup* icon button. * * @default 'Close' */ closeText?: string; /** * Text to display when in a loading state. * * @default 'Loading…' */ loadingText?: React.ReactNode; /** * Text to display when there are no options. * * @default 'No options' */ noOptionsText?: React.ReactNode; /** * Override the default text for the *open popup* icon button. * * @default 'Open' */ openText?: string; } export interface AutocompleteProps extends UseAutocompleteProps, AutocompleteLocale, Omit, 'defaultValue' | 'onChange' | 'children' | 'color'>, AutocompleteSlotsAndSlotProps { /** * The icon to display in place of the default clear icon. * @default */ clearIcon?: React.ReactNode; /** * If `true`, the component is disabled. * @default false */ disabled?: boolean; /** * If `true`, the `Popper` content will be under the DOM hierarchy of the parent component. * @default false */ disablePortal?: boolean; /** * Force the visibility display of the popup icon. * @default 'auto' */ forcePopupIcon?: true | false | 'auto'; /** * If `true`, the input will take up the full width of its container. * @default false */ fullWidth?: boolean; /** * The label to display when the tags are truncated (`limitTags`). * * @param {number} more The number of truncated tags. * @returns {ReactNode} * @default (more) => `+${more}` */ getLimitTagsText?: (more: number) => React.ReactNode; /** * If `true`, the component is in a loading state. * This shows the `loadingText` in place of suggestions (only if there are no suggestions to show, for example `options` are empty). * @default false */ loading?: boolean; /** * The maximum number of tags that will be visible when not focused. * Set `-1` to disable the limit. * @default -1 */ limitTags?: number; onKeyDown?: (event: React.KeyboardEvent & { defaultMuiPrevented?: boolean; }) => void; /** * The icon to display in place of the default popup icon. * @default */ popupIcon?: React.ReactNode; /** * If `true`, the component becomes readonly. It is also supported for multiple tags where the tag cannot be deleted. * @default false */ readOnly?: boolean; /** * Render the group. * * @param {AutocompleteRenderGroupParams} params The group to render. * @returns {ReactNode} */ renderGroup?: (params: AutocompleteRenderGroupParams) => React.ReactNode; /** * Render the input. * * @param {object} params * @returns {ReactNode} */ renderInput: (params: AutocompleteRenderInputParams) => React.ReactNode; /** * Render the option, use `getOptionLabel` by default. * * @param {object} props The props to apply on the li element. * @param {Value} option The option to render. * @param {object} state The state of each option. * @param {object} ownerState The state of the Autocomplete component. * @returns {ReactNode} */ renderOption?: (props: React.HTMLAttributes & { key: string | number; }, option: Value, state: AutocompleteRenderOptionState, ownerState: AutocompleteOwnerState) => React.ReactNode; /** * Renders the selected value(s) as rich content in the input for both single and multiple selections. * * @param {AutocompleteRenderValue} value The `value` provided to the component. * @param {function} getItemProps The value item props. * @param {object} ownerState The state of the Autocomplete component. * @returns {ReactNode} */ renderValue?: (value: AutocompleteValue, getItemProps: AutocompleteRenderValueGetItemProps, ownerState: AutocompleteOwnerState) => React.ReactNode; /** * The size of the component. * @default 'medium' */ size?: 'small' | 'medium' | 'large'; /** * If provided, the options will be grouped under the returned string. * The groupBy value is also used as the text for group headings when `renderGroup` is not provided. * * @param {Value} options The options to group. * @returns {string} */ groupBy?: (option: Value) => string; /** * The system prop that allows defining system overrides as well as additional CSS styles. */ sx?: SxProps; } export type AutocompleteOwnerState = AutocompleteProps & { disablePortal: boolean; expanded: boolean; focused: boolean; hasClearIcon: boolean; hasPopupIcon: boolean; inputFocused: boolean; popupOpen: boolean; filled: boolean; };