Data input masks

mandatory

Máscaras de apresentação para os tipos semânticos da Koder Stack — CPF, CNPJ, CEP, telefone, data, dinheiro, percentual. Define a máscara de exibição/entrada de cada tipo, a regra de separação apresentação↔storage (storage sempre normalizado, máscara só na UI), e o comportamento de digitação/colagem. Pareada com `specs/data/field-types.kmd` (storage canônico) e `specs/data/validation.kmd` (regras). Telefone é caso aplicado detalhado em `specs/components/phone-input.kmd`.

Facet Data + Visual. A máscara é apenas apresentação. O valor armazenado é sempre a forma canônica de specs/data/field-types.kmd §R2 (dígitos puros / E.164 / decimal). Regra inviolável: storage nunca contém máscara.

Applicability

Campos de formulário e exibição de valores dos tipos semânticos (field-types.kmd §R2) em qualquer UI Koder — mobiledesktopTVwebCLI. A lógica de mascaramento vive no engines/sdk/koder_kit (headless core + binding por surface, policies/headless-first.kmd); produto não reimplementa máscara local.


R1 — Catálogo de máscaras (BR)

Tipo Máscara de exibição Storage (de field-types.kmd) Largura
cpf 000.000.000-00 11 dígitos 12345678901 fixa
cnpj 00.000.000/0000-00 14 chars 12345678000190 (ver nota) fixa
cep 00000-000 8 dígitos 01310100 fixa
phone (BR) +55 (00) 00000-0000 E.164 +5511912345678 locale (phone-input.kmd)
date (pt-BR) 00/00/0000 (DDMMAAAA) ISO YYYY-MM-DD fixa
date (en-US) 00/00/0000 (MMDDYYYY) ISO YYYY-MM-DD fixa
money (BRL) R$ 0.000,00 (milhar ., decimal ,) decimal minor units + ISO 4217 dinâmica
money (USD) $ 0,000.00 idem dinâmica
percent 00,0% (pt-BR) / 00.0% (en) decimal dinâmica

0 = dígito obrigatório. Máscara de datemoneypercent é locale-aware (specs/i18n/contract.kmd); documento BR (CPFCNPJCEP) tem máscara fixa independente do locale da UI (um CPF é sempre 000.000.000-00).


R2 — Separação apresentação ↔ storage

  1. onChange emite o valor normalizado, nunca o mascarado. O componente

    tira a máscara antes de propagar (mesmo contrato de phone-input.kmd §R3: "Always strip mask before emitting onChange value").

  2. Exibir = aplicar máscara sobre o valor canônico. Ler do storage →

    formatar → mostrar. Nunca armazenar o que foi formatado.

  3. Comparação/igualdade sempre sobre o valor canônico (evita o bug

    123.456.789-0112345678901 de field-types.kmd §R2).


R3 — Comportamento de digitação

  • Máscara aplica ao vivo durante a digitação (o usuário vê 123.456.

    enquanto digita).

  • Caret estável — inserir separador não pode pular o cursor para trás

    (bug clássico de máscara ingênua); o core headless gerencia posição.

  • Colagem normaliza — colar 123.456.789-01 ou 12345678901 resulta no

    mesmo valor canônico; máscara reaplicada na exibição.

  • Backspace sobre separador apaga o dígito anterior, não só o separador.
  • CNPJ alfanumérico (IN RFB 2.229/2024, emissão ≥ 2026-07) — a partir

    da cutover o cnpj aceita letras nas 12 primeiras posições; nesse caso não use inputmode="numeric" (use input de texto com filtro uppercase + alfanumérico). A máscara visual 00.000.000/0000-00 e o storage de 14 chars seguem. Regra normativa completa + algoritmo de dígito verificador em specs/data/cnpj.kmd.

  • Teclado adequadoinputmode="numeric" para CPF/CEP (CNPJ ver nota acima);

    inputmode="decimal" para money/percent; inputmode="tel" para phone (phone-input.kmd §R6).


A máscara não valida — ela formata. Formato completo + correto é responsabilidade de specs/data/validation.kmd (incl. dígitos verificadores de CPFCNPJ). Estados visuais de validade (ícone ✓✗) seguem specs/components/text-fields.kmd e phone-input.kmd §R4. Mensagem de erro vem de specs/errors/user-facing-messages.kmd; a classe é VL (specs/errors/taxonomy.kmd).


R5 — Audit determinístico

data-masks-audit.sh (advisory), via /k-housekeep:

  1. Valor de cpfcnpjcep/phone persistido com caractere de

    máscara → error (viola R2; reflete field-types.kmd §R5.1).

  2. Máscara reimplementada localmente em produto em vez de usar o core do

    koder_kit → warning (headless-first/sdk-first).

  3. onChange propagando valor mascarado → error.
  4. Campo date/money com máscara hard-coded a um locale (sem

    locale-awareness) → warning.


Não-escopo

  • Validação (incl. check-digit) — specs/data/validation.kmd.
  • Storage canônicospecs/data/field-types.kmd.
  • Phone i18n completo (seletor de país, libphonenumber) —

    specs/components/phone-input.kmd.

  • Tema/tokens visuais do campospecs/themes/verge.kmd,

    specs/components/text-fields.kmd.