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: combo box.
  2. A caixa de texto pode conter qualquer valor arbitrário, mas é vantajoso 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: solo livre.

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

Combo box

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

<Autocomplete
  id="combo-box-demo"
  options={top100Films}
  getOptionLabel={(option) => option.title}
  style={{ width: 300 }}
  renderInput={(params) => <TextField {...params} label="Combo box" variant="outlined" />}
/>

Área de exemplos

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

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.
  2. o estado "input value" com a combinação das propriedades inputValue/onInputChange.

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

Free solo

Coloque freeSolo como true para que o textbox contenha qualquer valor aleatório. Essa prop é focada em cobrir o principal caso de uso que é seria uma caixa de pesquisas com sugestões, e.g. Google search.

Entretanto, se você gostaria de usá-lo para trazer ao usuário a experiência de um combo box (equivalente a um select aprimorado) nós recomendamos passar selectOnFocus (isso ajuda o usuário limpando o valor selecionado).

Mensagem de ajuda

Às vezes você quer tornar explícito ao usuário que ele pode adicionar qualquer valor que ele/ela quiser. O exemplo a seguir adiciona a última opção: Adicionar "SUA PESQUISA".

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

Agrupamento

<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" variant="outlined" />}
/>

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" variant="outlined" />
  )}
/>

useAutocomplete

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

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

Hook customizado

Indo para a seção de Autocompletar customizado vemos um exemplo de customização com o componente Autocompletar ao invés do hook.

Requisições assíncronas

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.

<Autocomplete
  multiple
  id="fixed-tags-demo"
  options={top100Films}
  getOptionLabel={(option) => option.title}
  defaultValue={[top100Films[6], top100Films[13]]}
  renderTags={(value, getTagProps) =>
    value.map((option, index) => (
      <Chip label={option.title} {...getTagProps({ index })} disabled={index === 0} />
    ))
  }
  style={{ width: 500 }}
  renderInput={(params) => (
    <TextField {...params} label="Fixed tag" variant="outlined" placeholder="Favorites" />
  )}
/>

Caixas de Seleção

Limitar tags

Você pode usar a propriedade limitTags para limitrar o nuú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} variant="outlined" label="limitTags" placeholder="Favorites" />
  )}
/>

Tamanhos

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

Autocompletar personalizado

Esta demonstração reproduz o rótulo de selecã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 depende 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 filerOption. Você pode usar ela para modificar o comportamento padão do filtro.

import { createFilterOptions } from '@material-ui/lab/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.startAfter(Number [opcional]): Padrão 0. Exibe as opções sugeridas somente depois de um certo número de letras.
    • 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 necessarias 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} variant="outlined" label="10,000 options" />}
  renderOption={(option) => <Typography noWrap>{option}</Typography>}
/>

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".

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. ex. 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":
      jsx
      <TextField
      {...params}
      inputProps={{
        ...params.inputProps,
        autoComplete: 'new-password',
      }}
      />

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.

TypeScript

Para tirar o máximo de proveito da inferência de tipos, você precisa definir a propriedade multiple para undefined, false ou true. Veja esta discussão para maiores detalhes. TypeScript poderá resolver este problema no futuro.

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.