Input OTP

Accessible one-time password input with copy/paste. Each character gets its own cell; built on the input-otp library.

Default (6-digit)

"use client";

import * as React from "react";
import { InputOTP, InputOTPGroup, InputOTPSlot } from "@tidal-ds/react";

export function Example() {
  const [value, setValue] = React.useState("");
  return (
    <InputOTP maxLength={6} value={value} onChange={setValue}>
      <InputOTPGroup>
        <InputOTPSlot index={0} />
        <InputOTPSlot index={1} />
        <InputOTPSlot index={2} />
        <InputOTPSlot index={3} />
        <InputOTPSlot index={4} />
        <InputOTPSlot index={5} />
      </InputOTPGroup>
    </InputOTP>
  );
}

With separator

<InputOTP maxLength={6} value={value} onChange={setValue}>
  <InputOTPGroup>
    <InputOTPSlot index={0} />
    <InputOTPSlot index={1} />
    <InputOTPSlot index={2} />
  </InputOTPGroup>
  <InputOTPSeparator />
  <InputOTPGroup>
    <InputOTPSlot index={3} />
    <InputOTPSlot index={4} />
    <InputOTPSlot index={5} />
  </InputOTPGroup>
</InputOTP>

Props

ComponentNotable props
InputOTPmaxLength (required), value, onChange, disabled, pattern (e.g. REGEXP_ONLY_DIGITS from input-otp), containerClassName
InputOTPGroupwraps a run of slots; first/last get outer radii automatically
InputOTPSlotindex (required) — reads char / caret / active state from OTPInputContext
InputOTPSeparatordecorative dash between groups; role="separator"

Source

packages/react/src/components/input-otp.tsx · built on input-otp