Default
import React from 'react';
import { PixelOTPInput } from '@pxlkit/ui-kit';
export function Default() {
const [value, setValue] = React.useState('')
return <PixelOTPInput length={6} value={value} onChange={setValue} />
}One-time passcode input with auto-advance, paste-fill, and per-cell keyboard navigation.
import { PixelOTPInput } from '@pxlkit/ui-kit';| Prop | Type | Default | Description |
|---|---|---|---|
length | number | 6 | Number of cells. |
value | string | — | Code; leave unset for an uncontrolled input. |
defaultValue | string | — | Initial code while uncontrolled. |
onChange | (next: string) => void | — | Called with the new code, after every edit. |
onComplete | (full: string) => void | — | Called with the code each time it comes to fill every cell. |
mask | boolean | false | Hides the characters, as a password field does. |
variant | 'numeric' | 'alphanumeric' | — | Canonical structural variant. |
type | 'numeric' | 'alphanumeric' | — | Deprecated. Use variant instead. Retained as alias for one minor. |
autoFocus | boolean | false | Focuses the first cell once mounted. |
separator | React.ReactNode | — | Shown between two cells, hidden from assistive technology. |
size | 'sm' | 'md' | 'lg' | 'md' | Cell size. |
surface | 'pixel' | 'linear' | — | Surface override; defaults to the nearest provider. |
name | string | — | Form field name — a hidden input submits the code. |
disabled | boolean | false | Disables every cell. |
ref points to <input>.
WCAG target: 2.1 AA
role="group" with aria-label for the cell collectionper-cell aria-label indicating digit index and totalinputmode=numeric|text matches the accepted character setautocomplete="one-time-code" on the first cell for SMS autofillInvalid characters are silently rejected based on the type prop. The completion event (onComplete, @complete in Vue, (complete) in Angular) fires once when all cells are filled.
| Key | Action | When |
|---|---|---|
| ArrowLeft | Focus previous cell | — |
| ArrowRight | Focus next cell | — |
| Home | Focus first cell | — |
| End | Focus last cell | — |
| Backspace | Clear current cell, or move back and clear previous if empty | — |
| Paste | Distribute sanitized characters across remaining cells | — |
import React from 'react';
import { PixelOTPInput } from '@pxlkit/ui-kit';
export function Default() {
const [value, setValue] = React.useState('')
return <PixelOTPInput length={6} value={value} onChange={setValue} />
}import React from 'react';
import { PixelOTPInput } from '@pxlkit/ui-kit';
export function Default() {
const [value, setValue] = React.useState('')
return <PixelOTPInput length={6} value={value} onChange={setValue} />
}import React from 'react';
import { PixelOTPInput } from '@pxlkit/ui-kit';
export function Numeric4() {
const [value, setValue] = React.useState('')
return (
<PixelOTPInput
length={4}
type="numeric"
value={value}
onChange={setValue}
/>
)
}import React from 'react';
import { PixelOTPInput } from '@pxlkit/ui-kit';
export function Alphanumeric() {
const [value, setValue] = React.useState('')
return (
<PixelOTPInput
length={6}
type="alphanumeric"
value={value}
onChange={setValue}
/>
)
}import React from 'react';
import { PixelOTPInput } from '@pxlkit/ui-kit';
export function Masked() {
const [value, setValue] = React.useState('')
return (
<PixelOTPInput
length={6}
mask
value={value}
onChange={setValue}
/>
)
}import React from 'react';
import { PixelOTPInput } from '@pxlkit/ui-kit';
export function WithSeparator() {
const [value, setValue] = React.useState('')
return (
<PixelOTPInput
length={6}
separator={<span>-</span>}
value={value}
onChange={setValue}
/>
)
}