137 lines
3.1 KiB
Vue
137 lines
3.1 KiB
Vue
<template>
|
|
<div class="eli-tabela__busca">
|
|
<div class="eli-tabela__busca-input-wrapper">
|
|
<input
|
|
id="eli-tabela-busca"
|
|
v-model="texto"
|
|
type="search"
|
|
class="eli-tabela__busca-input"
|
|
placeholder="Digite termos para filtrar"
|
|
@keyup.enter="emitirBusca"
|
|
/>
|
|
<button
|
|
type="button"
|
|
class="eli-tabela__busca-botao"
|
|
aria-label="Buscar"
|
|
title="Buscar"
|
|
@click="emitirBusca"
|
|
>
|
|
<Search class="eli-tabela__busca-botao-icone" :size="16" :stroke-width="2" aria-hidden="true" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { Search } from "@lucide/vue"
|
|
import { defineComponent, ref, watch } from "vue"
|
|
|
|
export default defineComponent({
|
|
name: "EliTabelaCaixaDeBusca",
|
|
components: { Search },
|
|
props: {
|
|
modelo: {
|
|
type: String,
|
|
required: false,
|
|
default: "",
|
|
},
|
|
},
|
|
emits: {
|
|
buscar(valor: string) {
|
|
return typeof valor === "string"
|
|
},
|
|
},
|
|
setup(props, { emit }) {
|
|
/**
|
|
* Estado local da entrada para que o usuário possa digitar livremente antes
|
|
* de disparar uma nova consulta.
|
|
*/
|
|
const texto = ref(props.modelo ?? "")
|
|
|
|
watch(
|
|
() => props.modelo,
|
|
(novo) => {
|
|
if (novo !== undefined && novo !== texto.value) {
|
|
texto.value = novo
|
|
}
|
|
},
|
|
)
|
|
|
|
function emitirBusca() {
|
|
emit("buscar", texto.value.trim())
|
|
}
|
|
|
|
return { texto, emitirBusca }
|
|
},
|
|
})
|
|
</script>
|
|
|
|
<style>
|
|
.eli-tabela__busca {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
gap: 8px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
|
|
.eli-tabela__busca-input-wrapper {
|
|
display: inline-flex;
|
|
align-items: stretch;
|
|
border-radius: var(--eli-tabela-cabecalho-controle-radius, 8px);
|
|
border: 1px solid rgba(15, 23, 42, 0.15);
|
|
overflow: hidden;
|
|
background: var(--cor-eli-superficie);
|
|
|
|
/* Herda do container do cabeçalho (.eli-tabela__cabecalho) quando presente. */
|
|
height: var(--eli-tabela-cabecalho-controle-altura, 34px);
|
|
}
|
|
|
|
.eli-tabela__busca-input {
|
|
/* Mantém o input com a mesma altura do botão e dos botões de ação do cabeçalho. */
|
|
height: 100%;
|
|
padding: 0 12px;
|
|
border: none;
|
|
outline: none;
|
|
font-size: 0.875rem;
|
|
color: rgba(15, 23, 42, 0.85);
|
|
}
|
|
|
|
.eli-tabela__busca-input::-webkit-search-cancel-button,
|
|
.eli-tabela__busca-input::-webkit-search-decoration {
|
|
-webkit-appearance: none;
|
|
}
|
|
|
|
.eli-tabela__busca-input::placeholder {
|
|
color: var(--cor-eli-neutro);
|
|
}
|
|
|
|
.eli-tabela__busca-botao {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border: none;
|
|
background: var(--cor-eli-primaria-bg);
|
|
color: var(--cor-eli-primaria-escura);
|
|
height: 100%;
|
|
padding: 0 12px;
|
|
cursor: pointer;
|
|
transition: background-color 0.2s ease, color 0.2s ease;
|
|
}
|
|
|
|
.eli-tabela__busca-botao-icone {
|
|
display: block;
|
|
}
|
|
|
|
.eli-tabela__busca-botao:hover,
|
|
.eli-tabela__busca-botao:focus-visible {
|
|
background: var(--cor-eli-primaria-clara);
|
|
color: var(--cor-eli-primaria-escura);
|
|
}
|
|
|
|
.eli-tabela__busca-botao:focus-visible {
|
|
outline: 2px solid var(--cor-eli-primaria-clara);
|
|
outline-offset: 2px;
|
|
}
|
|
</style>
|