Logo
DocsInput OTP

Input OTP

An input component for one-time password (OTP) codes.

Implementation

1

Install the following dependencies:

pnpm add input-otp
2

Copy and paste the following code into your project.

"use client"

import * as React from "react"
import { OTPInput, type OTPInputProps } from "@zag-js/otp-input"
import { useMachine, normalizeProps } from "@zag-js/react"
import * as otp from "@zag-js/otp-input"

import { cn } from "@/lib/utils"

const InputOTP = React.forwardRef<
  HTMLDivElement,
  OTPInputProps & React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => {
  const [state, send] = useMachine(
    otp.machine({
      id: React.useId(),
      ...props,
    })
  )

  const api = otp.connect(state, send, normalizeProps)

  return (
    <OTPInput
      {...api.rootProps}
      ref={ref}
      className={cn("flex items-center gap-2", className)}
    >
      {api.slots.inputs}
    </OTPInput>
  )
})
InputOTP.displayName = "InputOTP"

const InputOTPGroup = React.forwardRef<
  HTMLDivElement,
  React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
  <div ref={ref} className={cn("flex items-center", className)} {...props} />
))
InputOTPGroup.displayName = "InputOTPGroup"

const InputOTPSlot = React.forwardRef<
  HTMLInputElement,
  React.InputHTMLAttributes<HTMLInputElement>
>(({ className, ...props }, ref) => (
  <input
    ref={ref}
    className={cn(
      "h-10 w-10 rounded-md border border-input bg-transparent text-center text-sm shadow-sm transition-all placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
      className
    )}
    {...props}
  />
))
InputOTPSlot.displayName = "InputOTPSlot"

const InputOTPSeparator = React.forwardRef<
  HTMLDivElement,
  React.HTMLAttributes<HTMLDivElement>
>(({ ...props }, ref) => (
  <div ref={ref} role="separator" {...props}>
    -
  </div>
))
InputOTPSeparator.displayName = "InputOTPSeparator"

export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }
3

Update the import paths to match your project setup.

Usage

import {
  InputOTP,
  InputOTPGroup,
  InputOTPSeparator,
  InputOTPSlot,
} from "@/components/ui/input-otp"

Examples

Default

With Pattern

API Reference

InputOTP

The main component for creating an OTP input.

Properties

PropertyTypeDefaultDescription
maxLengthnumber-The maximum number of characters allowed in the input.
patternstring-A regular expression pattern to validate the input.
renderfunction-A render function to customize the input slots.