Aadhaar Input

An Aadhaar field that masks the number as it is typed and catches typos, pasted VIDs, PANs or mobile numbers before KYC rejects them.

StopsAadhaar typos and over-exposure

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/aadhaar-input.json

The files land in your project. They're yours to edit.

Usage

aadhaar-input-usage.tsx
import { AadhaarInput } from "@/components/ui/aadhaar-input"

<AadhaarInput value={value} onValueChange={setValue} accept={accept} onAcceptChange={setAccept} name="aadhaar" />

What it catches

  • Typos and swapped neighbouring digits, via the Verhoeff check digit
  • A first digit of 0 or 1, which Aadhaar numbers never use
  • A 16-digit VID, 28-digit enrolment ID, masked copy, PAN or mobile number pasted by mistake
  • Spaces, dashes and dots from a photocopy or PDF, and Indian-script or full-width digits
  • Letters typed for look-alike digits (O, I, l, S)

Props

AadhaarInput props
PropTypeDefault
accept

What the form wants. Defaults to `aadhaar`.

Accept"aadhaar"
value

Controlled entry (digits; letters only while a look-alike fix is pending).

string—
defaultValue

Initial entry when uncontrolled. Spaces and dashes are removed.

string""
onValueChange

Called with the entry and what it was read as. Store `maskAadhaar(entry)`, not the entry, unless you run an Aadhaar Data Vault.

(value: string, reading: AadhaarReading) => void—
onAcceptChange

Offer a one-tap switch when the other kind is pasted (VID in an Aadhaar field, or the reverse).

(accept: "aadhaar" | "vid") => void—
storage

How you keep the number, shown as the storage note. Defaults to `masked`.

"masked" | "vault" | "none""masked"
label

Visible label; defaults to one matching `accept`.

string—
messages

Any visible string.

Partial<AadhaarMessages>—

* required. Also accepts the native props of <input> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Visible <label> tied to the input; aria-invalid and aria-describedby point at the error and storage note
  • Show/hide is a real button with aria-pressed and an aria-label, and returns focus to the field
  • Status changes are announced through a role="status" region
  • Icons are aria-hidden; errors carry text, not only colour

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

This is a UX guard rail. Enforce on the server: Verify the number through an authorised KYC/eKYC provider on the server, and avoid storing or logging full Aadhaar numbers unless you are permitted to.

  • Format and checksum only: it does not confirm the number exists or belongs to this person
  • On a failed check digit it offers to reveal the number rather than guessing which digit is wrong
  • Masking is visual; your form still receives the full number unless you handle it otherwise
  • The storage note only describes what you pass in `storage`; it does not store or encrypt anything

Rules

Rules not yet verified against an official source.

Not verified on 2026-10-17: the UIDAI site did not respond. The no-0-or-1 first digit, Verhoeff check digit, 16-digit VID and masked-Aadhaar conventions are unchecked here. Copied components don't update themselves, so re-check after rule changes (see updating a component).

What it stops

Aadhaar typos and over-exposure

Also known as

aadhaar · uidai · aadhar number · vid · masked aadhaar · kyc · ekyc · 12 digit

Field type

Dependencies

Pairs well with