InputOtp

InputOtp is used to enter one time passwords.

basic-demo

Usage#

import { InputOtp } from '@primereact/ui/inputotp';
<InputOtp.Root>
    <InputOtp.Text />
</InputOtp.Root>

Examples#

Controlled#

InputOtp can be used as a controlled component with value and onValueChange properties.

Value:
controlled-demo
'use client';
import type { useInputOtpValueChangeEvent } from '@primereact/types/shared/inputotp';
import { Button } from '@primereact/ui/button';
import { InputOtp } from '@primereact/ui/inputotp';
import * as React from 'react';

export default function ControlledDemo() {
    const [value, setValue] = React.useState('');

    return (
        <div className="flex flex-col items-center gap-6">
            <InputOtp.Root value={value} onValueChange={(e: useInputOtpValueChangeEvent) => setValue(e.value)}>
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
            </InputOtp.Root>
            <div className="flex items-center gap-4">
                <span className="text-sm text-muted-color">
                    Value: <strong className="text-color">{value || ''}</strong>
                </span>
                <Button severity="secondary" size="small" onClick={() => setValue('')}>
                    Reset
                </Button>
            </div>
        </div>
    );
}

Mask#

Enable the mask option to hide the values in the input fields.

mask-demo
import { InputOtp } from '@primereact/ui/inputotp';

export default function MaskDemo() {
    return (
        <div className="flex justify-center">
            <InputOtp.Root mask>
                {Array.from({ length: 4 }, (_, index) => (
                    <InputOtp.Text key={index} />
                ))}
            </InputOtp.Root>
        </div>
    );
}

Integer Only#

When integerOnly is present, only integers can be accepted as input.

integer-only-demo
import { InputOtp } from '@primereact/ui/inputotp';

export default function IntegerOnlyDemo() {
    return (
        <div className="flex justify-center">
            <InputOtp.Root integerOnly>
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
            </InputOtp.Root>
        </div>
    );
}

Filled#

Specify the variant property as filled to display the component with a higher visual emphasis than the default outlined style.

filled-demo
import { InputOtp } from '@primereact/ui/inputotp';

export default function FilledDemo() {
    return (
        <div className="flex justify-center">
            <InputOtp.Root variant="filled">
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
            </InputOtp.Root>
        </div>
    );
}

Sizes#

InputOtp provides small and large sizes as alternatives to the base.

sizes-demo
import { InputOtp } from '@primereact/ui/inputotp';

export default function SizesDemo() {
    return (
        <div className="flex flex-col items-center gap-4">
            <InputOtp.Root size="small">
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
            </InputOtp.Root>
            <InputOtp.Root>
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
            </InputOtp.Root>
            <InputOtp.Root size="large">
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
            </InputOtp.Root>
        </div>
    );
}

Disabled#

When disabled is present, the component becomes non-interactive.

disabled-demo
import { InputOtp } from '@primereact/ui/inputotp';

export default function DisabledDemo() {
    return (
        <div className="flex justify-center">
            <InputOtp.Root disabled>
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
                <InputOtp.Text />
            </InputOtp.Root>
        </div>
    );
}

Custom#

Define a template with your own UI elements with bindings to the provided events and attributes to replace the default design.

custom-demo
import { InputOtp } from '@primereact/ui/inputotp';

export default function CustomDemo() {
    return (
        <div className="flex justify-center">
            <InputOtp.Root>
                {Array.from({ length: 4 }, (_, index) => (
                    <InputOtp.Text
                        key={index}
                        className="w-12 h-12 text-3xl text-center bg-transparent border-0 border-b-2 border-surface-300 dark:border-surface-600 rounded-none outline-none transition-colors duration-200 focus:border-primary"
                    />
                ))}
            </InputOtp.Root>
        </div>
    );
}

Sample#

A sample UI implementation with templating and additional elements.

Authenticate Your Account

Please enter the code sent to your phone.

sample-demo
import { Minus } from '@primeicons/react/minus';
import { Button } from '@primereact/ui/button';
import { InputOtp } from '@primereact/ui/inputotp';
import * as React from 'react';

export default function SampleDemo() {
    return (
        <div className="flex justify-center">
            <div className="flex flex-col items-center gap-6">
                <div className="flex flex-col items-center gap-2">
                    <span className="font-bold text-xl">Authenticate Your Account</span>
                    <p className="text-muted-color">Please enter the code sent to your phone.</p>
                </div>
                <InputOtp.Root integerOnly className="gap-0">
                    {Array.from({ length: 6 }, (_, index) => {
                        const inputClasses = [
                            'w-12 h-12 text-lg text-center transition-all duration-200',
                            'border border-surface-300 dark:border-surface-600 bg-transparent rounded-none',
                            'outline-offset-0 outline-transparent transition-[outline-color] duration-200',
                            'text-color',
                            index === 0 || index === 3 ? 'rounded-l-lg' : '',
                            index === 2 || index === 5 ? 'rounded-r-lg' : '',
                            !(index === 2 || index === 5) ? 'border-r-0' : '',
                            'focus:outline-2 focus:outline-primary focus:-outline-offset-2'
                        ].join(' ');

                        return (
                            <React.Fragment key={index}>
                                <InputOtp.Text className={inputClasses} />
                                {index === 2 && (
                                    <div className="px-4 flex items-center">
                                        <Minus />
                                    </div>
                                )}
                            </React.Fragment>
                        );
                    })}
                </InputOtp.Root>
                <div className="flex justify-between self-stretch">
                    <Button variant="link" className="p-0">
                        Resend Code
                    </Button>
                    <Button>Submit Code</Button>
                </div>
            </div>
        </div>
    );
}

Accessibility#

Screen Reader Support#

Input OTP uses a set of InputText components, refer to the InputText component for more information about the screen reader support.

Keyboard Support#

KeyFunction
tabMoves focus to the input otp.
right arrowMoves focus to the next input element.
left arrowMoves focus to the previous input element.
backspaceDeletes the input and moves focus to the previous input element.