ComponentIndia
PAN Card Input
A smart input component for Indian PAN Card numbers. Validates the AAAAA9999A format in real-time — 5 letters, 4 digits, 1 letter — with segment-level progress bars, live error feedback, and full keyboard support.
Real-time validationSegment progressAccessibleControlled & uncontrolled
⌘
Installation
npx kesp-ui@latest add pan-card-inputCustom path: npx kesp-ui@latest add pan-card-input -p src/components/ui
📋
PAN Format
A PAN number follows a strict AAAAA9999A pattern:
ABCDE·1234·F
5 Uppercase Letters4 Digits1 Check Letter
⚡
Preview
InteractiveDefault
Letters
Digits
Check
Format: ABCDE1234F
With Error
Letters
Digits
Check
PAN not found in Income Tax records
Disabled
Letters
Digits
Check
✓ Valid PAN number
Custom Label
Letters
Digits
Check
Format: ABCDE1234F
📖
Usage
Basic Usage
import PanCardInput from "@/components/ui/pan-card-input"
function MyForm() {
const [pan, setPan] = useState<string>("")
return (
<PanCardInput
value={pan}
onChange={setPan}
onComplete={(value: string) => console.log("PAN:", value)}
/>
)
}With Validation
import PanCardInput from "@/components/ui/pan-card-input"
function ValidatedForm() {
const [value, setValue] = useState<string>("")
const [error, setError] = useState<boolean>(false)
const [errorMsg, setErrorMsg] = useState<string>("")
const handleValid = async (pan: string) => {
const result = await verifyPanWithAPI(pan)
if (!result.valid) {
setError(true)
setErrorMsg("PAN not found in Income Tax records")
}
}
return (
<PanCardInput
value={value}
onChange={(v: string) => { setValue(v); setError(false); setErrorMsg("") }}
onValid={handleValid}
error={error}
errorMessage={errorMsg}
/>
)
}Uncontrolled Mode
// Works without value prop — manages state internally
<PanCardInput
onComplete={(value: string) => submitForm(value)}
/>⚠
Error Handling
⊗
Error State
Pass error=true to show destructive border styling. Combine with errorMessage for a descriptive hint.
<PanCardInput
error={true}
errorMessage="PAN not found in Income Tax records"
/>✓
Success State
When a valid PAN is entered, an amber checkmark animates in and a success message appears. The onValid and onComplete callbacks fire.
<PanCardInput
onValid={(pan: string) => {
// pan = "ABCDE1234F" (valid, 10 chars)
lookupTaxpayer(pan)
}}
onComplete={(pan: string) => {
// fires when length hits 10
validateWithAPI(pan)
}}
/>📝
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | undefined | Controlled value (10 chars, no formatting) |
onChange | (value: string) => void | undefined | Called on every change with raw sanitized string |
onComplete | (value: string) => void | undefined | Fired when all 10 characters are entered |
onValid | (value: string) => void | undefined | Fired when a fully valid PAN is entered |
error | boolean | false | Displays error styling on the input |
errorMessage | string | undefined | Error text shown below the input |
disabled | boolean | false | Disables the input field |
label | string | "PAN Card Number" | Label text above the input |
placeholder | string | "ABCDE 1234 F" | Placeholder for the input field |
className | string | "" | Additional CSS classes on the wrapper |
>
CLI Reference
Install component
npx kesp-ui@latest add pan-card-inputCustom path
npx kesp-ui@latest add pan-card-input -p src/components/uiList components
npx kesp-ui@latest listCheck version
npx kesp-ui --versionHelp
npx kesp-ui --help