HextaUI

Input OTP: With Field

Inside a <Field /> the label, description and error are linked for you. Enter anything but 000000 to see the error.

We sent it to [email protected].

"use client"

import * as React from "react"

import {
  Field,
  FieldDescription,
  FieldError,
  FieldLabel,
} from "@/components/ui/field"
import {
  InputOTP,
  InputOTPGroup,
  InputOTPSeparator,
  InputOTPSlot,
} from "@/components/ui/input-otp"

export function InputOTPField() {
  const [value, setValue] = React.useState("")
  const [error, setError] = React.useState<string>()

  return (
    <Field invalid={error !== undefined} className="w-fit">
      <FieldLabel>Verification code</FieldLabel>
      <InputOTP
        length={6}
        value={value}
        onValueChange={(next) => {
          setValue(next)
          setError(undefined)
        }}
        onValueComplete={(code) => {
          if (code !== "000000") {
            setError("That code has expired. Request a new one.")
          }
        }}
      >
        <InputOTPGroup>
          <InputOTPSlot />
          <InputOTPSlot />
          <InputOTPSlot />
        </InputOTPGroup>
        <InputOTPSeparator />
        <InputOTPGroup>
          <InputOTPSlot />
          <InputOTPSlot />
          <InputOTPSlot />
        </InputOTPGroup>
      </InputOTP>
      <FieldDescription>We sent it to [email protected].</FieldDescription>
      <FieldError errors={error ? [{ message: error }] : []} />
    </Field>
  )
}

This adds the example as components/examples/input-otp/field.tsx, together with the Input OTP component and the HextaUI theme tokens it needs.

pnpm dlx shadcn@latest add https://hextaui.com/r/input-otp-field.json

To add only the component, follow the Input OTP installation.

Props in this example

The Input OTP props this example sets, from the API reference.

PropTypeDefault
lengthRequired. The number of slots; render the same number of InputOTPSlot parts.
number–
value
string–
onValueChange
(value: string, details) => void–
onValueCompleteCalled when the last slot fills.
(value: string, details) => void–

Every prop is in the Input OTP API reference.

See them all, with keyboard support and accessibility notes, on the Input OTP page.