# ViraStack Mask (full)
> `@virastack/mask` (~1.1.1), type-safe input masking for React Hook Form. Headless: no CSS. Form stores raw values; inputs show formatted values.
## Install
```bash
npm install @virastack/mask
# peers: react, react-dom, react-hook-form
```
Docs: https://virastack.com/mask/docs; Index: https://virastack.com/mask/llms.txt; Repo: https://github.com/virastack/mask
## Critical rules for agents
1. Always pass a React Hook Form `UseFormReturn` as `form`.
2. Schema keys must match form field names.
3. Destructure `rawValue` out before spreading onto ``: `const { rawValue, ...inputProps } = field`.
4. Submit / validate against raw values in the form (unmasked), not display strings.
5. Works with any UI library via prop spread (shadcn Input, Ant Design, Chakra, native).
## Quick start
```tsx
import { useForm } from "react-hook-form"
import { useViraMask } from "@virastack/mask"
function Example() {
const form = useForm<{ phone: string }>()
const { phone } = useViraMask({
form,
schema: { phone: "phone" },
})
const { rawValue, ...inputProps } = phone
return
}
```
## useViraMask(props)
```ts
useViraMask({
form: UseFormReturn
schema: TSchema // MaskSchema
}): MaskFields
```
### Schema entry shapes
- Preset string: `{ phone: "phone" }`
- Options object: `{ amount: { currency: { decimalSeparator: ",", thousandSeparator: ".", symbol: "₺" } } }`
- Preset + override: `{ card: { preset: "card", onCardTypeChange: fn } }`
### MaskField (per schema key)
| Prop | Meaning |
| --- | --- |
| `value` | Formatted display value |
| `rawValue` | Raw value in form state (do not put on DOM) |
| `ref`, `name` | Input ref callback and name |
| `onChange`, `onBlur`, `onFocus`, `onKeyDown` | Handlers (IME composition supported) |
| `onCompositionStart`, `onCompositionEnd` | IME-safe updates |
| `type`, `inputMode`, `autoComplete` | From preset/options |
| `aria-invalid`, `aria-describedby`, `title` | When validation fails |
## MaskPreset strings
`card` | `expiry` | `cvv` | `tckn` | `phone` | `email` | `url` | `username` | `alpha` | `password` | `text` | `currency` | `iban` | `numeric` | `date` | `taxNumber` | `zipCode`
Notes:
- `card`: Luhn; Amex (`34`/`37`) switches to Amex mask; brands via `getCardType` / `onCardTypeChange`: visa, mastercard, amex, troy, unknown
- `cvv`: 3 digits, or 4 when paired card field is Amex (`resolveMask`)
- `iban`: TR display prefix; mod-97 validator
- `tckn`: Turkish national ID algorithm
- `taxNumber`: VKN validator
- `currency`: default EN separators (`.` decimal, `,` thousand); customize via `currency` options
- `date`: `dateFormat` `DMY` | `MDY` | `YMD`
- `phone`: TR-style mask in preset
## Custom mask pattern
In `mask` strings: `9` = digit, `a` = letter, `*` = alphanumeric.
## MaskOptions (selected)
| Option | Role |
| --- | --- |
| `mask` | Pattern string |
| `transform` | `uppercase` \| `lowercase` |
| `allowedChars` / `forbiddenChars` | RegExp filters |
| `currency` | `{ precision, decimalSeparator, thousandSeparator, symbol, symbolPosition }` |
| `placeholderChar` | Mask placeholder |
| `inputMode`, `type`, `autoComplete` | Input attrs |
| `validate`, `validator` | `true` + built-in or custom `(value) => boolean` |
| `errorMessage` | Validation message |
| `dateFormat` | `DMY` \| `MDY` \| `YMD` |
| `displayPrefix` | e.g. IBAN `TR` |
| `preset` | Base preset name when overriding |
| `resolveMask` | `(value, allValues?, schema?) => string \| undefined` dynamic mask |
| `onCardTypeChange` | Card brand callback |
Built-in `validator` names: `luhn`, `tckn`, `email`, `iban`, `expiry`, `date`, `url`, `vkn`.
## Helpers (named exports)
- `applyMask`, `cleanValue`, `unmask`, `stripMask`
- `formatCurrency`, `unformatCurrency`
- `getCardType`
- `mergeRefs`
- `PRESETS`: full preset map
## Example URLs
- https://virastack.com/mask/examples/credit-card
- https://virastack.com/mask/examples/card
- https://virastack.com/mask/examples/phone
- https://virastack.com/mask/examples/iban
- https://virastack.com/mask/examples/tckn
- https://virastack.com/mask/examples/currency
- https://virastack.com/mask/examples/date
- https://virastack.com/mask/examples/taxNumber
- Also: expiry, cvv, email, url, zipCode, alpha, username, text, password, numeric
## Related
- Password: https://virastack.com/password/llms-full.txt
- Start (can install Mask): https://virastack.com/start/llms-full.txt
- Ecosystem: https://virastack.com/llms.txt