Components
InputOTP
An accessible, customizable, and composable One-Time Password input component.
InputOTP
Preview
Interactive
Properties
Size
Live Code Snippet
import {
InputOTP,
InputOTPGroup,
InputOTPSlot,
InputOTPSeparator,
} from '@moul-dev/ui';
import { useState } from 'react';
export default function Example() {
const [value, setValue] = useState('');
return (
<InputOTP
value={value}
onChange={setValue} label="One-Time Password" description="Please enter the 6-digit code sent to your phone." errorMessage="The code is invalid."
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
);
}The InputOTP component is a flexible, highly accessible one-time password input component. It is built on top of the headless input-otp library by @guilhermerodz and styled using StyleX.
Import
import {
InputOTP,
InputOTPGroup,
InputOTPSlot,
InputOTPSeparator
} from '@moul-dev/ui';Features
Basic Layout (6-digit)
A standard 6-digit passcode layout utilizing a separator in the middle.
Default (6 Digits with Separator)
Value:
With Form Labels & Description
Invalid State with Error Message
import { useState } from 'react';
import {
InputOTP,
InputOTPGroup,
InputOTPSlot,
InputOTPSeparator
} from '@moul-dev/ui';
export default function Example() {
const [value, setValue] = useState('');
return (
<InputOTP maxLength={6} value={value} onChange={setValue}>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
);
}Label & Helper Text
The component supports standard form control label and description props.
<InputOTP
maxLength={4}
label="Security Code"
description="Enter the 4-digit code sent to your email."
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
</InputOTPGroup>
</InputOTP>Validation State
Marking the input as invalid highlights the slot borders and renders a custom error message.
<InputOTP
maxLength={4}
label="Verification Code"
isInvalid={true}
errorMessage="The verification code you entered is incorrect."
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
</InputOTPGroup>
</InputOTP>Custom Separator
You can provide any React node inside InputOTPSeparator to customize the visual divider.
<InputOTP maxLength={4}>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
</InputOTPGroup>
<InputOTPSeparator>-</InputOTPSeparator>
<InputOTPGroup>
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
</InputOTPGroup>
</InputOTP>