Components/OTP Input

OTP Input

Accessible one-time password input with copy-paste support and keyboard navigation.

Playground

Length

Slot Size

Separator
Disabled
Error

Code

import { useState } from 'react';
import { OTP } from 'irismail/react';

function VerifyForm() {
  const [code, setCode] = useState('');

  return (
    <OTP
      value={code}
      onChange={setCode}
    />
  );
}

Examples

Common patterns.

Basic

3
8
4
7
2
9

With Separator

7
4
9
2
8
1

Light Theme

5
2
8
1
4
6

Error State

1
9
2
8
4
7

API

Props for the OTP component.

PropTypeDefault
lengthnumber6
valuestring
onChange(value: string) => void
onComplete(value: string) => void
theme"dark" | "light""dark"
slotSize"sm" | "md" | "lg""md"
separatorbooleanfalse
groupSizenumberlength / 2
disabledbooleanfalse
errorbooleanfalse
autoFocusbooleanfalse
classNamesOTPClassNames

Styles API

Customize individual parts with the classNames prop.

KeyDescription
rootRoot container element
groupGroup wrapper containing slots
slotIndividual digit slot (base state)
slotFilledSlot when it contains a digit
slotActiveSlot when focused/active
slotErrorSlot in error state
separatorSeparator container
separatorLineThe separator dash/line
caretBlinking caret cursor
<OTP
  value={code}
  onChange={setCode}
  separator
  classNames={{
    slot: "rounded-none first:rounded-l-md",
    slotActive: "ring-2 ring-blue-500",
    separator: "mx-4",
    separatorLine: "bg-blue-500 w-4",
  }}
/>

Like what you see?

Check out the docs or star us on GitHub.