auto complete

This commit is contained in:
Luiz Silva 2026-07-13 14:53:47 -03:00
parent 642ccf4c1a
commit 1ee3b2d207
9 changed files with 2166 additions and 2163 deletions

View file

@ -1,5 +1,5 @@
<template>
<v-select
<v-autocomplete
v-model="localValue"
:label="opcoes?.rotulo"
:placeholder="opcoes?.placeholder"
@ -18,6 +18,9 @@
:density="opcoes?.densidade ?? 'comfortable'"
:variant="opcoes?.variante ?? 'outlined'"
:readonly="Boolean(opcoes?.apenasLeitura)"
:custom-filter="filtroSelecao"
auto-select-first
no-data-text="Nenhum resultado encontrado"
v-bind="attrs"
@focus="() => emit('focus')"
@blur="() => emit('blur')"
@ -26,15 +29,16 @@
<script lang="ts">
import { computed, defineComponent, onMounted, type PropType, ref, watch } from "vue"
import { VSelect } from "vuetify/components"
import { VAutocomplete } from "vuetify/components"
import type { PadroesEntradas } from "./tiposEntradas"
import { filtroSelecao } from "./utils/filtroSelecao"
type EntradaSelecao = PadroesEntradas["selecao"]
type ItemSelecao = { chave: string; rotulo: string }
export default defineComponent({
name: "EliEntradaSelecao",
components: { VSelect },
components: { VAutocomplete },
inheritAttrs: false,
props: {
value: {
@ -109,7 +113,7 @@ export default defineComponent({
return (item: ItemSelecao) => ({ disabled: desativados.includes(item.chave) })
})
return { attrs, emit, localValue, itens, carregando, itemProps }
return { attrs, emit, localValue, itens, carregando, itemProps, filtroSelecao }
},
})
</script>

View file

@ -1,5 +1,5 @@
<template>
<v-select
<v-autocomplete
v-model="localValue"
:label="opcoes?.rotulo"
:placeholder="opcoes?.placeholder"
@ -20,6 +20,8 @@
multiple
chips
closable-chips
:custom-filter="filtroSelecao"
no-data-text="Nenhum resultado encontrado"
:readonly="Boolean(opcoes?.apenasLeitura)"
v-bind="attrs"
@focus="() => emit('focus')"
@ -29,15 +31,16 @@
<script lang="ts">
import { computed, defineComponent, onMounted, type PropType, ref, watch } from "vue"
import { VSelect } from "vuetify/components"
import { VAutocomplete } from "vuetify/components"
import type { PadroesEntradas } from "./tiposEntradas"
import { filtroSelecao } from "./utils/filtroSelecao"
type EntradaSelecaoMultipla = PadroesEntradas["selecaoMultipla"]
type ItemSelecao = { chave: string; rotulo: string }
export default defineComponent({
name: "EliEntradaSelecaoMultipla",
components: { VSelect },
components: { VAutocomplete },
inheritAttrs: false,
props: {
value: {
@ -98,7 +101,7 @@ export default defineComponent({
return (item: ItemSelecao) => ({ disabled: desativados.includes(item.chave) })
})
return { attrs, emit, localValue, itens, carregando, itemProps }
return { attrs, emit, localValue, itens, carregando, itemProps, filtroSelecao }
},
})
</script>

View file

@ -0,0 +1,27 @@
/**
* Utilitário de filtragem para os componentes de seleção (EliEntradaSelecao e EliEntradaSelecaoMultipla).
*
* Normaliza a string removendo acentos e convertendo para minúsculas antes de comparar,
* garantindo que "São Paulo" seja encontrado digitando "sao paulo" ou "SÃO PAULO".
*/
/** Remove acentos e converte para minúsculas para comparação insensível. */
function normalizar(texto: string): string {
return texto
.normalize("NFD") // decompõe caracteres acentuados (ex: "ã" → "a" + diacrítico)
.replace(/\p{Diacritic}/gu, "") // remove os diacríticos
.toLowerCase()
}
/**
* Função de filtro customizada para v-autocomplete do Vuetify.
*
* Vuetify passa (value, query, item):
* - `value` → texto do item renderizado (item-title resolvido)
* - `query` → texto digitado pelo usuário
* - `item` → objeto completo do item (não usado aqui)
*/
export function filtroSelecao(value: string, query: string): boolean {
if (!query) return true
return normalizar(value).includes(normalizar(query))
}