# Autocomplete

- Page: https://jiguang132.com/resources/material-ui/docs/autocomplete
- Resource: Material UI (https://jiguang132.com/resources/material-ui.md)
- All guides: https://jiguang132.com/resources/material-ui/docs.md

Search and select from supplied options, with distinct input and selection state.

This guide covers Material UI Core with the default Emotion engine; extensions and additional demos are explicitly classified.

## Use case and business boundary

Remote queries, pagination and creation are host responsibilities; freeSolo may produce strings rather than option objects.

## Native composition and scope

`TextField`, `Popper`, `Autocomplete`

Preserve native Material UI composition and types; do not substitute JGuang UI/Base UI/Radix APIs. Example entries are not extra components.

## Native installation and initialization

```bash
npm install @mui/material@9.4.0 @emotion/react@11.14.0 @emotion/styled@11.14.1
```

Use native npm and Emotion, not an invented JGuang UI Registry URL. Place examples inside native ThemeProvider; choose CssBaseline or ScopedCssBaseline for the project. Inspect React, existing providers, lockfile and SSR first. Never overwrite files or conceal peer conflicts. This batch verified React 19.2.8; React 18 and below require matching react-is. See the included bilingual setup guide.

## Practical native parameters

These selected parameters are not a flattened universal API. Preserve the native declaring owner, slot structure, nullable values and generics.

| Owner.prop | Practical role | Declaration source |
| --- | --- | --- |
| `Autocomplete.options` | Host-supplied Autocomplete options; retain its generic item type. | `Autocomplete` |
| `Autocomplete.value` | Controlled native value; its scalar/array/nullable type is owner-specific. | `Autocomplete` |
| `Autocomplete.inputValue` | Autocomplete's controlled text input, distinct from selected value. | `Autocomplete` |
| `Autocomplete.onChange` | Owning control's native callback; preserve its exact event/value/nullable signature. | `Autocomplete` |
| `Autocomplete.onInputChange` | Autocomplete text-change callback, not selection change. | `Autocomplete` |
| `Autocomplete.isOptionEqualToValue` | Compare actual option identity against selection; handle the native value type. | `Autocomplete` |
| `Autocomplete.renderInput` | Autocomplete input renderer; spread native params, refs and inputProps correctly. | `Autocomplete` |

## Runnable native examples

Machine keys select example entries, not universal variant props. Native demo JSX/data stay unchanged; JGuang-authored acceptance fixtures are explicitly labelled.

- Combo box · `ComboBox` · upstream native demo
- Playground · `Playground` · upstream native demo
- Country select · `CountrySelect` · upstream native demo
- Controlled states · `ControllableStates` · upstream native demo
- Search input · `FreeSolo` · upstream native demo
- Creatable · `FreeSoloCreateOption` · upstream native demo
- Creatable · `FreeSoloCreateOptionDialog` · upstream native demo
- Grouped · `Grouped` · upstream native demo
- Grouped · `RenderGroup` · upstream native demo
- Disabled options · `DisabledOptions` · upstream native demo
- `useAutocomplete` · `UseAutocomplete` · upstream native demo
- Customized hook · `CustomizedHook` · upstream native demo
- Load on open · `Asynchronous` · upstream native demo
- Single value rendering · `CustomSingleValueRendering` · upstream native demo
- Multiple values · `Tags` · upstream native demo
- Fixed options · `FixedTags` · upstream native demo
- Selection indicators · `CheckboxesTags` · upstream native demo
- Limit tags · `LimitTags` · upstream native demo
- Sizes · `Sizes` · upstream native demo
- Custom input · `CustomInputAutocomplete` · upstream native demo
- Globally customized options · `GloballyCustomizedOptions` · upstream native demo
- GitHub's picker · `GitHubLabel` · upstream native demo
- Hint · `AutocompleteHint` · upstream native demo
- Returns · `Filter` · upstream native demo

## Explicitly unsupported additional examples

These remain in the upstream inventory, not silently skipped or presented as working previews. Additional dependency/framework acceptance is required.

- Google Maps place · `GoogleMaps`: `autosuggest-highlight/parse`
- Infinite loading · `InfiniteLoading`: `@tanstack/react-query`, `@tanstack/react-virtual`
- Highlights · `Highlights`: `autosuggest-highlight/parse`, `autosuggest-highlight/match`
- Virtualization · `Virtualize`: `react-window`

## Actual usage example

Unmodified pinned native demo; copy its required local helper files together.

```tsx
import TextField from '@mui/material/TextField';
import Autocomplete from '@mui/material/Autocomplete';
import top100Films from './top100Films';

export default function ComboBox() {
  return (
    <Autocomplete
      disablePortal
      options={top100Films}
      sx={{ width: 300 }}
      renderInput={(params) => <TextField {...params} label="Movie" />}
    />
  );
}

```

## Example dependency boundaries

`@mui/material/TextField`, `@mui/material/Autocomplete`, `react`, `@mui/material/Stack`, `@mui/material/Box`, `@mui/material/Dialog`, `@mui/material/DialogTitle`, `@mui/material/DialogContent`, `@mui/material/DialogContentText`, `@mui/material/DialogActions`, `@mui/material/Button`, `@mui/system`, `@mui/material/useAutocomplete`, `@mui/icons-material/Check`, `@mui/icons-material/Close`, `@mui/material/styles`, `@mui/material/CircularProgress`, `@mui/material/Chip`, `@mui/icons-material/CheckBoxOutlineBlank`, `@mui/icons-material/CheckBox`, `@mui/material/Popper`, `@mui/material/ClickAwayListener`, `@mui/icons-material/Settings`, `@mui/icons-material/Done`, `@mui/material/ButtonBase`, `@mui/material/InputBase`, `@mui/material/Typography`

Direct Icons/System/Utils example imports require their matching 9.4.0 packages. Relative data/helpers are part of the example closure, not extra components. Remote images and simulated operations do not supply a backend.

## Pinned upstream API metadata reference

These tables retain the upstream metadata, not a newly inferred generic type system. Conditional generics, inherited props and callback details are defined by the source declarations below. Theme defaults may override metadata defaults.

### TextField

```tsx
import TextField from '@mui/material/TextField';
import { TextField } from '@mui/material';
```

Native inheritance: `FormControl`. Parent/DOM props are not fabricated as additional own props.

| Prop | Required | Upstream metadata type / constraint | Metadata default |
| --- | --- | --- | --- |
| `autoComplete` | no | `string` | — |
| `autoFocus` | no | `bool` | `false` |
| `classes` | no | `object` | — |
| `color` | no | `'primary' \| 'secondary' \| 'error' \| 'info' \| 'success' \| 'warning' \| string` | `'primary'` |
| `defaultValue` | no | `any` | — |
| `disabled` | no | `bool` | `false` |
| `error` | no | `bool` | `false` |
| `fullWidth` | no | `bool` | `false` |
| `helperText` | no | `node` | — |
| `id` | no | `string` | — |
| `inputRef` | no | `ref` | — |
| `label` | no | `node` | — |
| `margin` | no | `'dense' \| 'none' \| 'normal'` | `'none'` |
| `maxRows` | no | `number \| string` | — |
| `minRows` | no | `number \| string` | — |
| `multiline` | no | `bool` | `false` |
| `name` | no | `string` | — |
| `onChange` | no | `func` | — |
| `placeholder` | no | `string` | — |
| `required` | no | `bool` | `false` |
| `rows` | no | `number \| string` | — |
| `select` | no | `bool` | `false` |
| `size` | no | `'medium' \| 'small' \| string` | `'medium'` |
| `slotProps` | no | `{ formHelperText?: func \| object, htmlInput?: func \| object, input?: func \| object, inputLabel?: func \| object, select?: func \| object }` | `{}` |
| `slots` | no | `{ formHelperText?: elementType, htmlInput?: elementType, input?: elementType, inputLabel?: elementType, root?: elementType, select?: elementType }` | `{}` |
| `sx` | no | `Array<func \| object \| bool> \| func \| object` | — |
| `type` | no | `string` | — |
| `value` | no | `any` | — |
| `variant` | no | `'filled' \| 'outlined' \| 'standard'` | `'outlined'` |



### Popper

```tsx
import Popper from '@mui/material/Popper';
import { Popper } from '@mui/material';
```

| Prop | Required | Upstream metadata type / constraint | Metadata default |
| --- | --- | --- | --- |
| `open` | yes | `bool` | — |
| `anchorEl` | no | `HTML element \| object \| func` | — |
| `children` | no | `node \| func` | — |
| `component` | no | `elementType` | — |
| `container` | no | `HTML element \| func` | — |
| `disablePortal` | no | `bool` | `false` |
| `keepMounted` | no | `bool` | `false` |
| `modifiers` | no | `Array<{ data?: object, effect?: func, enabled?: bool, fn?: func, name?: any, options?: object, phase?: 'afterMain' \| 'afterRead' \| 'afterWrite' \| 'beforeMain' \| 'beforeRead' \| 'beforeWrite' \| 'main' \| 'read' \| 'write', requires?: Array<string>, requiresIfExists?: Array<string> }>` | — |
| `placement` | no | `'auto-end' \| 'auto-start' \| 'auto' \| 'bottom-end' \| 'bottom-start' \| 'bottom' \| 'left-end' \| 'left-start' \| 'left' \| 'right-end' \| 'right-start' \| 'right' \| 'top-end' \| 'top-start' \| 'top'` | `'bottom'` |
| `popperOptions` | no | `{ modifiers?: array, onFirstUpdate?: func, placement?: 'auto-end' \| 'auto-start' \| 'auto' \| 'bottom-end' \| 'bottom-start' \| 'bottom' \| 'left-end' \| 'left-start' \| 'left' \| 'right-end' \| 'right-start' \| 'right' \| 'top-end' \| 'top-start' \| 'top', strategy?: 'absolute' \| 'fixed' }` | `{}` |
| `popperRef` | no | `ref` | — |
| `slotProps` | no | `{ root?: func \| object }` | `{}` |
| `slots` | no | `{ root?: elementType }` | `{}` |
| `sx` | no | `Array<func \| object \| bool> \| func \| object` | — |
| `transition` | no | `bool` | `false` |



### Autocomplete

```tsx
import Autocomplete from '@mui/material/Autocomplete';
import { Autocomplete } from '@mui/material';
```

| Prop | Required | Upstream metadata type / constraint | Metadata default |
| --- | --- | --- | --- |
| `options` | yes | `array` | — |
| `renderInput` | yes | `func` | — |
| `autoComplete` | no | `bool` | `false` |
| `autoHighlight` | no | `bool` | `false` |
| `autoSelect` | no | `bool` | `false` |
| `blurOnSelect` | no | `'mouse' \| 'touch' \| bool` | `false` |
| `classes` | no | `object` | — |
| `clearIcon` | no | `node` | `<ClearIcon fontSize="small" />` |
| `clearOnBlur` | no | `bool` | `!props.freeSolo` |
| `clearOnEscape` | no | `bool` | `false` |
| `clearText` | no | `string` | `'Clear'` |
| `closeText` | no | `string` | `'Close'` |
| `defaultValue` | no | `any` | `props.multiple ? [] : null` |
| `disableClearable` | no | `bool` | `false` |
| `disableCloseOnSelect` | no | `bool` | `false` |
| `disabled` | no | `bool` | `false` |
| `disabledItemsFocusable` | no | `bool` | `false` |
| `disableListWrap` | no | `bool` | `false` |
| `disablePortal` | no | `bool` | `false` |
| `filterOptions` | no | `func` | `createFilterOptions()` |
| `filterSelectedOptions` | no | `bool` | `false` |
| `forcePopupIcon` | no | `'auto' \| bool` | `'auto'` |
| `freeSolo` | no | `bool` | `false` |
| `fullWidth` | no | `bool` | `false` |
| `getLimitTagsText` | no | `func` | `(more) => `+${more}`` |
| `getOptionDisabled` | no | `func` | — |
| `getOptionKey` | no | `func` | — |
| `getOptionLabel` | no | `func` | `(option) => option.label ?? option` |
| `groupBy` | no | `func` | — |
| `handleHomeEndKeys` | no | `bool` | `!props.freeSolo` |
| `id` | no | `string` | — |
| `includeInputInList` | no | `bool` | `false` |
| `inputValue` | no | `string` | — |
| `isOptionEqualToValue` | no | `func` | — |
| `limitTags` | no | `integer` | `-1` |
| `loading` | no | `bool` | `false` |
| `loadingText` | no | `node` | `'Loading…'` |
| `multiple` | no | `bool` | `false` |
| `noOptionsText` | no | `node` | `'No options'` |
| `onChange` | no | `func` | — |
| `onClose` | no | `func` | — |
| `onHighlightChange` | no | `func` | — |
| `onInputChange` | no | `func` | — |
| `onOpen` | no | `func` | — |
| `open` | no | `bool` | — |
| `openOnFocus` | no | `bool` | `false` |
| `openText` | no | `string` | `'Open'` |
| `popupIcon` | no | `node` | `<ArrowDropDownIcon />` |
| `readOnly` | no | `bool` | `false` |
| `renderGroup` | no | `func` | — |
| `renderOption` | no | `func` | — |
| `renderValue` | no | `func` | — |
| `resetHighlightOnMouseLeave` | no | `bool` | `false` |
| `selectOnFocus` | no | `bool` | `!props.freeSolo` |
| `size` | no | `'small' \| 'medium' \| string` | `'medium'` |
| `slotProps` | no | `{ chip?: func \| object, clearIndicator?: func \| object, listbox?: func \| object, status?: func \| object, paper?: func \| object, popper?: func \| object, popupIndicator?: func \| object, root?: func \| object }` | `{}` |
| `slots` | no | `{ clearIndicator?: elementType, listbox?: elementType, paper?: elementType, popper?: elementType, popupIndicator?: elementType, root?: elementType, status?: elementType }` | `{}` |
| `sx` | no | `Array<func \| object \| bool> \| func \| object` | — |
| `value` | no | `any` | — |


## Native source declarations

Declarations/imports are extracted from pinned source without flattening unions or external inheritance. Original English comments/types are source reference, not a claim of translated upstream prose. Shared types stay in their native packages.

### vendor/src/TextField/TextField.d.ts

```ts
import * as React from 'react';

import { SxProps } from '@mui/system';

import { OverridableStringUnion } from '@mui/types';

import { Theme } from '../styles';

import { InternalStandardProps as StandardProps } from '../internal';

import { FormControlProps } from '../FormControl';

import { FormHelperTextProps } from '../FormHelperText';

import { InputBaseProps } from '../InputBase';

import { InputProps as StandardInputProps } from '../Input';

import { FilledInputProps } from '../FilledInput';

import { OutlinedInputProps } from '../OutlinedInput';

import { InputLabelProps } from '../InputLabel';

import { SelectProps } from '../Select';

import { TextFieldClasses } from './textFieldClasses';

import { CreateSlotsAndSlotProps, SlotProps } from '../utils/types';

export interface TextFieldPropsColorOverrides {}

export interface TextFieldPropsSizeOverrides {}

export interface TextFieldSlots {
  /**
   * The component that renders the root.
   * @default FormControl
   */
  root: React.ElementType;
  /**
   * The component that renders the input.
   * @default OutlinedInput
   */
  input: React.ElementType;
  /**
   * The component that renders the input's label.
   * @default InputLabel
   */
  inputLabel: React.ElementType;
  /**
   * The html input element.
   * @default 'input'
   */
  htmlInput: React.ElementType;
  /**
   * The component that renders the helper text.
   * @default FormHelperText
   */
  formHelperText: React.ElementType;
  /**
   * The component that renders the select.
   * @default Select
   */
  select: React.ElementType;
}

export interface TextFieldRootSlotPropsOverrides {}

export interface TextFieldInputSlotPropsOverrides {}

export interface TextFieldInputLabelSlotPropsOverrides {}

export interface TextFieldFormHelperTextSlotPropsOverrides {}

export interface TextFieldSelectSlotPropsOverrides {}

export type TextFieldSlotsAndSlotProps<InputPropsType> = CreateSlotsAndSlotProps<
  TextFieldSlots,
  {
    /**
     * Props forwarded to the root slot.
     * By default, the available props are based on the [FormControl](https://mui.com/material-ui/api/form-control/#props) component.
     */
    root: SlotProps<
      React.ElementType<FormControlProps>,
      TextFieldRootSlotPropsOverrides,
      TextFieldOwnerState
    >;
    /**
     * Props forwarded to the input slot.
     * By default, the available props are based on the [Input](https://mui.com/material-ui/api/input/#props) component.
     */
    input: SlotProps<
      React.ElementType<InputPropsType>,
      TextFieldInputSlotPropsOverrides,
      TextFieldOwnerState
    >;
    /**
     * Props forwarded to the input label slot.
     * By default, the available props are based on the [InputLabel](https://mui.com/material-ui/api/input-label/#props) component.
     */
    inputLabel: SlotProps<
      React.ElementType<InputLabelProps>,
      TextFieldInputLabelSlotPropsOverrides,
      TextFieldOwnerState
    >;
    /**
     * Props forwarded to the html input slot.
     * By default, the available props are based on the html input element.
     */
    htmlInput: SlotProps<React.ElementType<InputBaseProps['inputProps']>, {}, TextFieldOwnerState>;
    /**
     * Props forwarded to the form helper text slot.
     * By default, the available props are based on the [FormHelperText](https://mui.com/material-ui/api/form-helper-text/#props) component.
     */
    formHelperText: SlotProps<
      React.ElementType<FormHelperTextProps>,
      TextFieldFormHelperTextSlotPropsOverrides,
      TextFieldOwnerState
    >;
    /**
     * Props forwarded to the select slot.
     * By default, the available props are based on the [Select](https://mui.com/material-ui/api/select/#props) component.
     */
    select: SlotProps<
      React.ElementType<SelectProps>,
      TextFieldSelectSlotPropsOverrides,
      TextFieldOwnerState
    >;
  }
>;

export interface BaseTextFieldProps extends StandardProps<
  FormControlProps,
  // event handlers are declared on derived interfaces
  'onChange' | 'onBlur' | 'onFocus' | 'defaultValue'
> {
  /**
   * This prop helps users to fill forms faster, especially on mobile devices.
   * The name can be confusing, as it's more like an autofill.
   * You can learn more about it [following the specification](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill).
   */
  autoComplete?: string | undefined;
  /**
   * If `true`, the `input` element is focused during the first mount.
   * @default false
   */
  autoFocus?: boolean | undefined;
  /**
   * @ignore
   */
  children?: FormControlProps['children'] | undefined;
  /**
   * Override or extend the styles applied to the component.
   */
  classes?: Partial<TextFieldClasses> | undefined;
  /**
   * The color of the component.
   * It supports both default and custom theme colors, which can be added as shown in the
   * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
   * @default 'primary'
   */
  color?:
    | OverridableStringUnion<
        'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning',
        TextFieldPropsColorOverrides
      >
    | undefined;
  /**
   * The default value. Use when the component is not controlled.
   */
  defaultValue?: unknown;
  /**
   * If `true`, the component is disabled.
   * @default false
   */
  disabled?: boolean | undefined;
  /**
   * If `true`, the label is displayed in an error state.
   * @default false
   */
  error?: boolean | undefined;
  /**
   * If `true`, the input will take up the full width of its container.
   * @default false
   */
  fullWidth?: boolean | undefined;
  /**
   * The helper text content.
   */
  helperText?: React.ReactNode;
  /**
   * The id of the `input` element.
   * Use this prop to make `label` and `helperText` accessible for screen readers.
   */
  id?: string | undefined;
  /**
   * Pass a ref to the `input` element.
   */
  inputRef?: React.Ref<any> | undefined;
  /**
   * The label content.
   */
  label?: React.ReactNode;
  /**
   * If `true`, a `textarea` element is rendered instead of an input.
   * @default false
   */
  multiline?: boolean | undefined;
  /**
   * Name attribute of the `input` element.
   */
  name?: string | undefined;
  onBlur?: InputBaseProps['onBlur'] | undefined;
  onFocus?: StandardInputProps['onFocus'] | undefined;
  /**
   * The short hint displayed in the `input` before the user enters a value.
   */
  placeholder?: string | undefined;
  /**
   * If `true`, the label is displayed as required and the `input` element is required.
   * @default false
   */
  required?: boolean | undefined;
  /**
   * Number of rows to display when multiline option is set to true.
   */
  rows?: string | number | undefined;
  /**
   * Maximum number of rows to display when multiline option is set to true.
   */
  maxRows?: string | number | undefined;
  /**
   * Minimum number of rows to display when multiline option is set to true.
   */
  minRows?: string | number | undefined;
  /**
   * Render a [`Select`](https://mui.com/material-ui/api/select/) element while passing the Input element to `Select` as `input` parameter.
   * If this option is set you must pass the options of the select as children.
   * @default false
   */
  select?: boolean | undefined;
  /**
   * The size of the component.
   * @default 'medium'
   */
  size?: OverridableStringUnion<'small' | 'medium', TextFieldPropsSizeOverrides> | undefined;
  /**
   * The system prop that allows defining system overrides as well as additional CSS styles.
   */
  sx?: SxProps<Theme> | undefined;
  /**
   * Type of the `input` element. It should be [a valid HTML5 input type](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#input_types).
   */
  type?: React.InputHTMLAttributes<unknown>['type'] | undefined;
  /**
   * The value of the `input` element, required for a controlled component.
   */
  value?: unknown;
}

export interface StandardTextFieldProps
  extends BaseTextFieldProps, TextFieldSlotsAndSlotProps<StandardInputProps> {
  /**
   * Callback fired when the value is changed.
   *
   * @param {object} event The event source of the callback.
   * You can pull out the new value by accessing `event.target.value` (string).
   */
  onChange?: StandardInputProps['onChange'] | undefined;
  /**
   * The variant to use.
   * @default 'outlined'
   */
  variant?: 'standard' | undefined;
}

export interface FilledTextFieldProps
  extends BaseTextFieldProps, TextFieldSlotsAndSlotProps<FilledInputProps> {
  /**
   * Callback fired when the value is changed.
   *
   * @param {object} event The event source of the callback.
   * You can pull out the new value by accessing `event.target.value` (string).
   */
  onChange?: FilledInputProps['onChange'] | undefined;
  /**
   * The variant to use.
   * @default 'outlined'
   */
  variant: 'filled';
}

export interface OutlinedTextFieldProps
  extends BaseTextFieldProps, TextFieldSlotsAndSlotProps<OutlinedInputProps> {
  /**
   * Callback fired when the value is changed.
   *
   * @param {object} event The event source of the callback.
   * You can pull out the new value by accessing `event.target.value` (string).
   */
  onChange?: OutlinedInputProps['onChange'] | undefined;
  /**
   * The variant to use.
   * @default 'outlined'
   */
  variant: 'outlined';
}

export type TextFieldVariants = 'outlined' | 'standard' | 'filled';

export type TextFieldProps<Variant extends TextFieldVariants = TextFieldVariants> =
  Variant extends 'filled'
    ? FilledTextFieldProps
    : Variant extends 'standard'
      ? StandardTextFieldProps
      : OutlinedTextFieldProps;

export type TextFieldOwnerState = BaseTextFieldProps;

export default function TextField<Variant extends TextFieldVariants>(
  props: {
    /**
     * The variant to use.
     * @default 'outlined'
     */
    variant?: Variant | undefined;
  } & Omit<TextFieldProps, 'variant'>,
): React.JSX.Element;
```

### vendor/src/Popper/Popper.tsx

```ts
import { SxProps } from '@mui/system';

import { useRtl } from '@mui/system/RtlProvider';

import refType from '@mui/utils/refType';

import HTMLElementType from '@mui/utils/HTMLElementType';

import PropTypes from 'prop-types';

import * as React from 'react';

import BasePopper from './BasePopper';

import { PopperProps as BasePopperProps } from './BasePopper.types';

import { Theme } from '../styles';

import { styled } from '../zero-styled';

import { useDefaultProps } from '../DefaultPropsProvider';

export interface PopperProps extends Omit<BasePopperProps, 'direction'> {
  /**
   * The component used for the root node.
   * Either a string to use a HTML element or a component.
   */
  component?: React.ElementType | undefined;
  /**
   * The system prop that allows defining system overrides as well as additional CSS styles.
   */
  sx?: SxProps<Theme> | undefined;
}
```

### vendor/src/Autocomplete/Autocomplete.d.ts

```ts
import * as React from 'react';

import { SxProps } from '@mui/system';

import { OverridableStringUnion } from '@mui/types';

import { Theme } from '../styles';

import { InternalStandardProps as StandardProps } from '../internal';

import { IconButtonProps } from '../IconButton';

import { ChipProps, ChipTypeMap } from '../Chip';

import { PaperProps } from '../Paper';

import { PopperProps } from '../Popper';

import useAutocomplete, {
  AutocompleteChangeDetails,
  AutocompleteChangeReason,
  AutocompleteCloseReason,
  AutocompleteInputChangeReason,
  AutocompleteValue,
  createFilterOptions,
  UseAutocompleteProps,
  AutocompleteFreeSoloValueMapping,
  AutocompleteValueOrFreeSoloValueMapping,
} from '../useAutocomplete';

import { AutocompleteClasses } from './autocompleteClasses';

import { CreateSlotsAndSlotProps, SlotProps } from '../utils/types';

export interface AutocompletePaperSlotPropsOverrides {}

export interface AutocompletePopperSlotPropsOverrides {}

export interface AutocompleteStatusSlotPropsOverrides {}

export type AutocompleteOwnerState<
  Value,
  Multiple extends boolean | undefined,
  DisableClearable extends boolean | undefined,
  FreeSolo extends boolean | undefined,
  ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
> = AutocompleteProps<Value, Multiple, DisableClearable, FreeSolo, ChipComponent> & {
  disablePortal: boolean;
  expanded: boolean;
  focused: boolean;
  fullWidth: boolean;
  getOptionLabel: (option: AutocompleteValueOrFreeSoloValueMapping<Value, FreeSolo>) => string;
  hasClearIcon: boolean;
  hasPopupIcon: boolean;
  inputFocused: boolean;
  popupOpen: boolean;
  size: OverridableStringUnion<'small' | 'medium', AutocompletePropsSizeOverrides>;
};

export type AutocompleteRenderGetTagProps = ({ index }: { index: number }) => {
  key: number;
  className: string;
  disabled: boolean;
  'data-tag-index': number;
  tabIndex: -1;
  onDelete: (event: any) => void;
};

export type AutocompleteRenderValueGetItemProps<Multiple extends boolean | undefined> =
  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 | undefined }) => {
        className: string;
        disabled: boolean;
        'data-item-index': number;
        tabIndex: -1;
        onDelete: (event: any) => void;
      };

export type AutocompleteRenderValue<Value, Multiple, FreeSolo> = Multiple extends true
  ? Array<Value | AutocompleteFreeSoloValueMapping<FreeSolo>>
  : NonNullable<Value | AutocompleteFreeSoloValueMapping<FreeSolo>>;

export interface AutocompleteRenderOptionState {
  inputValue: string;
  index: number;
  selected: boolean;
}

export interface AutocompleteRenderGroupParams {
  key: number;
  group: string;
  children?: React.ReactNode;
}

export interface AutocompleteRenderInputParams {
  id: string;
  disabled: boolean;
  fullWidth: boolean;
  size: 'small' | undefined;
  slotProps: {
    inputLabel: ReturnType<ReturnType<typeof useAutocomplete>['getInputLabelProps']>;
    input: {
      ref: React.Ref<any>;
      className: string;
      startAdornment: React.ReactNode;
      endAdornment: React.ReactNode;
      onMouseDown: React.MouseEventHandler;
    };
    htmlInput: ReturnType<ReturnType<typeof useAutocomplete>['getInputProps']>;
  };
}

export interface AutocompletePropsSizeOverrides {}

export interface AutocompleteSlots {
  /**
   * The component that renders the root.
   * @default 'div'
   */
  root: React.ElementType;
  /**
   * The component used to render the clear indicator element.
   * @default IconButton
   */
  clearIndicator: React.JSXElementConstructor<IconButtonProps>;
  /**
   * The component used to render the popup indicator element.
   * @default IconButton
   */
  popupIndicator: React.JSXElementConstructor<IconButtonProps>;
  /**
   * The component used to render the listbox.
   * @default 'ul'
   */
  listbox: React.JSXElementConstructor<React.HTMLAttributes<HTMLElement>>;
  /**
   * The component used to render the status message container.
   * @default 'div'
   */
  status: React.ElementType;
  /**
   * The component used to render the body of the popup.
   * @default Paper
   */
  paper: React.JSXElementConstructor<PaperProps & AutocompletePaperSlotPropsOverrides>;
  /**
   * The component used to position the popup.
   * @default Popper
   */
  popper: React.JSXElementConstructor<PopperProps & AutocompletePopperSlotPropsOverrides>;
}

export type AutocompleteSlotsAndSlotProps<
  Value,
  Multiple extends boolean | undefined,
  DisableClearable extends boolean | undefined,
  FreeSolo extends boolean | undefined,
  ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
> = CreateSlotsAndSlotProps<
  AutocompleteSlots,
  {
    root: SlotProps<
      'div',
      {},
      AutocompleteOwnerState<Value, Multiple, DisableClearable, FreeSolo, ChipComponent>
    >;
    chip: SlotProps<
      React.ElementType<Partial<ChipProps<ChipComponent>>>,
      {},
      AutocompleteOwnerState<Value, Multiple, DisableClearable, FreeSolo, ChipComponent>
    >;
    clearIndicator: SlotProps<
      React.ElementType<Partial<IconButtonProps>>,
      {},
      AutocompleteOwnerState<Value, Multiple, DisableClearable, FreeSolo, ChipComponent>
    >;
    /**
     * Props applied to the Listbox element.
     */
    listbox: SlotProps<
      React.ElementType<
        ReturnType<ReturnType<typeof useAutocomplete>['getListboxProps']> & {
          sx?: SxProps<Theme> | undefined;
          ref?: React.Ref<Element> | undefined;
        }
      >,
      {},
      AutocompleteOwnerState<Value, Multiple, DisableClearable, FreeSolo, ChipComponent>
    >;
    status: SlotProps<
      'div',
      AutocompleteStatusSlotPropsOverrides,
      AutocompleteOwnerState<Value, Multiple, DisableClearable, FreeSolo, ChipComponent>
    >;
    paper: SlotProps<
      React.ElementType<Partial<PaperProps>>,
      AutocompletePaperSlotPropsOverrides,
      AutocompleteOwnerState<Value, Multiple, DisableClearable, FreeSolo, ChipComponent>
    >;
    popper: SlotProps<
      React.ElementType<Partial<PopperProps>>,
      AutocompletePopperSlotPropsOverrides,
      AutocompleteOwnerState<Value, Multiple, DisableClearable, FreeSolo, ChipComponent>
    >;
    popupIndicator: SlotProps<
      React.ElementType<Partial<IconButtonProps>>,
      {},
      AutocompleteOwnerState<Value, Multiple, DisableClearable, FreeSolo, ChipComponent>
    >;
  }
>;

export interface AutocompleteProps<
  Value,
  Multiple extends boolean | undefined,
  DisableClearable extends boolean | undefined,
  FreeSolo extends boolean | undefined,
  ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
>
  extends
    UseAutocompleteProps<Value, Multiple, DisableClearable, FreeSolo>,
    StandardProps<React.HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange' | 'children'>,
    AutocompleteSlotsAndSlotProps<Value, Multiple, DisableClearable, FreeSolo, ChipComponent> {
  /**
   * Override or extend the styles applied to the component.
   */
  classes?: Partial<AutocompleteClasses> | undefined;
  /**
   * The icon to display in place of the default clear icon.
   * @default <ClearIcon fontSize="small" />
   */
  clearIcon?: React.ReactNode;
  /**
   * Override the default text for the *clear* icon button.
   *
   * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
   * @default 'Clear'
   */
  clearText?: string | undefined;
  /**
   * Override the default text for the *close popup* icon button.
   *
   * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
   * @default 'Close'
   */
  closeText?: string | undefined;
  /**
   * If `true`, the component is disabled.
   * @default false
   */
  disabled?: boolean | undefined;
  /**
   * If `true`, the `Popper` content will be under the DOM hierarchy of the parent component.
   * @default false
   */
  disablePortal?: boolean | undefined;
  /**
   * Force the visibility display of the popup icon.
   * @default 'auto'
   */
  forcePopupIcon?: true | false | 'auto' | undefined;
  /**
   * If `true`, the input takes up the full width of its container.
   *
   * `Autocomplete` treats `undefined` and `false` differently.
   * If `undefined`, the inner input takes up the full width of its container.
   * If `false`, the inner input is restricted to its intrinsic width.
   * @default false
   */
  fullWidth?: boolean | undefined;
  /**
   * 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) | undefined;
  /**
   * 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 | undefined;
  /**
   * Text to display when in a loading state.
   *
   * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
   * @default 'Loading…'
   */
  loadingText?: React.ReactNode;
  /**
   * The maximum number of tags that will be visible when not focused.
   * Set `-1` to disable the limit.
   * @default -1
   */
  limitTags?: number | undefined;
  /**
   * Text to display when there are no options.
   *
   * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
   * @default 'No options'
   */
  noOptionsText?: React.ReactNode;
  onKeyDown?:
    | ((
        event: React.KeyboardEvent<HTMLDivElement> & { defaultMuiPrevented?: boolean | undefined },
      ) => void)
    | undefined;
  /**
   * Override the default text for the *open popup* icon button.
   *
   * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
   * @default 'Open'
   */
  openText?: string | undefined;
  /**
   * The icon to display in place of the default popup icon.
   * @default <ArrowDropDownIcon />
   */
  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 | undefined;
  /**
   * Render the group.
   *
   * @param {AutocompleteRenderGroupParams} params The group to render.
   * @returns {ReactNode}
   */
  renderGroup?: ((params: AutocompleteRenderGroupParams) => React.ReactNode) | undefined;
  /**
   * Render the input.
   *
   * **Note:** The `renderInput` prop must return a `TextField` component or a compatible custom component
   * that correctly forwards `InputProps.ref` and spreads `inputProps`. This ensures proper integration
   * with the Autocomplete's internal logic (e.g., focus management and keyboard navigation).
   *
   * Avoid using components like `DatePicker` or `Select` directly, as they may not forward the required props,
   * leading to runtime errors or unexpected behavior.
   *
   * @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<HTMLLIElement> & { key: React.Key },
        option: Value,
        state: AutocompleteRenderOptionState,
        ownerState: AutocompleteOwnerState<
          Value,
          Multiple,
          DisableClearable,
          FreeSolo,
          ChipComponent
        >,
      ) => React.ReactNode)
    | undefined;
  /**
   * Renders the selected value(s) as rich content in the input for both single and multiple selections.
   *
   * @param {AutocompleteRenderValue<Value, Multiple, FreeSolo>} 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: AutocompleteRenderValue<Value, Multiple, FreeSolo>,
        getItemProps: AutocompleteRenderValueGetItemProps<Multiple>,
        ownerState: AutocompleteOwnerState<
          Value,
          Multiple,
          DisableClearable,
          FreeSolo,
          ChipComponent
        >,
      ) => React.ReactNode)
    | undefined;
  /**
   * The size of the component.
   * @default 'medium'
   */
  size?: OverridableStringUnion<'small' | 'medium', AutocompletePropsSizeOverrides> | undefined;
  /**
   * The system prop that allows defining system overrides as well as additional CSS styles.
   */
  sx?: SxProps<Theme> | undefined;
}

export default function Autocomplete<
  Value,
  Multiple extends boolean | undefined = false,
  DisableClearable extends boolean | undefined = false,
  FreeSolo extends boolean | undefined = false,
  ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
>(
  props: AutocompleteProps<Value, Multiple, DisableClearable, FreeSolo, ChipComponent>,
): React.JSX.Element;
```

## Post-install acceptance

Run strict types, production build and real interactions. Check keyboard labels/focus, disabled/error/read-only semantics where natively supported, both themes, narrow screens and reduced motion. Verify callbacks against the real host data; do not declare installation complete from copying a prompt. Initialization fixtures also require server HTML and warning-free hydration.

## Source and license

https://github.com/mui/material-ui/tree/809a7717b4c050ba3f69b75300689f07c050a16e

MIT · @mui/material@9.4.0. Vendor originals and license are preserved. Full original upstream prose remains in vendor/docs and is not represented as fully translated.

---

Index of all JGuang resources: https://jiguang132.com/llms.txt
