Skip to main content
ninna-ui

PinInput

A component for entering PIN codes, OTP, and verification codes.

import { PinInput } from "@ninna-ui/forms"
pnpm add @ninna-ui/forms

Requires @ninna-ui/core (auto-installed) + CSS setup.

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.

Length

PinInput with different number of fields.

4 digits (default)
6 digits
8 digits

Input Types

Text, number, and password input types.

Text (default)
Number only
Password (masked)

Sizes

PinInput in different sizes.

Extra Small

Small

Medium

Large

Extra Large

OTP Mode

6-digit OTP input with number-only mode.

Enter the 6-digit code sent to your phone

Masked

PIN input with masked/hidden values.

Enter your PIN (masked)

States

Different states of the PIN input.

Normal

With Default Value

Disabled

Invalid

React Hook Form

PinInput works with React Hook Form using the Controller pattern.

Enter the 6-digit code sent to your phone

API Reference

Complete list of props for the PinInput component.

Props

PropTypeDefaultDescription
lengthnumber4Number of input fields
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Size of the inputs
type'text' | 'password' | 'number''text'Input type
maskbooleanfalseMask input value
otpbooleanfalseOne-time password mode (enables autocomplete)
valuestring-Controlled value
defaultValuestring-Default value (uncontrolled)
onChange(value: string) => void-Callback when value changes
onComplete(value: string) => void-Callback when all fields are filled
disabledbooleanfalseDisabled state
invalidbooleanfalseInvalid state
placeholderstring'○'Placeholder for each field
autoFocusbooleanfalseAuto focus the first input on mount
namestring-Name for hidden form submission input
aria-labelstring'PIN input'Accessible label for the input group

Accessibility

  • Uses role="group" with a customizable aria-label (default: "PIN input")
  • Each input has an aria-label indicating 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-invalid and aria-disabled states
  • OTP mode enables autocomplete="one-time-code"