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-input

Custom 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

Interactive
Default
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

PropTypeDefaultDescription
valuestringundefinedControlled value (10 chars, no formatting)
onChange(value: string) => voidundefinedCalled on every change with raw sanitized string
onComplete(value: string) => voidundefinedFired when all 10 characters are entered
onValid(value: string) => voidundefinedFired when a fully valid PAN is entered
errorbooleanfalseDisplays error styling on the input
errorMessagestringundefinedError text shown below the input
disabledbooleanfalseDisables the input field
labelstring"PAN Card Number"Label text above the input
placeholderstring"ABCDE 1234 F"Placeholder for the input field
classNamestring""Additional CSS classes on the wrapper
>

CLI Reference

Install component
npx kesp-ui@latest add pan-card-input
Custom path
npx kesp-ui@latest add pan-card-input -p src/components/ui
List components
npx kesp-ui@latest list
Check version
npx kesp-ui --version
Help
npx kesp-ui --help