apps/design-system/content/docs/components/input-otp.mdx
Input OTP is built on top of input-otp by @guilherme_rodz.
<Step>Run the following command:</Step>
npx shadcn-ui@latest add input-otp
<Step>Update tailwind.config.js</Step>
Add the following animations to your tailwind.config.js file:
/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
extend: {
keyframes: {
'caret-blink': {
'0%,70%,100%': { opacity: '1' },
'20%,50%': { opacity: '0' },
},
},
animation: {
'caret-blink': 'caret-blink 1.25s ease-out infinite',
},
},
},
}
<Step>Install the following dependencies:</Step>
npm install input-otp
<Step>Copy and paste the following code into your project.</Step>
<ComponentSource name="input-otp" /><Step>Update the import paths to match your project setup.</Step>
<Step>Update tailwind.config.js</Step>
Add the following animations to your tailwind.config.js file:
/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
extend: {
keyframes: {
'caret-blink': {
'0%,70%,100%': { opacity: '1' },
'20%,50%': { opacity: '0' },
},
},
animation: {
'caret-blink': 'caret-blink 1.25s ease-out infinite',
},
},
},
}
import { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from '@/components/ui/input-otp'
<InputOTP maxLength={6}>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
Use the pattern prop to define a custom pattern for the OTP input.
import { REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp"
...
<InputOTP
maxLength={6}
pattern={REGEXP_ONLY_DIGITS_AND_CHARS}
>
<InputOTPGroup>
<InputOTPSlot index={0} />
</InputOTPGroup>
</InputOTP>
You can use the <InputOTPSeparator /> component to add a separator between the input groups.
import {
InputOTP,
InputOTPGroup,
InputOTPSeparator,
InputOTPSlot,
} from "@/components/ui/input-otp"
...
<InputOTP maxLength={4}>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
</InputOTPGroup>
</InputOTP>
You can use the value and onChange props to control the input value.