Verify and upload3 checks
FormOtp
One-time code that fills from paste and SMS.
Example
Installation
bunx --bun shadcn@latest add @fieldkit/form-otpNeeds the @fieldkit registry. Add it once
Usage
- 1
Add the field to your schema
schema.tsimport { z } from "zod"import { otpField } from "@/lib/field-schemas" export const schema = z.object({ code: otpField(6),}) - 2
Render it inside a Form
The name prop matches the schema key.
example-form.tsximport { Form } from "@/components/form/form"import { FormOtp } from "@/components/form/form-otp"import { FormSubmit } from "@/components/form/form-submit"import { FieldGroup } from "@/components/ui/field"import { schema } from "./schema" export function ExampleForm() { return ( <Form schema={schema} defaultValues={{ code: "" }} onSubmit={save} > <FieldGroup> <FormOtp name="code" autoSubmit onResend={resendCode} /> <FormSubmit>Save</FormSubmit> </FieldGroup> </Form> )}
Checks
CheckOptionError message
Length and digits
otpField(length)Enter the 6-digit codeSubmits when complete
autoSubmitNoneResend cooldown
onResend, cooldownNoneBest practices
- Uses autoComplete="one-time-code"
Try these values
Terminal
otpField(6)| Input | Result | Output |
|---|---|---|
"123456" | Valid | "123456" |
"12345" | Invalid | Enter the 6-digit code |
"12a456" | Invalid | Enter the 6-digit code |
API reference
FormOtp
PropDescription
autoSubmitbooleanSubmits the form when every box is filled.onResend() => Promise<void>Shows Resend code with a cooldown.cooldownnumber = 30Seconds before resending.size"sm" | "default" | "lg" = "default"Box and button size.align"start" | "center" | "fill" = "center"Where the boxes sit. Fill stretches them.Field frame
PropDescription
namestringKey in the schema. Also picks the preset label and autocomplete.labelReact.ReactNodeOverrides the preset label. Pass null to hide it.descriptionReact.ReactNodeHint under the control.requiredbooleanOverrides the asterisk read from the schema.fieldPropsFormFieldPropsProps for the wrapping Field, such as className.