GitHub

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.

Read the original on github.com ↗