Input OTP
A one-time password input component with animated slots and customizable separators.
Overview
The InputOTP component provides a user-friendly interface for entering one-time passwords or verification codes. It features animated character slots, customizable grouping with separators, and supports validation states.
Usage
import {
InputOTP,
InputOTPGroup,
InputOTPSeparator,
InputOTPSlot,
} from "@tilt-legal/cubitt-components/input-otp";<InputOTP maxLength={6}>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>Examples
With Multiple Separators
OTP input with multiple groups and separators for credit card-style formatting.
import {
InputOTP,
InputOTPGroup,
InputOTPSeparator,
InputOTPSlot,
} from "@tilt-legal/cubitt-components/input-otp";
<InputOTP maxLength={6}>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>;Numbers Only
OTP input restricted to numeric characters only using a regex pattern.
import {
InputOTP,
InputOTPGroup,
InputOTPSlot,
} from "@tilt-legal/cubitt-components/input-otp";
<InputOTP maxLength={6} pattern="^[0-9]*$">
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>;States
Switch between default, error, and disabled states.
import {
InputOTP,
InputOTPGroup,
InputOTPSeparator,
InputOTPSlot,
} from "@tilt-legal/cubitt-components/input-otp";
const states = ["default", "invalid", "disabled"] as const;
const [state, setState] =
useState<"default" | "invalid" | "disabled">("default");
<>
<InputOTP
disabled={state === "disabled"}
invalid={state === "invalid"}
maxLength={6}
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
<PreviewFooter>
<ToggleGroup
aria-label="Input OTP state"
groupVariant="segmented"
multiple={false}
onValueChange={(value) => {
if (states.includes(value as (typeof states)[number])) {
setState(value as (typeof states)[number]);
}
}}
value={state}
>
<ToggleGroupItem value="default">Default</ToggleGroupItem>
<ToggleGroupItem value="invalid">Error</ToggleGroupItem>
<ToggleGroupItem value="disabled">Disabled</ToggleGroupItem>
</ToggleGroup>
</PreviewFooter>
</>;API Reference
InputOTP
The root component that manages the OTP input state. Built on input-otp.
| Prop | Type | Default | Description |
|---|---|---|---|
maxLength | number | - | Maximum number of characters (required) |
value | string | - | Controlled value |
onChange | (value: string) => void | - | Callback when value changes |
onComplete | (value: string) => void | - | Callback when all slots are filled |
pattern | string | - | Regex pattern for allowed characters |
invalid | boolean | false | Shows invalid/error styling on all slots and sets aria-invalid |
disabled | boolean | false | Disables the input |
containerClassName | string | - | Class name for the container element |
InputOTPGroup
Groups slots together visually.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
InputOTPSlot
Individual character slot that displays a single character.
| Prop | Type | Default | Description |
|---|---|---|---|
index | number | - | Slot position index (required) |
className | string | - | Additional CSS classes |
InputOTPSeparator
Visual separator between slot groups.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |