vue-componentes/.agent/memoria/adr-001-comportamento-inputs-decimais.md

2.6 KiB

ADR 001: Comportamento de Entradas Decimais (Fixed Point vs Modo Livre)

Contexto

A manipulação de valores numéricos fracionários (monetários, quantidades) por meio de um v-text-field frequentemente esbarra em limitações de UX e sincronização entre value (tipo numérico) e displayValue (string amigável localizada - vírgula no Brasil).

Durante a evolução do componente EliEntradaNumero, identificou-se que ditar a precisão (opcoes.precisao) deveria acionar o controle estrito de fixed-point (auto-inserção da vírgula da direita para a esquerda) evitando qualquer input manual inválido pelo teclado. Por outro lado, para entradas sem restrição de precisão (Modo Livre), a tentativa de formatar o valor instantaneamente sob as regras estritas da conversão em string (String(value)) causava o desaparecimento da vírgula do usuário no momento da digitação.

Exemplo de Falha:

  • Usuário digita "1" -> Display: "1" / Valor Interno: 1
  • Usuário digita "," -> Display formata o valor 1 -> Resultado: "1". A vírgula some.

Decisão

Adotou-se o seguinte padrão para o comportamento bidirecional do Input Numérico Decimal:

  1. Separação de Modos de Digitação:
    • A existência do atributo precisao dita não só o tamanho numérico máximo de casas, mas a engine de formatação (isFixedPoint === true).
    • Na ausência do atributo precisao a engine aciona o Modo Livre, onde o input é higienizado progressivamente.
  2. Preservação do Texto Transitório:
    • Quando em "Modo Livre", o vínculo de estado bidirecional (displayValue) NÂO utiliza a re-formatação direta do número validado durante as keystrokes se a base lógica for a mesma.
    • Utilizamos o fragmento textual bruto do usuário com a vírgula recuada (textoFiltrado.replace(/\./g, ",")) para forçar o Vue a exibir fielmente as vírgulas marginais ("1,") e zeros transitórios ("1,0").
  3. Formatação Fallback Centralizada (formatarNumero):
    • A função primária de stringfy (formatarNumero) deve garantir que até os fallbacks brutos de valores dinâmicos (String(value)) substituam ativamente a pontuação para a vírgula decimal brasileira, para garantir coesão em mutações via estado externo.

Impacto

Este padrão resolve conflitos generalizados onde campos numéricos em modo livre (sem padding automático via toFixed) apagavam preenchimentos parciais e tornavam a navegação manual hostil. Ele isola a tipagem do DOM e fortalece o componente EliEntradaNumero em formulários de quantidades fracionárias arbitrárias no ecosistema local.