Input OTP
Accessible one-time password component with copy paste functionality.
Interactive
Features
Copy/paste support. Keyboard navigation. Customizable slot rendering. Works with password managers. Supports numeric and alphanumeric modes.
Installation
Install the component from your command line.
ng g @ng-cn/core:c input-otpAnatomy
Import all parts and piece them together.
import {
InputOTP,
InputOTPGroup,
InputOTPSlot,
InputOTPSeparator
} from '@/ui/input-otp';<InputOTP>
<InputOTPGroup>
<InputOTPSlot [index]="0" />
<InputOTPSlot [index]="1" />
<InputOTPSlot [index]="2" />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot [index]="3" />
<InputOTPSlot [index]="4" />
<InputOTPSlot [index]="5" />
</InputOTPGroup>
</InputOTP>API Reference
Root
Contains all the parts of an input OTP.
| Prop | Type | Default |
|---|---|---|
| value | string | — |
| The controlled value of the input. | ||
| maxLength | number | 6 |
| Maximum number of characters. | ||
| disabled | boolean | false |
| When true, prevents the user from interacting with the input. | ||
| pattern | string | "^[0-9]*$" |
| Pattern for input validation. | ||
| inputMode | 'numeric' | 'text' | 'decimal' | 'tel' | 'numeric' |
| Input mode for virtual keyboard. | ||
| class | string | — |
| Additional CSS classes to apply. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-disabled] | Present when disabled |
Group
Used to group multiple InputOTPSlot components.
| Prop | Type | Default |
|---|---|---|
| class | string | — |
| Additional CSS classes to apply. |
Slot
Renders an individual input slot.
| Prop | Type | Default |
|---|---|---|
| index * | number | — |
| The index of this slot (0-based). | ||
| class | string | — |
| Additional CSS classes to apply. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-active] | Present when slot is active |
| [data-filled] | Present when slot has a value |
Separator
Used to render a separator between slot groups.
| Prop | Type | Default |
|---|---|---|
| class | string | — |
| Additional CSS classes to apply. |
Examples
Basic
A 6-digit OTP input with separator.
<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>Simple 4-digit
A simple 4-digit OTP without separator.
<InputOTP [maxLength]="4">
<InputOTPGroup>
@for (i of [0,1,2,3]; track i) {
<InputOTPSlot [index]="i" />
}
</InputOTPGroup>
</InputOTP>Controlled
Control the OTP value externally.
// In your component:
otp = signal('');
onComplete(value: string) {
console.log('OTP completed:', value);
}
// In template:
<InputOTP
[(value)]="otp"
[maxLength]="6"
(onComplete)="onComplete($event)"
>
<InputOTPGroup>
@for (i of [0,1,2,3,4,5]; track i) {
<InputOTPSlot [index]="i" />
}
</InputOTPGroup>
</InputOTP>
<p>Current value: {{ otp() }}</p>With pattern
Alphanumeric OTP with custom pattern.
<InputOTP [maxLength]="6" pattern="^[a-zA-Z0-9]*$" inputMode="text">
<InputOTPGroup>
@for (i of [0,1,2,3,4,5]; track i) {
<InputOTPSlot [index]="i" />
}
</InputOTPGroup>
</InputOTP>Disabled
Disabled state.
<InputOTP [maxLength]="6" [disabled]="true">
<InputOTPGroup>
@for (i of [0,1,2,3,4,5]; track i) {
<InputOTPSlot [index]="i" />
}
</InputOTPGroup>
</InputOTP>Accessibility
Adheres to the OTP/PIN input pattern .
Keyboard Interactions
| Key | Description |
|---|---|
| 0-9 | Types the digit into the current slot and moves to next. |
| Backspace | Clears the current slot and moves to previous. |
| Paste | Fills slots with pasted content. |