On this page
PinInput
A component for entering PIN codes, OTP, and verification codes.
import { PinInput } from "@ninna-ui/forms";pnpm add @ninna-ui/forms@latestIncludes
@ninna-ui/core. CSS setup required.View source Usage
Import and use the PinInput component in your application.
import { PinInput } from "@ninna-ui/forms";
export default function Example() { return ( <PinInput length={6} onComplete={(pin) => console.log('PIN:', pin)} /> );}Basic
Basic 4-digit PIN input.
Live preview/ Default
Length
PinInput with different number of fields.
Live preview/ Default
4 digits (default)
6 digits
8 digits
Input Types
Text, number, and password input types.
Live preview/ Default
Text (default)
Number only
Password (masked)
Sizes
PinInput in different sizes.
Live preview/ Default
Extra Small
Small
Medium
Large
Extra Large
OTP Mode
6-digit OTP input with number-only mode.
Live preview/ Default
Enter the 6-digit code sent to your phone
Masked
PIN input with masked/hidden values.
Live preview/ Default
Enter your PIN (masked)
States
Different states of the PIN input.
Live preview/ Default
Normal
With Default Value
Disabled
Invalid
React Hook Form
PinInput works with React Hook Form using the Controller pattern.
Live preview/ Default
API Reference
Complete list of props for the PinInput component.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
length | number | 4 | Number of input fields |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Size of the inputs |
type | 'text' | 'password' | 'number' | 'text' | Input type |
mask | boolean | false | Mask input value |
otp | boolean | false | One-time password mode (enables autocomplete) |
value | string | — | Controlled value |
defaultValue | string | — | Default value (uncontrolled) |
onChange | (value: string) => void | — | Callback when value changes |
onComplete | (value: string) => void | — | Callback when all fields are filled |
disabled | boolean | false | Disabled state |
invalid | boolean | false | Invalid state |
placeholder | string | '○' | Placeholder for each field |
autoFocus | boolean | false | Auto focus the first input on mount |
name | string | — | Name for hidden form submission input |
aria-label | string | 'PIN input' | Accessible label for the input group |
Accessibility
- Uses
role="group"with a customizablearia-label(default: "PIN input") - Each input has an
aria-labelindicating its position (e.g. "Pin digit 1 of 6") - Arrow keys navigate between inputs
- Backspace moves to previous input when empty
- Paste support for filling multiple inputs at once
- Proper
aria-invalidandaria-disabledstates - OTP mode enables
autocomplete="one-time-code"