Simple but effective Otp input (for Vue2 only)
This sounds simple to do, but hard to make it works correctly and handles all the cases for otp. Based on my expericences with the existing libs, I created this to handle all my needs. Hope it helps you as well.
Video for autofill in mobile page (from friends)
| Safari | Chrome | On/off focus suggestion |
|---|---|---|
Screen shot for tests and test coverage:

yarn add vue-simple-otp-input
import SimpleOtpInput from "vue-simple-otp-input";
Look at the App.vue for more detail, or try it here
<section class="story">
<label>Default otp input</label>
<SimpleOtpInput />
</section>
<section class="story">
<label>Password type input</label>
<SimpleOtpInput type="password" :length="4" />
</section>
<section class="story">
<label>With inital value</label>
<SimpleOtpInput value="123456" />
</section>
<section class="story">
<label>With events</label>
<SimpleOtpInput
type="password"
:length="4"
@change="handleChange"
@complete="handleComplete"
/>
<div><strong>Draft</strong> </div>
<div><strong>Submitted</strong> </div>
</section>
<section class="story">
<label>Lazy v-model </label>
<button @click="setLazyCodeValue">Randomize code value</button>
<SimpleOtpInput v-model="lazyCode" />
</section>
<section class="story">
<label>With extra slot to create border effect</label>
<SimpleOtpInput
class="otp-with-effect"
inputClasses="input-with-effect"
:pasteDelayMs="192"
withWebOtp
>
<template v-slot:extra>
<span class="focus-border">
<i></i>
</span>
</template>
</SimpleOtpInput>
</section>
| Prop | Default | Description |
|---|---|---|
| length | 6 |
Length of this otp input |
| value | '' |
Value for this input, v-model is supported, in rare cases, you may need to use setOtpValue to force update internal state |
| type | 'text' |
Html input type of each input, you may find 'password' useful |
| inputClasses | '' |
Inner input classess, allow you to fully control input styles |
| pasteDelayMs | 0 |
Delay for pasting content, we may want to let the animation to take effect on pasting |
| withWebOtp | false |
Should we enable WebOtp setup when browser is supported |
| withExtraSpan | false |
Just like extra slot, but enabled via a flag and no customization |
| inputProps | {} |
Custom input props will be set to all input, totally control edge cases |
| Event | Description |
|---|---|
| input | Emit on every change on otp input, support v-model |
| change | Emit on every update on otp input |
| complete | Emit on key enter, emitted otp may not complete |
{ idx, otp, length } to allow fully customization.vue-simple-otp-input/dist/vue-simple-otp-input.css to your component..simple-otp-input {
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.otp-single-input {
padding: 4px;
width: 2em;
height: 2em;
text-align: center;
}
.single-input-container {
position: relative;
z-index: 1;
margin: 2px;
}
/* To grab suggestion input in IOS */
.simple-otp-input .hidden-otp-input {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
box-sizing: border-box;
pointer-events: none;
}
.simple-otp-input.empty .single-input-container {
z-index: 0;
}
.simple-otp-input.empty .hidden-otp-input {
z-index: 1;
pointer-events: initial;
}