---
title: Input OTP
description: Accessible one-time password component with copy-paste functionality.
icon: lock
author:
  name: guilherme_rodz
  url: https://github.com/guilhermerodz
search:
  keywords: [one-time password, verification code, pin]
mode: wide
---

<PoweredBy
  packages={[
    { name: 'Shadcn UI', url: 'https://ui.shadcn.com/docs/components/input-otp' },
    { name: 'Base UI', url: 'https://base-ui.com/react/components/otp-field' },
  ]}
/>

### Installation

```package-install
npx shadcn@latest add @redpanda/input-otp
```

<ComponentPreview name="input-otp-demo" className="[&_input]:max-w-xs" description="A one-time password input." />

## When to use

Use this decision tree to determine when to use the Input OTP component:

```mermaid
graph TD;
    A[❓ Need secure code input?] --> B{What type of code?};
    B --> C["✅ One-time passwords (OTP)"];
    B --> D[✅ Verification codes];
    B --> E[✅ PIN codes];
    B --> F[⚠️ Regular passwords];

    C --> G[❓ Code length?];
    D --> G;
    E --> G;
    F --> H[⚠️ Use Password Input instead];

    G --> I[✅ 4-6 digit codes];
    G --> J[✅ Custom length codes];

    I --> K[❓ Need grouping/separators?];
    J --> L[✅ Set custom maxLength];

    K --> M[✅ Use InputOTPGroup + Separator];
    K --> N[ℹ️ Single group layout];
    L --> O[❓ Input pattern restrictions?];

    M --> O;
    N --> O;

    O --> P["✅ Digits only (default)"];
    O --> Q[✅ Alphanumeric codes];

    P --> R[ℹ️ Default digit pattern];
    Q --> S[✅ Set validationType to alphanumeric];

    R --> T[❓ Auto-focus behavior?];
    S --> T;

    T --> U["✅ Auto-advance on input (default)"];
    T --> V[ℹ️ Manual navigation only];

    U --> W[❓ Copy-paste support?];
    V --> W;

    W --> X[✅ Built-in paste functionality];
    W --> Y[ℹ️ Disable paste behavior];

    X --> Z[❓ Controlled vs uncontrolled?];
    Y --> Z;

    Z --> AA[✅ Controlled with value/onChange];
    Z --> BB[ℹ️ Uncontrolled component];

    classDef recommended fill:#4ade80,stroke:#22c55e,stroke-width:2px,color:#000;
    classDef discouraged fill:#fbbf24,stroke:#f59e0b,stroke-width:2px,color:#000;
    classDef decision fill:#60a5fa,stroke:#3b82f6,stroke-width:2px,color:#fff;
    classDef neutral fill:#9ca3af,stroke:#6b7280,stroke-width:2px,color:#fff;

    class C,D,E,I,J,L,M,P,Q,S,U,X,AA recommended;
    class F,H discouraged;
    class A,B,G,K,O,T,W,Z decision;
    class N,R,V,Y,BB neutral;
```

## Usage

```tsx
import { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from '@/components/redpanda-ui/input-otp';
```

```tsx
<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

### Pattern

Use Base UI's `validationType` prop to accept an alphanumeric OTP. The default is `numeric`.

<ComponentPreview name="input-otp-pattern-demo" description="An input OTP with alphanumeric pattern." />

```tsx lineNumbers {2}
<InputOTP maxLength={6} validationType="alphanumeric">
  <InputOTPGroup>
    <InputOTPSlot index={0} />
    {/* ... */}
  </InputOTPGroup>
</InputOTP>
```

### Separator

Use `InputOTPSeparator` to add a separator between input groups.

<ComponentPreview name="input-otp-separator-demo" description="An input OTP with custom separator." />

```tsx lineNumbers {4,15}
import {
  InputOTP,
  InputOTPGroup,
  InputOTPSeparator,
  InputOTPSlot,
} from "@/components/redpanda-ui/input-otp"

...

<InputOTP maxLength={4}>
  <InputOTPGroup>
    <InputOTPSlot index={0} />
    <InputOTPSlot index={1} />
  </InputOTPGroup>
  <InputOTPSeparator />
  <InputOTPGroup>
    <InputOTPSlot index={2} />
    <InputOTPSlot index={3} />
  </InputOTPGroup>
</InputOTP>
```

### Controlled

You can use the `value` and `onChange` props to control the input value.

<ComponentPreview name="input-otp-controlled-demo" />

## Credits

- We use [Base UI OTP Field](https://base-ui.com/react/components/otp-field) for the Input OTP component.
- We take our inspiration from [Shadcn UI](https://ui.shadcn.com/docs/components/input) for the input OTP style.
