Skip to content

MeAutocomplete

Campo de busca com autocomplete assíncrono. Suporta dois modos: searchFn (componente gerencia debounce e loading) e controlado (pai fornece :options e :loading). O texto digitado persiste ao fechar o dropdown — padrão Combobox.

Playground

Importação

vue
<script setup>
import { MeAutocomplete } from '@me/ui-vue3'
import type { AutocompleteOption } from '@me/ui-vue3'
</script>
vue
<script>
import { MeAutocomplete } from '@me/ui-vue2'

export default {
  components: { MeAutocomplete }
}
</script>

Uso Básico — Modo searchFn

Dados de exemplo

Nos demos abaixo, digite Alpha, Beta ou Gamma (ou apenas Empresa) para ver resultados.

Passe uma função assíncrona via :search-fn. O componente gerencia debounce (padrão 800 ms) e exibe o spinner de loading automaticamente.

vue
<script setup>
import { ref } from 'vue'
import { MeAutocomplete } from '@me/ui-vue3'
import type { AutocompleteOption } from '@me/ui-vue3'

const cnpj = ref(null)

async function buscarEmpresas(term: string): Promise<AutocompleteOption[]> {
  const { data } = await api.get('/company/search', { params: { term } })
  return data.map((c) => ({
    label: `${c.cnpj} - ${c.name}`,
    value: c.cnpj,
    data: c,
  }))
}
</script>

<template>
  <MeAutocomplete
    v-model="cnpj"
    :search-fn="buscarEmpresas"
    label="CNPJ da empresa"
    placeholder="Digite o CNPJ ou nome"
  />
</template>

Modo Controlado

Dados de exemplo

Digite Alpha, Beta ou Gamma (ou apenas Empresa) para ver resultados.

O pai é responsável por buscar e atualizar :options. O componente emite @search quando o usuário digita um termo válido.

vue
<script setup>
import { ref } from 'vue'
import { MeAutocomplete } from '@me/ui-vue3'
import type { AutocompleteOption } from '@me/ui-vue3'

const value   = ref(null)
const options = ref<AutocompleteOption[]>([])
const loading = ref(false)

async function handleSearch(term: string) {
  if (!term) { options.value = []; return }
  loading.value = true
  const { data } = await api.get('/search', { params: { term } })
  options.value = data.map((item) => ({ label: item.name, value: item.id }))
  loading.value = false
}
</script>

<template>
  <MeAutocomplete
    v-model="value"
    :options="options"
    :loading="loading"
    label="Buscar empresa"
    @search="handleSearch"
  />
</template>

Com Label e Obrigatório

Dados de exemplo

Digite Alpha, Beta ou Gamma (ou apenas Empresa) para ver resultados.

Use label para exibir um rótulo e :mandatory="true" para adicionar o asterisco de campo obrigatório.

vue
<MeAutocomplete
  v-model="value"
  :search-fn="buscar"
  label="CNPJ da empresa"
  :mandatory="true"
/>

Validação de mínimo de caracteres

Dados de exemplo

Digite Alpha, Beta ou Gamma (ou apenas Empresa) para ver resultados.

Quando minChars é definido, o componente exibe automaticamente uma mensagem de erro enquanto o usuário digita menos que o mínimo — sem nenhuma prop extra.

vue
<MeAutocomplete
  v-model="value"
  :search-fn="buscar"
  label="Buscar empresa"
  :min-chars="4"
/>
<!-- Digitar 1–3 chars exibe automaticamente: "É preciso no mínimo 4 caracteres." -->

Com Mensagem de Erro

Dados de exemplo

Digite Alpha, Beta ou Gamma (ou apenas Empresa) para ver resultados.

Use error-message para exibir um erro customizado. Ele tem prioridade sobre a mensagem automática de minChars.

CNPJ inválido ou não encontrado
vue
<MeAutocomplete
  v-model="value"
  :search-fn="buscar"
  label="CNPJ"
  error-message="CNPJ inválido ou não encontrado"
/>

Máscara

Dados de exemplo

Digite Alpha, Beta ou Gamma (ou apenas Empresa) para ver resultados por nome, ou comece com dígitos para testar a máscara.

Use a prop mask para formatar o input automaticamente. O padrão é uma string onde X representa um dígito e os demais caracteres são separadores literais inseridos automaticamente.

A máscara só é aplicada quando o usuário digita apenas dígitos — ao digitar letras (ex: busca por nome de empresa), o campo funciona livremente.

vue
<!-- CNPJ -->
<MeAutocomplete
  v-model="cnpj"
  :search-fn="buscar"
  label="CNPJ"
  mask="XX.XXX.XXX/XXXX-XX"
  :min-chars="4"
/>

<!-- CPF -->
<MeAutocomplete
  v-model="cpf"
  :search-fn="buscar"
  label="CPF"
  mask="XXX.XXX.XXX-XX"
  :min-chars="4"
/>

Variante Visual

Use variant para controlar o comportamento de foco do campo.

  • light (padrão): foco destacado com sombra ocean (teal) no wrapper.
  • dark: foco destacado com sombra escura (neutra) no wrapper — sem a cor verde/teal.

Dados de exemplo

Digite Alpha, Beta ou Gamma (ou apenas Empresa) para ver resultados.

vue
<!-- light (padrão) — sombra no wrapper ao focar -->
<MeAutocomplete v-model="value" :search-fn="buscar" variant="light" />

<!-- dark — foco via focus-visible no input -->
<MeAutocomplete v-model="value" :search-fn="buscar" variant="dark" />

Disabled

vue
<MeAutocomplete
  v-model="value"
  :search-fn="buscar"
  label="Campo desabilitado"
  :disabled="true"
/>

Sem botão de limpar

Dados de exemplo

Digite Alpha, Beta ou Gamma (ou apenas Empresa) para ver resultados.

vue
<MeAutocomplete
  v-model="value"
  :search-fn="buscar"
  :clearable="false"
/>

Eventos

Dados de exemplo

Digite Alpha, Beta ou Gamma (ou apenas Empresa) para ver resultados.

Último evento: Nenhum

vue
<script setup>
import { ref } from 'vue'

const value     = ref(null)
const lastEvent = ref('Nenhum')
</script>

<template>
  <MeAutocomplete
    v-model="value"
    :search-fn="buscar"
    label="Empresa"
    @select="(opt) => lastEvent = opt ? `select: ${opt.label}` : 'select: null'"
    @clear="lastEvent = 'clear'"
    @focus="lastEvent = 'focus'"
    @blur="lastEvent = 'blur'"
  />
  <p>Último evento: <strong>{{ lastEvent }}</strong></p>
</template>

API

Props

PropTipoPadrãoDescrição
modelValuestring | number | nullnullValor selecionado — use com v-model
searchFn(term: string) => Promise<AutocompleteOption[]>Modo searchFn: função de busca assíncrona. O componente gerencia debounce e loading.
debouncenumber800Delay do debounce em ms. Apenas no modo searchFn.
optionsAutocompleteOption[][]Modo controlado: opções fornecidas pelo pai.
loadingbooleanfalseModo controlado: estado de loading externo.
labelstringTexto do label exibido acima do campo.
placeholderstring'Buscar...'Placeholder do input.
disabledbooleanfalseDesabilita o campo.
mandatorybooleanfalseExibe asterisco de obrigatório no label.
minCharsnumber3Mínimo de caracteres para disparar a busca. Enquanto abaixo do mínimo, exibe automaticamente "É preciso no mínimo N caracteres."
errorMessagestringMensagem de erro customizada. Tem prioridade sobre a mensagem automática de minChars.
noResultsTextstring'Nenhum resultado encontrado'Texto exibido no dropdown quando não há resultados.
clearablebooleantrueExibe botão para limpar o campo.
variant'light' | 'dark''light'Variante visual do foco. light: sombra ocean (teal) no wrapper. dark: sombra escura no wrapper, sem a cor verde/teal.
maskstringPadrão de máscara aplicado quando o usuário digita apenas dígitos. Use X para cada dígito e outros chars como separadores literais. Ex: 'XX.XXX.XXX/XXXX-XX' (CNPJ), 'XXX.XXX.XXX-XX' (CPF).

Tipo AutocompleteOption

ts
type AutocompleteOption<D = unknown> = {
  label: string          // Texto exibido no dropdown e no input após seleção
  value: string | number // Valor emitido no v-model ao selecionar
  data?: D               // Payload arbitrário acessível no evento @select
  disabled?: boolean
}

Eventos

EventoPayloadDescrição
update:modelValuestring | number | nullEmitido ao selecionar ou limpar — use com v-model
searchstringModo controlado: emitido quando o usuário digita um termo válido
selectAutocompleteOption | nullEmitido ao selecionar uma opção ou ao limpar
clearEmitido ao clicar no botão de limpar
focusEmitido ao focar no input
blurEmitido ao perder o foco
openEmitido ao abrir o dropdown
closeEmitido ao fechar o dropdown

Acessibilidade

  • O input possui role="combobox" e aria-haspopup="listbox"
  • aria-expanded reflete o estado do dropdown
  • Cada opção possui role="option" com aria-selected e aria-disabled
  • Opções desabilitadas têm aria-disabled="true"
TeclaAção
ArrowDownMove o foco para a próxima opção (pula desabilitadas)
ArrowUpMove o foco para a opção anterior (pula desabilitadas)
EnterSeleciona a opção com foco
EscapeFecha o dropdown mantendo o texto digitado
TabFecha o dropdown e avança o foco normalmente

Posicionamento inteligente

O MeAutocomplete detecta automaticamente o espaço disponível na viewport e abre o dropdown para cima quando não há espaço suficiente abaixo.