An accessible one-time password input for the Octane
renderer, ported from input-otp@1.4.2.
It keeps one native input for keyboard, screen-reader, paste, and mobile autofill
behavior while projecting the value into individually styled slots.
import { useContext, useState } from 'octane'; import { OTPInput, OTPInputContext, REGEXP_ONLY_DIGITS } from '@octanejs/input-otp'; function Slots(_props: {}) @{ const state = useContext(OTPInputContext); const indexes = state.slots.map((_slot, index) => index); <div class="otp-slots"> @for (const index of indexes; key index) { <span data-active={state.slots[index].isActive || undefined}> {state.slots[index].char ?? state.slots[index].placeholderChar ?? '–'} </span> } </div> } export function VerificationCode(_props: {}) @{ const [value, setValue] = useState(''); <OTPInput maxLength={6} value={value} onChange={setValue} pattern={REGEXP_ONLY_DIGITS} aria-label="Verification code" > <Slots /> </OTPInput> }
The root package exports OTPInput, OTPInputContext, the three built-in regexp
patterns, and the OTPInputProps, RenderProps, and SlotProps types. Prop names,
callback payloads, intrinsic input attributes, context/render projection, selection,
paste transformation, completion, password-manager displacement, SSR, and hydration
match the pinned upstream contract. Octane's native input event drives edits
internally; the public callback remains onChange(newValue).
See UPSTREAM.md for provenance and test inventory details. Current verification status is generated from status.json into the repository's bindings status.
License
MIT — derived from input-otp, © Guilherme Rodrigues and contributors.