Taiwan ID Number Input
An input for the Taiwan national ID number — check-digit validation, masked display by default, and district and gender badges.
A dedicated input for the Taiwan national ID number: it implements the Ministry of the Interior's published check-digit algorithm (the leading letter is transcoded and weighted), validating in real time with animated feedback as soon as 10 characters are entered. The middle four digits are masked by default (A12****789, with an eye button to toggle visibility), and on a successful validation it shows small badges for the household registration city or county derived from the leading letter and the gender derived from the 2nd digit.
npx shadcn@latest add https://webberui.com/r/taiwan-id-input.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<TaiwanIdInput />
Installation
npx shadcn@latest add https://webberui.com/r/taiwan-id-input.jsonOr, once registries are configured in components.json, install it as @webberui/taiwan-id-input.
Usage
import { TaiwanIdInput, validateTaiwanId } from "@/components/ui/taiwan-id-input";
// Uncontrolled: use it as is
<TaiwanIdInput onValidChange={(valid) => console.log(valid)} />
// Controlled: manage the value yourself
const [id, setId] = React.useState("");
<TaiwanIdInput value={id} onChange={setId} masked />
// The validator can also be used on its own
validateTaiwanId("A123456789"); // true (demo data, not a real ID)Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | The current input value (controlled); when omitted, the component manages the state internally |
defaultValue | string | "" | Initial value in uncontrolled mode |
onChange | (value: string) => void | — | Callback when the value changes, returning the cleaned string (1 letter plus up to 9 digits) |
onValidChange | (valid: boolean) => void | — | Reports the validation result once 10 characters have been entered |
masked | boolean | true | Whether the middle four digits are masked by default, toggleable with the eye button |
disabled | boolean | false | Disable the input |
className | string | — | Forwarded to the outer container |
validateTaiwanId(id: string): boolean is also a named export and can be called independently before form submission.
Accessibility
- The real input is a native
<input>overlaid transparently on top (witharia-label「身分證字號」, national ID number), and it carries all keyboard input and screen reader interaction;aria-invalidis set when validation fails - The validation result (pass, including the city/county and gender, or fail) is read out through an
aria-live="polite"region; the purely visual character boxes are hidden from assistive technology (aria-hidden) - The mask is a display layer only — the field's actual value is preserved in full, so form submission and
onChangeare unaffected - The eye toggle button has an
aria-labeland anaria-pressedstate - When the user has "reduce motion" enabled at the system level, the shake and scale pulse animations are disabled and only the color and text feedback remains