# Input OTP

> Fixed-length one-time-code input. One cell per character, auto-advances focus on typing, handles paste of a full code, optional masking like a password field.

Source: https://ngwr.dev/reference/components/input-otp  
Kind: Signal Forms, a11y

## Installation

```angular-ts
import { WrInputOtp } from 'ngwr/input-otp';

@Component({ imports: [WrInputOtp] })
export class MyComponent {
  protected code = '';
  protected verify(code: string) { /* … */ }
}
```

## Basic (numeric, 6 cells)

The default. `completed` fires once every cell holds a character — paste the value `123456` to try it.

```angular-html
<wr-input-otp [(value)]="code" length="6" (completed)="verify($event)" />
```

```html
<wr-input-otp [(value)]='code' (completed)='onCompleted($event)' />
```

## Custom length

```html
<wr-input-otp [(value)]='codeShort' length='4' />
```

## Alphanumeric

Letters and digits. Useful for invitation codes.

```angular-html
<wr-input-otp [(value)]="alphaNumeric" mode="alphanumeric" length="8" />
```

```html
<wr-input-otp [(value)]='alphaNumeric' mode='alphanumeric' length='8' />
```

## Masked

Renders cells as `type='password'` — characters are hidden as you type.

```angular-html
<wr-input-otp [(value)]="secret" mask />
```

```html
<wr-input-otp [(value)]='secret' mask />
```

## Disabled

```html
<wr-input-otp disabled />
```

## API

| Name | Description | Type | Default |
| --- | --- | --- | --- |
| `ariaLabel` | Accessible name of the whole strip. Falls back to `inputOtp.label`. | `string \| null` | `null` |
| `length` | Number of cells to render. Clamped to `[1, 20]`. | `number` | `6` |
| `mode` | Character set per cell. | `WrInputOtpMode` | `'numeric'` |
| `size` | Control size — shares the `--wr-control-*` contract. Unset falls back to the `inputOtp.size` app default from `provideWrConfig()`. | `WrInputOtpSize \| null` | `'md'` |
| `mask` | Mask the typed characters like a password. | `boolean` | `false` |
| `disabled` | Disable interaction. Bound automatically from the field's disabled state when used with `[formField]`. | `boolean` | `false` |
| `readonly` | Refuse edits while every box stays focusable and the code still submits. Bound automatically from the field's readonly state when used with `[formField]`. Each box is a real text input, so this is the native `readonly` attribute — arrow keys, Home / End and selection keep working, which is the whole difference from `disabled`. Paste is cancelled too, since a `paste` still reaches a read-only input even though typing does not. | `boolean` | `false` |
| `placeholder` | Character shown in empty cells. | `string` | `'•'` |
| `value` | The entered code. Bound by `[formField]`, or two-way via `[(value)]`. | `string` | `''` |
| `(completed)` | Fires once when every cell holds a character. | `string` | — |
| `(touch)` | Emitted on blur so a bound field can mark itself touched. | `void` | — |

## Events

| Name | Description | Type | Default |
| --- | --- | --- | --- |
| `(completed)` | Fires once every cell holds a character — useful for auto-submit. | `string` | `—` |

## CSS variables

Custom properties `ngwr/input-otp` publishes. Each default below is declared on the component's own selector, so a `:root` override is shadowed by it — set them on that selector, on a wrapper you scope yourself, or inline on the element. Unlike the BEM class names, these are the supported way to restyle the component.

| Variable | Default | Declared on |
| --- | --- | --- |
| `--wr-input-otp-bg` | `var(--wr-color-surface)` | `.wr-input-otp` |
| `--wr-input-otp-border` | `var(--wr-color-outline)` | `.wr-input-otp` |
| `--wr-input-otp-color` | `var(--wr-color-on-surface)` | `.wr-input-otp` |
| `--wr-input-otp-focus` | `var(--wr-color-primary)` | `.wr-input-otp` |
| `--wr-input-otp-font` | `var(--wr-text-lg)` | `.wr-input-otp` +2 variant overrides |
| `--wr-input-otp-gap` | `0.5rem` | `.wr-input-otp` +2 variant overrides |
| `--wr-input-otp-radius` | `var(--wr-control-radius-md)` | `.wr-input-otp` +2 variant overrides |
| `--wr-input-otp-size` | `2.5rem` | `.wr-input-otp` +2 variant overrides |
