Gathering detailed insights and metrics for vue-input-otp
Gathering detailed insights and metrics for vue-input-otp
Gathering detailed insights and metrics for vue-input-otp
Gathering detailed insights and metrics for vue-input-otp
react-otp-input
A fully customizable, one-time password input component for the web built with React
vue3-otp-input
A fully customizable, OTP (one-time password) input component built with Vue 3.x and Vue Composition API.
input-otp
One-time password input component for React.
ng-otp-input
A fully customizable, one-time password input component for the web built with Angular.
npm install vue-input-otp
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
67 Stars
136 Commits
2 Forks
2 Watching
5 Branches
3 Contributors
Updated on 26 Nov 2024
Minified
Minified + Gzipped
Vue (64.56%)
TypeScript (27.35%)
JavaScript (6.11%)
CSS (1.98%)
Cumulative downloads
Total Downloads
Last day
140%
36
Compared to previous day
Last week
-22.6%
164
Compared to previous week
Last month
39.9%
701
Compared to previous month
Last year
0%
4,320
Compared to previous year
1
https://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.
1npm install vue-input-otp
1<script setup lang="ts"> 2import { OTPInput } from 'vue-input-otp' 3import Slot from './Slot.vue' 4 5const input = ref('123456') 6</script> 7 8<template> 9 <form> 10 <OTPInput v-slot="{ slots }" v-model="input" :maxlength="6"> 11 <!-- slots --> 12 </OTPInput> 13 </form> 14</template>
The example below uses tailwindcss
, shadcn-vue
, tailwind-merge
and clsx
:
1<script setup lang="ts"> 2import { OTPInput } from 'vue-input-otp' 3import Slot from './Slot.vue' 4</script> 5 6<template> 7 <OTPInput 8 v-slot="{ slots }" 9 :maxlength="6" 10 container-class="group flex items-center has-[:disabled]:opacity-30" 11 > 12 <div class="flex"> 13 <Slot v-for="(slot, idx) in slots.slice(0, 3)" v-bind="slot" :key="idx" /> 14 </div> 15 16 <!-- Fake Dash. Inspired by Stripe's MFA input. --> 17 <div class="flex w-10 justify-center items-center"> 18 <div class="w-3 h-1 rounded-full bg-border" /> 19 </div> 20 21 <div class="flex"> 22 <Slot v-for="(slot, idx) in slots.slice(3)" v-bind="slot" :key="idx" /> 23 </div> 24 </OTPInput> 25</template>
1<script setup lang="ts"> 2import type { SlotProps } from 'vue-input-otp' 3import { cn } from '$lib/utils' 4 5defineProps<SlotProps>() 6</script> 7 8<template> 9 <div 10 :class="cn( 11 'relative w-10 h-14 text-[2rem]', 12 'flex items-center justify-center', 13 'transition-all duration-300', 14 'border-border border-y border-r first:border-l first:rounded-l-md last:rounded-r-md', 15 'group-hover:border-accent-foreground/20 group-focus-within:border-accent-foreground/20', 16 'outline outline-0 outline-accent-foreground/20', 17 { 'outline-4 outline-accent-foreground': isActive }, 18 )" 19 > 20 <div v-if="char !== null"> 21 {{ char }} 22 </div> 23 24 <!-- Emulate a Fake Caret --> 25 <div v-if="char === null && isActive" class="absolute pointer-events-none inset-0 flex items-center justify-center animate-caret-blink"> 26 <div class="w-px h-8 bg-white" /> 27 </div> 28 </div> 29</template>
1// tailwind.config.ts for the blinking caret animation. 2// Small utility to merge class names. 3import { clsx } from 'clsx' 4import { twMerge } from 'tailwind-merge' 5 6import type { ClassValue } from 'clsx' 7 8const config = { 9 theme: { 10 extend: { 11 keyframes: { 12 'caret-blink': { 13 '0%,70%,100%': { opacity: '1' }, 14 '20%,50%': { opacity: '0' }, 15 }, 16 }, 17 animation: { 18 'caret-blink': 'caret-blink 1.2s ease-out infinite', 19 }, 20 }, 21 }, 22} 23 24export function cn(...inputs: ClassValue[]) { 25 return twMerge(clsx(inputs)) 26}
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 relative
ly positioned parent (the container root called OTPInput).
The root container. Define settings for the input via props. Then, pass in child elements to create the slots.
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 |
Name | Description | Props |
---|---|---|
default | The slots to be rendered. | slots: SlotProps[], isFocused: boolean, isHovering: boolean |
Name | Description | Parameters |
---|---|---|
complete | Emitted when the input is complete. | value: string |
1<script setup> 2import { OTPInput } from 'vue-input-otp' 3import { ref } from 'vue' 4 5const formRef = ref() 6const buttonRef = ref() 7 8function onComplete() { 9 // ... automatically submit the form 10 formRef.value.submit() 11 // ... or focus the button like as you wish 12 buttonRef.value.focus() 13} 14</script> 15 16<template> 17 <form ref="formRef"> 18 <OTPInput @complete="onComplete" /> 19 <button ref="buttonRef"> 20 Submit 21 </button> 22 </form> 23</template>
1<script setup> 2import { OTPInput } from 'vue-input-otp' 3</script> 4 5<template> 6 <form> 7 <!-- Pro tip: accepts all common HTML input props... --> 8 <OTPInput auto-focus /> 9 </form> 10</template>
See list of caveats in the original implementation here.
MIT
No vulnerabilities found.
No security vulnerabilities found.