Masked input
ProA text field that shapes what is typed into a pattern: a card number in fours, a code like "AB-1234", or a whole number grouped as the locale groups it. The app gets the raw value (the characters only) and the shown one.
With a mask, the literals are typed for the person and the caret steps over them; a paste is read through the mask, keeping the characters that fit. Under the field the whole pattern is drawn with what is typed filled in, as a guide (hidden from screen readers), and the field is described by the pattern as an example, "Format: 1234 5678 9012". The text is read against the mask by position, so a literal that could fill a slot ("+1 ### ####") isn't read back as typed. Digits typed in any script (Arabic-Indic, Devanagari, Bengali, full-width …) are read as digits.
Version 5.2.0· other versions
This page is for 5.2.0, the current release. An earlier release’s page is the Markdown that release published, so the docs match the version you have installed (candor-lock.json records it).
Not in the docs of 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.6.0, 1.7.0, 1.8.0, 1.8.1, 1.9.0, 1.9.1, 2.0.0, 2.1.0, 2.2.0, 2.3.0, 2.4.0, 2.5.0, 2.5.1, 2.6.0, 2.6.1, 2.6.2, 2.7.0, 2.8.0, 2.9.0, 2.10.0, 3.0.0, 4.0.0, 4.0.1, 4.0.2, 4.1.0, 4.2.0 and 4.3.0: the page came later, or had another name then.
Docs pages weren’t kept for 1.0.0, 1.0.1, 1.1.0, 1.1.1, 1.2.0 and 1.2.1: they are kept from 1.3.0 on, and before that only llms.txt was published.
Preview
Loading the preview
Install
First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/masked-input
Brings in: input, locale, merge-refs, tokens, utils
Usage
"use client"
import * as React from "react"
import { Field } from "@/components/candor/ui/field"
import { MaskedInput } from "@/components/candor/ui/masked-input"
// The app keeps the raw value; the field shows it in its shape. A paste is read through the mask, and the pattern is
// read with the field as an example.
export default function Example() {
const [card, setCard] = React.useState("")
return (
<div className="flex w-full max-w-sm flex-col gap-4">
<Field label="Card number">
<MaskedInput mask="#### #### #### ####" autoComplete="cc-number" value={card} onValueChange={(raw) => setCard(raw)} />
</Field>
<Field label="Order reference">
<MaskedInput mask="AA-######" />
</Field>
<Field label="Seats" hint="Grouped as your language groups numbers.">
<MaskedInput group="digits" defaultValue="12500" />
</Field>
</div>
)
}<MaskedInput>
| Prop | Type | Default | Description |
|---|---|---|---|
| mask | string | undefined | — | The value's shape: `#` a digit, `A` a letter, anything else written for the person ("#### #### ####", "AA-####"). The literals are typed for them, the caret steps over them, and a paste is read through the mask. |
| group | "digits" | undefined | — | In place of a mask: group a whole number's digits as the locale does, "1,234,567", "12,34,567" in Hindi. |
| value | string | undefined | — | The raw value (the mask's characters only, no literals), when the app controls it. |
| defaultValue | string | undefined | — | The raw value at first, when the field keeps its own. |
| onValueChange | ((raw: string, shown: string) => void) | undefined | — | Called with the raw value and the value as shown, as the person types or pastes. |
Also takes the props of Omit<React.ComponentProps<typeof Input>, "value" | "defaultValue" | "onChange" | "type">.
Strings
The fixed words, in English by default. Change any of them under maskedInput in <LocaleProvider strings={{ … }}>; the table is exported as maskedInputStrings.
| Key | English |
|---|---|
| format | Format: {example} |