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:
- 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.
- 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" />}
/>
Estrutura das opções
Por padrão, o componente aceita as seguintes estruturas de opções:
interface AutocompleteOption {
label: string;
}
// ou
type AutocompleteOption = string;
por exemplo:
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 um prop getOptionLabel
.
Área de exemplos
Cada um dos exemplos a seguir demonstra uma funcionalidade do componente Autocomplete.
Estados controláveis
O componente tem dois estados que podem ser controlados:
- o estado "value" com a combinação das propriedades
value
/onChange
. Esse estado representa o valor selecionado pelo usuário, por exemplo, quando pressionando Enter. - 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.
Free solo
Coloque freeSolo
como true para que o campo de texto contenha qualquer valor aleatório.
Campo search
A propriedade é projetada para cobrir o principal caso de uso de uma caixa de pesquisa com sugestões, por exemplo, pesquisa do Google ou react-autowhatever.
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 o prop 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" />}
/>
<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';
Vá para a seção de customização para um exemplo com o componente Autocomplete
em vez do hook.
Requisições assíncronas
O componente suporta duas situações de uso assíncronas diferentes:
- Carregar ao abrir: espera uma interação com o componente para carregar as opções.
- Pesquisar enquanto digita: um novo pedido é feito para cada tecla pressionada.
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 o prop 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.
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" />
)}
/>
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
.
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
config
(Object [opcional]):
config.ignoreAccents
(Boolean [opcional]): Padrãotrue
. Remover sinais diacríticos.config.ignoreCase
(Boolean [opcional]): Padrãotrue
. Minúsculas em tudo.config.limit
(Number [opcional]): Padrão null. Limitar o número de opções sugeridas a serem exibidas. Por exemplo, seconfig.limit
é100
, somente as primeiras100
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 para texto para poder ser comparada com qualquer fragmento de texto de entrada.config.trim
(Boolean [opcional]): Padrãofalse
. 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 do evento 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 deid="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.