# Masked Input

Formatted number field for phone, card, expiry, date, currency or custom patterns. It formats as you type, shows the card network, refuses keys it can’t take and checks the value when you’re done.

> Primitive · Pro · Forms & Inputs — React Native, Expo Go compatible.

## Install

```bash
npx @lumioui/cli add pro/masked-input
```

## Import

```tsx
import { applyMask, detectCardBrand, luhnValid, cvcLength, MaskedInput } from "@/components/ui/masked-input/masked-input";
```

## Variants

- `transfer` — Send money: `npx @lumioui/cli add pro/masked-input-transfer`

## Props

| Prop | Type | Notes |
| --- | --- | --- |
| `value?` | `string` | Formatted value (controlled). |
| `defaultValue?` | `string` | Initial value (uncontrolled) — digits or formatted. |
| `onChangeText?` | `(raw: string, formatted: string) => void` | Called with (raw digits, formatted). |
| `onComplete?` | `(raw: string, formatted: string) => void` | Fires once when the last slot of the mask fills. |
| `mask?` | `string` | Custom mask — `#` marks a digit slot. Overrides `preset`. |
| `preset?` | `MaskPreset` | Built-in format. Default "phone". |
| `currencySymbol?` | `string` | Currency symbol prefix. Default "$". |
| `ghost?` | `boolean` | Show the empty format as dim ghost slots. Default true (not for  currency or secure entry). |
| `validate?` | `boolean | ((raw: string, formatted: string) => string | undefined)` | Check the value on blur. `true` (default) uses the preset's rules; a  function returns a message for a bad value; `false` turns it off. |
| `onBrandChange?` | `(brand: CardBrand) => void` | Card preset: fires when the detected network changes. |
| `showBrand?` | `boolean` | Card preset: show the network mark at the right edge. Default true. |
| `size?` | `"md" | "lg"` | "md" 48pt field (default) or "lg" 64pt with a larger figure. |
| `label?` | `string` | — |
| `helperText?` | `string` | — |
| `error?` | `string` | Error message from outside — wins over the built-in check. |
| `success?` | `boolean` | Shows a drawn check at the right edge (suppressed while an error shows). |
| `reserveHelperLine?` | `boolean` | Reserve one message line even when empty — no layout shift on error. |
| `className?` | `string` | — |
| `inputClassName?` | `string` | — |

Source: https://lumioui.com/components/masked-input