Skip to content

Автозаполнение (Autocomplete)

Автозаполнение - это обычный текстовый ввод, дополненный панелью предлагаемых вариантов.

Виджет полезен для установки значения однострочного текстового поля в одном из двух типов сценариев:

  1. Значение для текстового поля должно быть выбрано из заранее определенного набора допустимых значений, например, поле местоположения должно содержать допустимое имя местоположения: комбобокс.
  2. Текстовое поле может содержать любое произвольное значение, но выгодно предложить пользователю возможные значения, например, поле поиска может предложить похожие или предыдущие поиски, чтобы сэкономить время пользователя: свободное соло.

Он должен стать улучшенной версией пакетов "react-select" и "downshift".

Комбобокс

Значение должно быть выбрано из заранее определенного набора допустимых значений.

Press Enter to start editing

Структура опций

По умолчанию компонент принимает следующие структуры опций:

interface AutocompleteOption {
  label: string;
}
// or
type AutocompleteOption = string;

например:

const options = [
  { label: 'The Godfather', id: 1 },
  { label: 'Pulp Fiction', id: 2 },
];
// or
const options = ['The Godfather', 'Pulp Fiction'];

Однако вы можете использовать различные структуры, предоставив параметр getOptionLabel.

Игровая площадка

Каждый из следующих примеров демонстрирует одну из возможностей компонента Autocomplete.

Выбор страны

Выберите одну из 248 стран.

Управляемые состояния

Компонент имеет два состояния, которыми можно управлять:

  1. состояние "значение" с помощью комбинации свойств value/onChange. Это состояние представляет собой значение, выбранное пользователем, например, при нажатии Enter.
  2. состояние "введенное значение" с помощью комбинации реквизитов inputValue/onInputChange. Это состояние представляет собой значение, отображаемое в текстовом поле.
value: 'Option 1'
inputValue: ''

Свободное соло

Установите freeSolo в true, чтобы текстовое поле могло содержать любое произвольное значение.

Поле поиска

Этот реквизит предназначен для основного случая использования поискового ввода с предложениями, например, поиск Google или react-autowhatever.

С созданием опций

Если вы планируете использовать этот режим для комбобокса (расширенная версия элемента select), мы рекомендуем установить следующие параметры

  • selectOnFocus, чтобы помочь пользователю очистить выбранное значение.
  • clearOnBlur, чтобы помочь пользователю ввести новое значение.
  • handleHomeEndKeys для перемещения фокуса внутри всплывающего окна с помощью клавиш Home и End.
  • Последний вариант, например: Добавить "ВВЕДЕННОЕ ЗНАЧЕНИЕ".

Можно также вывести диалоговое окно, когда пользователь хочет добавить новое значение.

Сгруппированные

Вы можете сгруппировать параметры с помощью атрибута groupBy. Если вы это сделаете, убедитесь, что опции также отсортированы по тому же измерению, по которому они сгруппированы, в противном случае вы увидите дублирующиеся заголовки.

Press Enter to start editing

Чтобы управлять отображением групп, предоставьте атрибут renderGroup. Это функция, которая принимает объект с двумя полями:

  • group - строка, представляющая имя группы
  • children - коллекция элементов списка, которые принадлежат группе.

Следующая демонстрация показывает, как использовать этот атрибут для определения пользовательской разметки и переопределения стилей групп по умолчанию:

Press Enter to start editing

Отключенные опции

Press Enter to start editing

useAutocomplete.

Для расширенной настройки используется headless хук useAutocomplete(). Он принимает почти те же параметры, что и компонент Autocomplete, за вычетом всех реквизитов. связанные с рендерингом JSX. Компонент Autocomplete построен на этом хуке.

import { useAutocomplete } from '@mui/base/AutocompleteUnstyled';

Хук useAutocomplete также реэкспортирован из @mui/material для удобства и обратной совместимости.

import useAutocomplete from '@mui/material/useAutocomplete';

Хук с настройками

The Godfather

Перейдите в раздел Кастомизация для примера с компонентом Autocomplete вместо хука.

Асинхронные запросы

Компонент поддерживает два различных случая асинхронного использования:

Загрузка при открытии

Он отображает состояние выполнения, пока запрос сети находится на рассмотрении.

Поиск по мере ввода

Если ваша логика заключается в получении новых вариантов при каждом нажатии клавиши и использовании текущего значения текстового поля для фильтрации на сервере, вам стоит подумать о дросселировании запросов.

Кроме того, вам нужно отключить встроенную фильтрацию компонента Autocomplete путем переопределив атрибут filterOptions:

<Autocomplete filterOptions={(x) => x} />

Google Maps

Настроенный интерфейс для автозаполнения мест из Google Maps. Для этого демо нам необходимо загрузить Google Maps JavaScript и Google Places API.

Множественные значения

Также известны как теги, пользователю разрешается вводить более одного значения.

Inception
Inception
Inception
Forrest Gump
Inception

Фиксированные опции

В случае, если вам нужно заблокировать определенные теги, чтобы их нельзя было удалить, вы можете установить отключение фишек.

Pulp Fiction
Inception

Галочки

Ограничение тегов

Вы можете использовать параметр limitTags, чтобы ограничить количество отображаемых опций, когда они не сфокусированы.

Inception
Forrest Gump
+1
Press Enter to start editing

Размеры

Вам нравятся маленькие поля для ввода? Используйте параметр size.

Inception
Inception
Inception

Кастомизация

Выбор элемента для поля ввода

Реквизит renderInput позволяет вам настраивать отображаемое поле для ввода. Первый аргумент этого реквизита render содержит реквизиты, которые вам необходимо переслать. Обратите особое внимание на ключи ref и inputProps.

Ярлыки как на GitHub

Эта демонстрация воспроизводит подборщик ярлыков GitHub:

help wanted
type: bug

Перейдите в раздел Customized hook для примера настройки с хуком useAutocomplete вместо компонента.

Выделение

Следующая демонстрация основана на autosuggest-highlight, небольшой (1 кБ) утилите для выделения текста в компонентах autosuggest и autocomplete.

Пользовательский фильтр

Компонент предоставляет фабрику для создания метода фильтра, который может быть предоставлен в свойстве filterOptions. Вы можете использовать его для изменения поведения фильтра опций по умолчанию.

import { createFilterOptions } from '@mui/material/Autocomplete';

TODOTRAN доперевести

createFilterOptions(config) => filterOptions

Arguments

  1. config (object [optional]):
  • config.ignoreAccents (bool [optional]): Defaults to true. Remove diacritics.
  • config.ignoreCase (bool [optional]): Defaults to true. Lowercase everything.
  • config.limit (number [optional]): Default to null. Limit the number of suggested options to be shown. For example, if config.limit is 100, only the first 100 matching options are shown. It can be useful if a lot of options match and virtualization wasn't set up.
  • config.matchFrom ('any' | 'start' [optional]): Defaults to 'any'.
  • config.stringify (func [optional]): Controls how an option is converted into a string so that it can be matched against the input text fragment.
  • config.trim (bool [optional]): Defaults to false. Remove trailing spaces.

Returns

filterOptions: the returned filter method can be provided directly to the filterOptions prop of the Autocomplete component, or the parameter of the same name for the hook.

In the following demo, the options need to start with the query prefix:

const filterOptions = createFilterOptions({
  matchFrom: 'start',
  stringify: (option) => option.title,
});

<Autocomplete filterOptions={filterOptions} />;

Advanced

For richer filtering mechanisms, like fuzzy matching, it's recommended to look at match-sorter. For instance:

import { matchSorter } from 'match-sorter';

const filterOptions = (options, { inputValue }) => matchSorter(options, inputValue);

<Autocomplete filterOptions={filterOptions} />;

Virtualization

Search within 10,000 randomly generated options. The list is virtualized thanks to react-window.

Press Enter to start editing

Events

If you would like to prevent the default key handler behavior, you can set the event's defaultMuiPrevented property to true:

<Autocomplete
  onKeyDown={(event) => {
    if (event.key === 'Enter') {
      // Prevent's default 'Enter' behavior.
      event.defaultMuiPrevented = true;
      // your handler code
    }
  }}
/>

Limitations

autocomplete/autofill

Browsers have heuristics to help the user fill in form inputs. However, this can harm the UX of the component.

By default, the component disables the input autocomplete feature (remembering what the user has typed for a given field in a previous session) with the autoComplete="off" attribute. Google Chrome does not currently support this attribute setting (Issue 587466). A possible workaround is to remove the id to have the component generate a random one.

In addition to remembering past entered values, the browser might also propose autofill suggestions (saved login, address, or payment details). In the event you want the avoid autofill, you can try the following:

  • Name the input without leaking any information the browser can use. e.g. id="field1" instead of id="country". If you leave the id empty, the component uses a random id.

  • Set autoComplete="new-password" (some browsers will suggest a strong password for inputs with this attribute setting):

    <TextField
      {...params}
      inputProps={{
        ...params.inputProps,
        autoComplete: 'new-password',
      }}
    />
    

Read the guide on MDN for more details.

iOS VoiceOver

VoiceOver on iOS Safari doesn't support the aria-owns attribute very well. You can work around the issue with the disablePortal prop.

ListboxComponent

If you provide a custom ListboxComponent prop, you need to make sure that the intended scroll container has the role attribute set to listbox. This ensures the correct behavior of the scroll, for example when using the keyboard to navigate.

Accessibility

(WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/)

We encourage the usage of a label for the textbox. The component implements the WAI-ARIA authoring practices.