# MaskedInput

Campo com mascara guiada por molde: `9` e digito, `A` e letra, `*` e os dois, e
o resto e literal que a mascara poe sozinha.

Moldes prontos: `cpf`, `cnpj`, `cep`, `telefone`, `data`, `hora`, `placa`,
`cartao` e `moeda`. Aceita molde escrito na mao, como `99-99/9999`.

`onValueChange` entrega o texto pontuado e o cru. **Guarde o cru**: a pontuacao
muda com o tempo e o dado deixa de bater. O dinheiro sai também em centavos, por
`toCents()`, para o servidor receber inteiro em vez de ponto flutuante.

O telefone troca de molde entre o fixo e o celular sozinho.

## Os nove moldes

| Nome | Molde | Sai como |
|---|---|---|
| `cpf` | `999.999.999-99` | `123.456.789-01` |
| `cnpj` | `99.999.999/9999-99` | `12.345.678/0001-90` |
| `cep` | `99999-999` | `58000-000` |
| `telefone` | `(99) 99999-9999` | `(83) 99999-1234` |
| `data` | `99/99/9999` | `05/08/2026` |
| `hora` | `99:99` | `14:30` |
| `placa` | `AAA9A99` | `ABC1D23` |
| `cartao` | `9999 9999 9999 9999` | `4111 1111 1111 1111` |
| `moeda` | - | `2.480,00` |

`moeda` é o único sem molde: em dinheiro os centavos vêm primeiro e a casa anda
para a esquerda a cada dígito, o contrário de todo o resto. Os oito primeiros
vivem em `MASKS`, e `MaskName` é o nome de um deles. O tipo `Mask` da prop
aceita esse nome, `moeda`, ou um molde escrito à mão.

Nome de molde digitado errado não vira molde literal: `mask="dinheiro"` avisa no
console em desenvolvimento e deixa o texto passar cru, em vez de escrever
"dinheiro" dentro do campo, que foi o que a versão anterior fazia.

## As máscaras fora do campo

A mesma lógica sai como função, para o texto que a tela **mostra** e nunca
recebe digitação: a coluna de CPF de uma tabela, o CNPJ no cabeçalho de um
recibo, o telefone que voltou cru do servidor.

| Função | Para que |
|---|---|
| `applyMask(texto, mask)` | Aplica pelo nome do molde, molde cru ou `moeda` |
| `applyPattern(texto, molde)` | Aplica um molde direto, sem passar pelos nomes |
| `applyCurrencyMask(texto)` | Só o dinheiro, da direita para a esquerda |
| `unmask(texto)` | Tira a pontuação e devolve o que a pessoa digitou |
| `toCents(texto)` | `1.234,56` vira `123456`, sem ponto flutuante no meio |
| `phonePatternFor(texto)` | Diz qual dos dois moldes de telefone o texto pede |

```tsx
<TableCell>{applyMask(cliente.document, 'cnpj')}</TableCell>
```

`phonePatternFor` devolve um molde, e não um texto: o telefone brasileiro tem oito ou
nove casas depois do DDD e o molde muda no meio da digitação, então quem formata
telefone à mão pergunta a ele primeiro e passa a resposta para o `applyPattern`.

## No React Native

Traduz: o `@rivocode/ui-native` exporta `MaskedInput` - o valor é só dígitos; a máscara é do campo, o dado não a carrega. A API não é a mesma do web (no nativo tudo é controlado), e a [tabela de paridade](/react-native) diz o que muda peça a peça.

## Importação

```tsx
import { MaskedInput } from '@rivocode/ui'
```

## Exemplos

### Moldes

```tsx
import { Field, FieldDescription, FieldLabel, MaskedInput, toCents } from '@rivocode/ui'
import { useState } from 'react'

export function Masks() {
  return (
    <div className="flex w-80 flex-col gap-3">
      <Field>
        <FieldLabel>CNPJ</FieldLabel>
        <MaskedInput mask="cnpj" defaultValue="12345678000199" />
      </Field>
      <Field>
        <FieldLabel>Telefone</FieldLabel>
        <MaskedInput mask="telefone" defaultValue="83988112233" />
      </Field>
      <Field>
        <FieldLabel>CEP</FieldLabel>
        <MaskedInput mask="cep" defaultValue="58000000" />
      </Field>
    </div>
  )
}
```

### Dinheiro

```tsx
import { Field, FieldDescription, FieldLabel, MaskedInput, toCents } from '@rivocode/ui'
import { useState } from 'react'

export function Money() {
  const [cents, setCents] = useState(248_000)

  return (
    <div className="w-80">
      <Field>
        <FieldLabel>Valor da nota</FieldLabel>
        <MaskedInput
          mask="moeda"
          defaultValue="248000"
          onValueChange={(masked) => setCents(toCents(masked))}
        />
        <FieldDescription>Vai para o servidor como {cents} centavos.</FieldDescription>
      </Field>
    </div>
  )
}
```

## Props

| Prop | Tipo | Obrigatória | Desde | O que faz |
| --- | --- | --- | --- | --- |
| `mask` | `Mask` | sim | 0.4.0 | Nome de molde pronto, molde escrito na mao, ou `moeda`. |
| `defaultValue` | `string \| (readonly string[] & string)` |  | 0.4.0 | O texto inicial, quando o componente controla o proprio estado. |
| `onValueChange` | `((masked: string, raw: string) => void)` |  | 0.4.0 | Chamado a cada tecla, com o texto mascarado e o cru. |
| `render` | `ComponentRenderFn<HTMLProps, FieldControlState> \| ReactElement<unknown, string \| JSXElementConstructor<any>>` |  | 0.4.0 | Allows you to replace the component's HTML element with a different tag, or compose it with another component. |
| `size` | `"lg" \| "md" \| "sm" \| null` |  | 0.4.0 |  |
| `value` | `string` |  | 0.4.0 | O texto ja com mascara, quando quem usa controla o estado. |

Além dessas: repassa `className`, `style`, `id` e os demais atributos do elemento raiz.

## Ver também

- [Autocomplete](/componentes/autocomplete.md)
- [Calendar](/componentes/calendar.md)
- [Checkbox](/componentes/checkbox.md)
- [CheckboxGroup](/componentes/checkbox-group.md)
- [ColorPicker](/componentes/color-picker.md)
- [Combobox](/componentes/combobox.md)
- [Convenções da biblioteca](/convencoes.md): Provider, tokens e as regras que valem para toda peça
- [Índice completo](/llms.txt)
