OTP Field
FormsA one-time-password input split across several single-character slots.
OTP fields chunk a code into individual boxes for fast, focused entry. Typing advances automatically, and the value can be read or controlled as a single string.
npx shadcn@latest add otp-fieldBasic usage
Six slots that fill as the code is typed. onValueChange reports the full value.
Preview
LiveCode: empty
tsx
1const [value, setValue] = useState("")23<OtpField4 value={value}5 onValueChange={setValue}6 length={6}7 className="flex w-full gap-2"8>9 <OtpFieldGroup>10 <OtpFieldInput aria-label="Digit 1" />11 <OtpFieldInput aria-label="Digit 2" />12 <OtpFieldInput aria-label="Digit 3" />13 </OtpFieldGroup>14 <OtpFieldSeparator />15 <OtpFieldGroup>16 <OtpFieldInput aria-label="Digit 4" />17 <OtpFieldInput aria-label="Digit 5" />18 <OtpFieldInput aria-label="Digit 6" />19 </OtpFieldGroup>20</OtpField>
Completion
React when the code becomes complete with onValueComplete.
Preview
Livetsx
1<OtpField2 length={4}3 onValueComplete={(value) => {4 console.log("Code entered:", value)5 }}6 className="flex gap-2"7>8 <OtpFieldInput aria-label="Digit 1" />9 <OtpFieldInput aria-label="Digit 2" />10 <OtpFieldInput aria-label="Digit 3" />11 <OtpFieldInput aria-label="Digit 4" />12</OtpField>
API reference
All props of the underlying Base UI primitive are forwarded. The table below documents the Shelf-specific props.
| Prop | Type | Description |
|---|---|---|
| value | string | The controlled OTP value. |
| defaultValue | string | The uncontrolled initial value. |
| onValueChange | (value: string) => void | Called when the value changes. |
| onValueComplete | (value: string) => void | Called once all slots are filled. |
| length | number | The number of input slots. Required. |
| mask | boolean= false | Masks the entered characters. |