rejuvallife/resources/js/@core/app-form-elements/AppOtpInput.vue
2024-10-25 01:02:11 +05:00

79 lines
1.8 KiB
Vue

<script setup>
const props = defineProps({
totalInput: {
type: Number,
required: false,
default: 6,
},
default: {
type: String,
required: false,
default: '',
},
})
const emit = defineEmits(['updateOtp'])
const digits = ref([])
const refOtpComp = ref(null)
digits.value = props.default.split('')
const defaultStyle = { style: 'max-width: 54px; text-align: center;' }
// eslint-disable-next-line sonarjs/cognitive-complexity
const handleKeyDown = (event, index) => {
if (event.code !== 'Tab' && event.code !== 'ArrowRight' && event.code !== 'ArrowLeft')
event.preventDefault()
if (event.code === 'Backspace') {
digits.value[index - 1] = ''
if (refOtpComp.value !== null && index > 1) {
const inputEl = refOtpComp.value.children[index - 2].querySelector('input')
if (inputEl)
inputEl.focus()
}
}
const numberRegExp = /^([0-9])$/
if (numberRegExp.test(event.key)) {
digits.value[index - 1] = event.key
if (refOtpComp.value !== null && index !== 0 && index < refOtpComp.value.children.length) {
const inputEl = refOtpComp.value.children[index].querySelector('input')
if (inputEl)
inputEl.focus()
}
}
emit('updateOtp', digits.value.join(''))
}
</script>
<template>
<div>
<h6 class="text-h6 mb-3">
Type your 6 digit security code
</h6>
<div
ref="refOtpComp"
class="d-flex align-center gap-4"
>
<AppTextField
v-for="i in props.totalInput"
:key="i"
:model-value="digits[i - 1]"
v-bind="defaultStyle"
maxlength="1"
@keydown="handleKeyDown($event, i)"
/>
</div>
</div>
</template>
<style lang="scss">
.v-field__field {
input {
padding: 0.5rem;
font-size: 1.25rem;
text-align: center;
}
}
</style>