OTP Input
A one-time code as separate boxes that type, delete, paste and autofill like one field.
Rendering OTP Input…
Installation
Copy the source into your project with the CLI. It lands under @/components/ui and is yours to edit.
npx mlola-ui add otp-inputUsage
import { OtpInput } from "@/components/ui/otp-input";
export default function Example() {
return <OtpInput label="Verification code" hint="Sent to your email." length={6} />;
}Styling comes from the engine stylesheet and the nearest theme. Set it once at the root:
<html data-theme="graphite" data-mode="light">HTML
The markup the example above renders, at rest. The interaction lives in the React component; from another framework, set the attributes below as the state changes.
<div class="ml-input-field">
<label class="ml-input-label" id="otp-1-label" for="otp-1">Verification code</label>
<div class="ml-otp" role="group" aria-labelledby="otp-1-label">
<input class="ml-otp-box" id="otp-1" inputMode="numeric" autoComplete="one-time-code" aria-label="Digit 1 of 6" aria-describedby="otp-1-hint" maxLength="6" value=""/>
<input class="ml-otp-box" inputMode="numeric" autoComplete="off" aria-label="Digit 2 of 6" maxLength="1" value=""/>
<input class="ml-otp-box" inputMode="numeric" autoComplete="off" aria-label="Digit 3 of 6" maxLength="1" value=""/>
<input class="ml-otp-box" inputMode="numeric" autoComplete="off" aria-label="Digit 4 of 6" maxLength="1" value=""/>
<input class="ml-otp-box" inputMode="numeric" autoComplete="off" aria-label="Digit 5 of 6" maxLength="1" value=""/>
<input class="ml-otp-box" inputMode="numeric" autoComplete="off" aria-label="Digit 6 of 6" maxLength="1" value=""/>
</div>
<p class="ml-input-hint" id="otp-1-hint">Sent to your email.</p>
</div>Options
| Prop | Values | Default | Description |
|---|---|---|---|
mode | numericalphanumeric | numeric | "numeric" (default) or "alphanumeric". |
Every prop with a fixed set of values, read from the exported TypeScript types with its doc comment. Open the Code tab above for the rest of the API.
Classes and attributes
A class names each element; data-* and aria-* attributes carry its variant and state. The values listed are the ones the stylesheet draws; the default needs no attribute.
| Class | Attributes |
|---|---|
ml-otp | data-invalid |
ml-otp-box | — |
ml-otp-separator | — |
Accessibility and theming
- Semantic elements, accessible names and state relationships are part of the contract.
- Keyboard, pointer and touch paths are operable; focus stays visible in every theme.
- Light and dark modes pass WCAG AA contrast in all 5 canonical themes.
- Reduced motion and forced colors keep meaning and operation.
Dependencies
Installed alongside this component. No third-party UI runtime is ever added.