Pular para o conteúdo

Autocompletar

O autocompletar é uma entrada de texto normal aprimorada por um painel de opções sugeridas.

Essa ferramenta é útil para configurar os valores de um campo de texto quando em um dos dois cenários abaixo:

  1. O valor para a caixa de texto deve ser escolhido a partir de um conjunto pré-definido de valores permitidos, por exemplo, um campo de localização deve conter um nome de localização válido: caixa de combinação.
  2. A caixa de texto pode conter qualquer valor arbitrário, mas é mais vantajosa, porque pode sugerir possíveis valores para o usuário, por exemplo, um campo de pesquisa que pode sugerir pesquisas anteriores ou semelhantes para economizar o tempo do usuário: free solo.

A ideia dessa ferramenta é ser uma versão melhorada das bibliotecas "react-select" e "downshift".

Caixa de combinação

O valor deve ser escolhido a partir de um conjunto predefinido de valores permitidos.

<Autocomplete
  disablePortal
  id="combo-box-demo"
  options={top100Films}
  style={{ width: 300 }}
  renderInput={(params) => <TextField {...params} label="Movie" />}
/>

Área de exemplos

Por padrão, o componente aceita as seguintes estruturas de opções:

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

<Autocomplete filterOptions={filterOptions} />

Escolha um dos 248 países.

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

No entanto, você pode usar estruturas diferentes fornecendo uma propriedade getOptionLabel.

Área de exemplos

Cada um dos exemplos a seguir demonstra uma funcionalidade do componente Autocomplete.

Seleção de países

Escolha um dos 248 países.

Estados controláveis

O componente tem dois estados que podem ser controlados:

  1. o estado "value" com a combinação das propriedades value/onChange. Esse estado representa o valor selecionado pelo usuário, por exemplo, quando é pressionado a tecla Enter.
  2. o estado "input value" com a combinação das propriedades inputValue/onInputChange. Esse estado representa o valor exibido na caixa de texto.

⚠️ Esses dois estados estão isolados, eles podem ser controlados de forma independente.

value: 'Option 1'
inputValue: ''

Free solo

Coloque freeSolo como true para que o campo de texto contenha qualquer valor aleatório.

Campo search

Você pode também exibir um diálogo quando o usuário quiser adicionar um novo valor.

Creatable

Se você pretende usar este modo para uma caixa de combinação, por experiência (uma versão aprimorada de um elemento select) recomendamos a configuração:

  • selectOnFocus para ajudar o usuário a limpar o valor selecionado.
  • clearOnBlur para ajudar o usuário a digitar um novo valor.
  • handleHomeEndKeys para mover o foco dentro do popup com as teclas Home e End.
  • Adicione uma última opção para indicar a possibilidade de adição, por exemplo Adicionar "SUA PESQUISA".

Você pode também exibir um diálogo quando o usuário quiser adicionar um novo valor.

Agrupamento

Você pode agrupar as opções com a propriedade groupBy. Se você fizer isso, certifique-se de que as opções também estejam classificadas com a mesma dimensão que serão agrupadas, caso contrário, você notará cabeçalhos duplicados.

<Autocomplete
  id="grouped-demo"
  options={options.sort((a, b) => -b.firstLetter.localeCompare(a.firstLetter))}
  groupBy={(option) => option.firstLetter}
  getOptionLabel={(option) => option.title}
  style={{ width: 300 }}
  renderInput={(params) => <TextField {...params} label="With categories" />}
/>

Opções desabilitadas

<Autocomplete
  id="disabled-options-demo"
  options={timeSlots}
  getOptionDisabled={(option) =>
    option === timeSlots[0] || option === timeSlots[2]
  }
  style={{ width: 300 }}
  renderInput={(params) => <TextField {...params} label="Disabled options" />}
/>

useAutocomplete

Para casos de customização avançada, nós expomos o hook useAutocomplete(). Ele aceita quase as mesmas opções do componente autocompletar exceto todas as propriedades relacionadas a renderização do JSX. O componente autocompletar usa esse hook internamente.

import useAutocomplete from '@material-ui/core/useAutocomplete';

Hook customizado

Também conhecidos como tags, o usuário pode inserir mais de um valor.

Requisições assíncronas

O componente suporta duas situações de uso assíncronas diferentes:

Carregar ao abrir

Exibe um estado de progresso enquanto a solicitação de rede estiver pendente.

Pesquisar enquanto digita

Se sua lógica é buscar novas opções a cada tecla pressionada e usando o valor atual da caixa de texto para filtrar no servidor, você pode querer considerar a limitação de requisições.

Além disso, você precisará desabilitar a filtragem integrada do componente Autocomplete sobrescrevendo a propriedade filterOptions:

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

Lugares com a API do Google Maps

Uma customização de UI para o autocompletar de lugares do Google Maps.

Para esse exemplo, nós precisamos carregar a API de Javascript do Google Maps.

⚠️ Antes de você começar a usar a API JavaScript do Google Maps você precisará estar cadastrado e ter uma conta.

Múltiplos valores

Também conhecidos como tags, o usuário pode inserir mais de um valor.

Opções fixas

Em ocasiões que você necessite travar certa tag para que não possa ser removida da interface, você pode defini-la como desabilitada.

Caixas de seleção

Limitar tags

Você pode usar a propriedade limitTags para limitrar o número de opções exibidas quando o componente não estiver com o foco.

<Autocomplete
  multiple
  limitTags={2}
  id="multiple-limit-tags"
  options={top100Films}
  getOptionLabel={(option) => option.title}
  defaultValue={[top100Films[13], top100Films[12], top100Films[11]]}
  renderInput={(params) => (
    <TextField {...params} label="limitTags" placeholder="Favorites" />
  )}
/>

Tamanhos

Gosta mais de campos de texto menores? Use a propriedade size.

Customização

Input customizado

A propriedade renderInput permite que você customize o input renderizado. O primeiro argumento desta propriedade de render, contém propriedades que você precisa encaminhar. Preste atenção específicamente nas chaves ref e inputProps.

Seletor do GitHub

Esta demonstração reproduz o rótulo de seleção do GitHub's:

help wanted
type: bug

Va para a seção Hook customizado para um exemplo com o uso do hook customizado useAutocomplete ao invés do componente.

Realce

A demonstração a seguir dependem do autosuggest-highlight, um utilitário pequeno (1 kB) para realçar textos nos componentes autosuggest e autocomplete.

Filtro customizado

O componente expõe uma fábrica para criar um método de filtro que pode ser fornecido para a propriedade filterOptions. Você pode usar ela para modificar o comportamento padrão do filtro.

import { createFilterOptions } from '@material-ui/core/Autocomplete';

createFilterOptions(config) => filterOptions

Argumentos

  1. config (Object [opcional]):
  • config.ignoreAccents (Boolean [opcional]): Padrão true. Remover sinais diacríticos.
  • config.ignoreCase (Boolean [opcional]): Padrão true. Minúsculas em tudo.
  • config.limit (Number [opcional]): Padrão null. Limitar o número de opções sugeridas a serem exibidas. Por exemplo, se config.limit é 100, somente as primeiras 100 opções correspondentes são exibidas. Isto pode ser útil se um monte corresponderem e a virtualização não estiver configurada.
  • config.matchFrom ('any' | 'start' [opcional]): Padrão 'any'.
  • config.stringify (Func [opcional]): Controla a forma como a opção é convertida em texto, dessa forma pode ser comparada com qualquer fragmento de texto.
  • config.trim (Boolean [opcional]): Padrão false. Remover espaços ao fim.

Retornos

filterOptions: o método de filtro retornado pode ser fornecido diretamente para a propriedade filterOptions do componente Autocomplete ou para o parâmetro de mesmo nome no hook.

Na demonstração a seguir, as opções necessárias para o filtro ser aplicado no inicio das opções:

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

<Autocomplete filterOptions={filterOptions} />;

Avançado

Para mecanismos de filtragem mais ricos, como correspondência difusa, recomenda-se explorar o match-sorter. Por exemplo:

import matchSorter from 'match-sorter';

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

<Autocomplete filterOptions={filterOptions} />;

Virtualização

Pesquise dentro de 10.000 opções geradas aleatoriamente. A lista é virtualizada graças a react-window.

<Autocomplete
  id="virtualize-demo"
  style={{ width: 300 }}
  disableListWrap
  classes={classes}
  ListboxComponent={ListboxComponent}
  renderGroup={renderGroup}
  options={OPTIONS}
  groupBy={(option) => option[0].toUpperCase()}
  renderInput={(params) => <TextField {...params} label="10,000 options" />}
  renderOption={(props, option) => (
    <li {...props}>
      <Typography noWrap>{option}</Typography>
    </li>
  )}
/>

Eventos

Se você deseja evitar o comportamento padrão do teclado, você pode definir a propriedade defaultMuiPrevented para true:

<Autocomplete
  onKeyDown={(event) => {
    if (event.key === 'Enter') {
      // Previne o comportamento padrão do 'Enter'.
      event.defaultMuiPrevented = false;
      // seu código manipulador
    }
  }}
/>

Limitações

autocomplete/autofill

Os navegadores têm heurística para ajudar os usuários a preencherem os campos do formulário. No entanto, isso pode prejudicar a experiência do usuário com o componente.

Por padrão, o componente desabilita o recurso de autocomplete (recurso que memoriza informações que o usuário forneceu em sessões anteriores) com o atributo autoComplete="off". Atualmente, o Google Chrome não suporta essa configuração de atributo (Issue 587466). Uma solução alternativa possível é remover o id para que o componente gere um aleatório.

No entanto, além de relembrar valores fornecidos anteriormente, o navegador também pode propor sugestões de autofill (preenchimento automático para informações de login, endereço ou detalhes de pagamento). No caso de você querer evitar o recurso de preenchimento automático, tente o seguinte:

  • Nomeie o campo sem fornecer informações para o navegador do que ele representa. id="field1" ao invés de id="country". Se você deixar o id do vazio, o componente utiliza um id aleatório.

  • Defina autoComplete="new-password" (alguns navegadores irão sugerir uma senha forte para entradas com esta configuração de atributo):

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

Leia este guia na MDN para mais detalhes.

iOS VoiceOver

VoiceOver no Safari do iOS não suporta o atributo aria-owns muito bem. Você pode contornar o problema com a propriedade disablePortal.

ListboxComponent

Se você fornecer um componente customizado na propriedade ListboxComponent, você precisará certificar-se de que o contêiner de scroll esteja com o atributo role definido como listbox. Isto garante o comportamento correto do scroll, por exemplo, quando utilizar o teclado para navegar.

Acessibilidade

(WAI-ARIA: https://www.w3.org/TR/wai-aria-practices/#combobox)

Incentivamos a utilização de um rótulo para a caixa de texto. O componente implementa as práticas de autoria da WAI-ARIA.