https://github.com/wobsoriano/vue-input-otp/assets/13049130/c5080f41-f411-4d38-aa57-d04d90c832c3
npm install vue-input-otphttps://github.com/wobsoriano/vue-input-otp/assets/13049130/c5080f41-f411-4d38-aa57-d04d90c832c3
One-time passcode Input. Accessible & unstyled. Based on the React version by guilhermerodz.
``bash`
npm install vue-input-otp
`vue
`
The example below uses tailwindcss, shadcn-vue, tailwind-merge and clsx:
`vue
:maxlength="6"
container-class="group flex items-center has-[:disabled]:opacity-30"
>
`vue
:class="cn(
'relative w-10 h-14 text-[2rem]',
'flex items-center justify-center',
'transition-all duration-300',
'border-border border-y border-r first:border-l first:rounded-l-md last:rounded-r-md',
'group-hover:border-accent-foreground/20 group-focus-within:border-accent-foreground/20',
'outline outline-0 outline-accent-foreground/20',
{ 'outline-4 outline-accent-foreground': isActive },
)"
>
{{ char }}
`ts
import type { ClassValue } from 'clsx'
// tailwind.config.ts for the blinking caret animation.
// Small utility to merge class names.
import { clsx } from 'clsx'import { twMerge } from 'tailwind-merge'
const config = {
theme: {
extend: {
keyframes: {
'caret-blink': {
'0%,70%,100%': { opacity: '1' },
'20%,50%': { opacity: '0' },
},
},
animation: {
'caret-blink': 'caret-blink 1.2s ease-out infinite',
},
},
},
}
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
`How it works
There's currently no native OTP/2FA/MFA input in HTML, which means people are either going with 1. a simple input design or 2. custom designs like this one. This library works by rendering an invisible input as a sibling of the slots, contained by a
relatively positioned parent (the container root called OTPInput).API Reference
$3
The root container. Define settings for the input via props. Then, pass in child elements to create the slots.
##### Props
|Name|Description|Type|Values|Default|
|:----|:----|:----|:----|:----|
|
maxlength|The number of slots.|number|-|-|
|containerClass|The class for the root container.|string|-|-|
|textAlign|Where is the text located within the input. Affects click-holding or long-press behavior.|string|left, right, center|center|
|inputmode|Virtual keyboard appearance on mobile.|string|numeric, text|numeric|
|pushPasswordManagerStrategy|Detect Password Managers and shift their badges to the right side, outside the input.|string|increase-width, none|increase-width|#### Slots
|Name|Description|Props|
|:----|:----|:----|
|
default|The slots to be rendered.|slots: SlotProps[], isFocused: boolean, isHovering: boolean|#### Events
|Name|Description|Parameters|
|:----|:----|:----|
|
complete|Emitted when the input is complete.|value: string|Examples
Automatic form submission on OTP completion
`vue
`
Automatically focus the input when the page loads
`vue
``See list of caveats in the original implementation here.
MIT