vue-componentes/src/componentes/EliEntrada/EliEntradaTexto.vue

101 lines
2.8 KiB
Vue

<template>
<v-text-field
v-model="localValue"
:type="inputHtmlType"
:inputmode="inputMode"
:label="opcoes?.rotulo"
:placeholder="opcoes?.placeholder"
:counter="opcoes?.limiteCaracteres"
:maxlength="opcoes?.limiteCaracteres"
v-bind="attrs"
@focus="() => emit('focus')"
@blur="() => emit('blur')"
@input="onInput"
/>
</template>
<script lang="ts">
import { computed, defineComponent, PropType } from "vue";
import type { PadroesEntradas } from "./tiposEntradas";
import { formatarCpfCnpj } from "./utils/cpfCnpj";
import { formatTelefone } from "./utils/telefone";
import { formatarCep } from "./utils/cep";
type EntradaTexto = PadroesEntradas["texto"];
export default defineComponent({
name: "EliEntradaTexto",
inheritAttrs: false,
props: {
/** Interface padrão (EliEntrada): value + opcoes. */
value: {
type: [String, null] as unknown as PropType<EntradaTexto["value"]>,
default: undefined,
},
opcoes: {
type: Object as PropType<EntradaTexto["opcoes"]>,
required: true,
},
},
emits: {
"update:value": (_v: EntradaTexto["value"]) => true,
/** Compat Vue2 (v-model padrão: value + input) */
input: (_v: EntradaTexto["value"]) => true,
change: (_v: EntradaTexto["value"]) => true,
focus: () => true,
blur: () => true,
},
setup(props, { attrs, emit }) {
const formato = computed(() => props.opcoes?.formato ?? "texto");
const localValue = computed<EntradaTexto["value"]>({
get: () => props.value,
set: (v) => {
emit("update:value", v);
emit("input", v);
emit("change", v);
},
});
const inputHtmlType = computed(() => {
if (formato.value === "email") return "email";
if (formato.value === "url") return "url";
return "text";
});
const inputMode = computed<string | undefined>(() => {
if (formato.value === "telefone") return "tel";
if (formato.value === "cpfCnpj" || formato.value === "cep") return "numeric";
return undefined;
});
function aplicarFormato(valor: string) {
switch (formato.value) {
case "telefone":
return formatTelefone(valor);
case "cpfCnpj":
return formatarCpfCnpj(valor);
case "cep":
return formatarCep(valor);
default:
return valor;
}
}
function onInput(e: Event) {
const target = e.target as HTMLInputElement;
const resultado = aplicarFormato(target.value);
// garante que o input mostre o valor formatado
target.value = resultado;
// regra do projeto: value sempre igual ao que aparece
localValue.value = resultado;
}
return { attrs, emit, localValue, inputHtmlType, inputMode, onInput };
},
});
</script>
<style scoped></style>