<OTPField length={6}>
<Label>Verification code</Label>
<div className="flex items-center">
<Group>
<Input />
<Input aria-label="Digit 2" />
<Input aria-label="Digit 3" />
</Group>
<OTPFieldSeparator className="px-2 text-fg-muted">-</OTPFieldSeparator>
<Group>
<Input aria-label="Digit 4" />
<Input aria-label="Digit 5" />
<Input aria-label="Digit 6" />
</Group>
</div>
</OTPField>Installation
npx shadcn@latest add @dotui/otp-fieldUsage
Use OTPField with Group and the existing Input component to compose passcode slots.
import { OTPField } from '@/ui/otp-field'
import { Label } from '@/ui/field'
import { Group } from '@/ui/group'
import { Input } from '@/ui/input'<OTPField length={6}>
<Label>Verification code</Label>
<Group>
<Input />
<Input aria-label="Digit 2" />
<Input aria-label="Digit 3" />
<Input aria-label="Digit 4" />
<Input aria-label="Digit 5" />
<Input aria-label="Digit 6" />
</Group>
</OTPField>Anatomy
OTPField wraps a Label, one or more Groups of single-character Input slots, and optional Description, FieldError, and OTPFieldSeparator parts. length sets how many slots render. Split the slots across Groups with an OTPFieldSeparator between them.
import { OTPField, OTPFieldSeparator } from '@/ui/otp-field'
import { Description, FieldError, Label } from '@/ui/field'
import { Group } from '@/ui/group'
import { Input } from '@/ui/input'<OTPField length={6}>
<Label />
<Group>
<Input />
</Group>
<OTPFieldSeparator />
<Group>
<Input />
</Group>
<Description />
<FieldError />
</OTPField>Value
The value is a string sized by length. Pass defaultValue for uncontrolled state, or value with onChange to control it.
const [value, setValue] = React.useState('')
<OTPField length={6} value={value} onChange={setValue}>
{/* ... */}
</OTPField>Validation
Mark the field isRequired, drive isInvalid to surface a FieldError alongside a Description, and set name for form submission. Use validationType to restrict input to "numeric" (default) or "alphanumeric".
<OTPField
length={6}
name="code"
isInvalid={isInvalid}
validationType="alphanumeric"
>
<Label>Recovery code</Label>
<Group>
<Input />
{/* ... */}
</Group>
<Description>Enter the code we sent you.</Description>
<FieldError>Enter all six characters.</FieldError>
</OTPField>Examples
Basic OTP Field
Verification Form
2FA Verification
Email Verification
API Reference
OTPField
An OTP field lets users enter a one-time passcode across multiple single-character inputs.
| Prop | Type | Default | |
|---|---|---|---|
boolean | — | ||
boolean | — | ||
boolean | false | ||
union | — | ||
number | — | ||
boolean | false | ||
function | — | ||
OTPValidationType | 'numeric' | ||
string | — | ||
string | — | ||
function | — | ||
OTPFieldSeparator
A separator visually divides groups of inputs within the OTP field.
| Prop | Type | Default | |
|---|---|---|---|
Orientation | 'horizontal' | ||
Last updated on 7/22/2026