Forms and dates
useInputOTP
Builds an Astro-compatible OTP field with a native input, visual segments, sanitized values, and caret navigation.
Live component preview · Astro
Explore InputOTP
Try the component this hook connects to. The preview uses the Astro adapter; the React example below uses useInputOTP.
Paste the full code, or move through digits with Arrow Left / Arrow Right.
React usage
Import from @santi020k/lumen-react and spread the controller props onto the matching components.
import { useInputOTP } from '@santi020k/lumen-react'
export function VerificationCode() {
const otp = useInputOTP({ length: 6, defaultValue: '123456' })
return (
<div {...otp.rootProps}>
<input aria-label="Verification code" name="code" {...otp.getInputProps()} />
<div {...otp.segmentsProps}>
{otp.segmentIndexes.map(index => (
<button key={index} {...otp.getSegmentProps(index)}>
<span data-ui-input-otp-char>{otp.getSegmentChar(index)}</span>
</button>
))}
</div>
</div>
)
}import { useInputOTP } from '@santi020k/lumen-react'
export function VerificationCode() {
const otp = useInputOTP({ length: 6, defaultValue: '123456' })
return (
<div {...otp.rootProps}>
<input aria-label="Verification code" name="code" {...otp.getInputProps()} />
<div {...otp.segmentsProps}>
{otp.segmentIndexes.map(index => (
<button key={index} {...otp.getSegmentProps(index)}>
<span data-ui-input-otp-char>{otp.getSegmentChar(index)}</span>
</button>
))}
</div>
</div>
)
}Load @santi020k/lumen-react/styles.css once in your application. With React Server Components, put 'use client' at the top of the module that calls the hook. Follow the React setup guide for the framework boundary.
Options
| Property | Type | Default | Description |
|---|---|---|---|
| length | number | 6 | Number of visible OTP segments. |
| value | string | - | Controlled OTP value. |
| defaultValue | string | "" | Initial value for uncontrolled usage. |
| onValueChange | (value: string) => void | - | Callback fired when input or paste changes the sanitized value. |
| inputMode | string | "numeric" | Native inputMode forwarded to the hidden input. Numeric mode removes non-digits. |
| pattern | string | "[0-9]*" | Native pattern forwarded to the hidden input. |
Controller return values
| Property | Type | Description |
|---|---|---|
| rootProps | LumenProps<"div"> | Spread onto the OTP field root. |
| getInputProps | (props?) => LumenProps<"input"> | Returns props for the native input. |
| segmentsProps | LumenProps<"div"> | Spread onto the visual segment container. |
| getSegmentProps | (index, props?) => LumenProps<"button"> | Returns props for a visual segment button. |
| getSegmentChar | (index) => string | Returns the character or blank placeholder for a segment. |
| setValue | (value) => string | Sanitize and set the current OTP value. |