OTP Field
Fixed-length segmented input for one-time passwords, verification codes and recovery codes.
Purpose
Use OTP Field for short one-time passwords, verification codes and recovery codes that should be entered as a fixed sequence of slots.
Six-digit code
Installation
With the Siteplane registry alias configured, add the component and import the installed source from your app.
CLI
pnpm dlx shadcn@4.16.1 add @siteplane/otp-fieldImport
import { OTPField, OTPFieldInput, OTPFieldSeparator } from "@/components/ui/otp-field";
import { Field, FieldDescription, FieldError, FieldLabel } from "@/components/ui/field";Need the machine-readable source metadata? View registry JSON.
Usage
OTP Field is for fixed-length verification codes. Use separators only when they improve grouping.
import { OTPField, OTPFieldInput, OTPFieldSeparator } from "@/components/ui/otp-field";
import { Field, FieldLabel } from "@/components/ui/field";
export function Example() {
return (
<Field>
<FieldLabel>Verification code</FieldLabel>
<OTPField length={6}>
<OTPFieldInput />
<OTPFieldInput />
<OTPFieldInput />
<OTPFieldSeparator />
<OTPFieldInput />
<OTPFieldInput />
<OTPFieldInput />
</OTPField>
</Field>
);
}Examples
Sizes, states, masking, validation types and normalization are props and compositions of the same primitive.
Sizes
States
disabled dims the whole field; aria-invalid on the inputs marks a rejected code.
Masked entry
Alphanumeric
Placeholder hints
Validation
Custom normalization
normalizeValue filters accepted characters; onValueInvalid reports rejected input.
API Reference
The reference lists the source-owned exports and props that are easy to miss in visual examples. Inherited Base UI props remain available unless the wrapper narrows them.
OTPFieldis the root and requireslength; it also acceptssize="sm" | "default" | "lg" | "xl"and the Base UI OTP Field props.size="xl"renders each slot as a 56px square; the segmented value remains a set of real inputs. Use the surrounding provider'sradius="sm"personality for the global 8px main corner.- Render one
OTPFieldInputfor every character in DOM order. The number of slots must matchlength. OTPFieldSeparatorvisually divides slot groups without changing the value length.- Use
validationType,normalizeValue,onValueInvalid,maskand controlled or uncontrolled value props on the root.
Motion
Component motion uses the shared Siteplane motion contract. See the global motion guide for provider setup, tokens and reduced-motion behavior.
- Slots do not translate or resize while the value changes. Focus, invalid and disabled feedback use the native state styles.
- Reduced motion needs no extra handling because OTP Field does not animate with scale or movement.
Accessibility
- Pair the field with a visible
FieldLabel; without one, give every slot a specific label such asCharacter 2 of 6. - Keep the slot count synchronized with
lengthand explain rejected characters when custom validation is active. - Masking protects shoulder-surfing only; it is not a substitute for secure verification logic.
Implementation Guidance
- Use OTP Field only for short fixed-length codes, not free text.
- Keep every slot as a real
OTPFieldInputand uselength, not the legacymaxLengthcontract. - Do not replace the native slot, focus, disabled, invalid or masking behavior.