WebberUI

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.

Loading preview…
npx shadcn@latest add https://webberui.com/r/taiwan-id-input.json

Playground

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.json

Or, 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

PropTypeDefaultDescription
valuestringThe current input value (controlled); when omitted, the component manages the state internally
defaultValuestring""Initial value in uncontrolled mode
onChange(value: string) => voidCallback when the value changes, returning the cleaned string (1 letter plus up to 9 digits)
onValidChange(valid: boolean) => voidReports the validation result once 10 characters have been entered
maskedbooleantrueWhether the middle four digits are masked by default, toggleable with the eye button
disabledbooleanfalseDisable the input
classNamestringForwarded 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 (with aria-label「身分證字號」, national ID number), and it carries all keyboard input and screen reader interaction; aria-invalid is 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 onChange are unaffected
  • The eye toggle button has an aria-label and an aria-pressed state
  • 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

On this page