InputOTP

A one-time-code field, one box per digit.

<InputOTP.Root maxLength={6} pattern={REGEXP_ONLY_DIGITS}>
	<InputOTP.Group>
		<InputOTP.Slot index={0} />
		<InputOTP.Slot index={1} />
		<InputOTP.Slot index={2} />
	</InputOTP.Group>
	<InputOTP.Separator />
	<InputOTP.Group>…</InputOTP.Group>
</InputOTP.Root>

Built on input-otp, so it is one real input behind the boxes — paste, autofill from an SMS, and select-all all work.

API

InputOTP.Root

PropTypeDefault
containerClassNamestring
maxLengthnumberrequired
childrenReactNode
noScriptCSSFallbackstring | null
onChange((newValue: string) => unknown)
onComplete((...args: any[]) => unknown)
pasteTransformer((pasted: string) => string)
pushPasswordManagerStrategy"increase-width" | "none"
renderInputOTPRenderFn
textAlign"center" | "left" | "right"
valuestring

Plus the DOM props of the element it renders. Source: input-otp/components/input-otp-root.tsx.

InputOTP.Group

Plus every <div> prop. Source: input-otp/components/input-otp-group.tsx.

InputOTP.Separator

Plus every <div> prop. Source: input-otp/components/input-otp-separator.tsx.

InputOTP.Slot

PropTypeDefault
indexnumberrequired

Plus every <div> prop. Source: input-otp/components/input-otp-slot.tsx.