vue3-pincode-input
Version:
Pincode input component for Vue3 applications.
179 lines (178 loc) • 5.72 kB
JavaScript
(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".vue-pincode-input-wrapper{display:flex;flex-wrap:wrap;row-gap:1rem}.vue-pincode-input-wrapper.is-success .vue-pincode-input{border:1px solid #62c633}.vue-pincode-input-wrapper.is-error .vue-pincode-input{border:1px solid #da3945}.vue-pincode-input-wrapper .vue-pincode-input{text-align:center;vertical-align:middle}.vue-pincode-input-wrapper .vue-pincode-input.default{width:65px;height:65px;border:1px solid #c4c4c4;font-size:1.8rem;transition:all .3s}.vue-pincode-input-wrapper .vue-pincode-input.default:focus{box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}.vue-pincode-input-wrapper .vue-pincode-input.default:not(:last-child){margin-right:.5rem}.vue-pincode-input-wrapper .vue-pincode-input:focus{outline-style:none}")),document.head.appendChild(e)}}catch(p){console.error("vite-plugin-css-injected-by-js",p)}})();
import { openBlock as r, createElementBlock as a, Fragment as c, renderList as h, withDirectives as p, normalizeClass as d, withKeys as f, vModelDynamic as I } from "vue";
const y = (t, e) => {
const s = t.__vccOpts || t;
for (const [n, i] of e)
s[n] = i;
return s;
}, m = {
name: "PincodeInput",
props: {
modelValue: {
type: String,
default: ""
},
digits: {
type: Number,
default: 4
},
placeholder: {
type: String,
default: ""
},
secure: {
type: Boolean,
default: !1
},
autofocus: {
type: Boolean,
default: !1
},
inputClass: {
type: String,
default: ""
},
successClass: {
type: String,
default: ""
},
spacingClass: {
type: String,
default: ""
},
preview: {
type: Number,
default: 0
}
},
data() {
return {
baseRefName: "vue-pincode-input",
focusedInputIndex: 0,
watchers: {},
inputs: this.initialInputs()
};
},
computed: {
inputClasses() {
return [
this.inputClass || "default",
this.isValid ? this.successClass : ""
].join(" ");
},
isValid() {
return this.inputs.join("").length === this.digits;
}
},
mounted() {
this.$nextTick(() => {
this.init(), this.autofocus && this.$refs["vue-pincode-input0"] && this.$refs["vue-pincode-input0"][0].focus();
});
},
beforeDestroy() {
this.unwatchInputs();
},
methods: {
init() {
this.inputs = this.initialInputs();
for (let t in this.inputs)
this.setInputWatcher(t);
},
focusPreviousInput() {
this.focusedInputIndex && this.focusInputByIndex(this.focusedInputIndex - 1);
},
focusNextInput() {
this.focusedInputIndex !== this.digits - 1 && this.focusInputByIndex(this.focusedInputIndex + 1);
},
focusInputByIndex(t) {
const e = `${this.baseRefName}${t}`, s = this.$refs[e];
s && (s[0].focus(), s[0].select()), this.focusedInputIndex = t;
},
hadleKeyDown(t) {
switch (t.keyCode) {
case 37:
return this.focusPreviousInput();
case 39:
return this.focusNextInput();
}
if (this.inputs[this.focusedInputIndex])
return this.inputs[this.focusedInputIndex] = "";
this.preview && this.secure && (t.target.type = "tel", setTimeout(() => {
t.target.type = "password";
}, this.preview));
},
setInputWatcher(t) {
const e = `inputs.${t}`;
this.watchers[e] = this.$watch(
e,
(s, n) => this.hadleInputChange(t, s, n)
);
},
isInputValid(t, e = !0) {
return t ? !!t.match("^\\d{1}$") : e ? t === "" : !1;
},
hadleInputChange(t, e, s) {
if (this.$emit("update:modelValue", this.inputs.join("")), !this.isInputValid(e, !1)) {
this.inputs[t] = "";
return;
}
if (+t === this.digits - 1) {
const n = this.inputs.findIndex((i) => !i);
n !== -1 && this.focusInputByIndex(n);
return;
}
this.focusNextInput();
},
handleFocus(t) {
this.$refs[t][0].setSelectionRange(1, 1);
},
pinfocus(t) {
this.$refs[t][0].focus();
},
hadleDelete(t, e) {
this.inputs[t].length || (this.focusPreviousInput(), e.preventDefault());
},
initialInputs() {
return this.modelValue ? this.modelValue.length <= this.digits ? [
...this.modelValue,
...[...Array(this.digits - this.modelValue.length)].map(() => "")
] : [...this.modelValue.slice(0, this.digits)] : [...Array(this.digits)].map(() => "");
},
reset() {
this.unwatchInputs(), this.init();
},
unwatchInputs() {
Object.keys(this.watchers).forEach((e) => this.watchers[e]());
}
}
}, g = { class: "vue-pincode-input-wrapper" }, w = ["onUpdate:modelValue", "type", "placeholder", "onFocus", "onKeydown"];
function _(t, e, s, n, i, l) {
return r(), a("div", g, [
(r(!0), a(c, null, h(i.inputs, (v, u) => p((r(), a("input", {
key: u,
ref_for: !0,
ref: `${i.baseRefName}${u}`,
"onUpdate:modelValue": (o) => i.inputs[u] = o,
type: s.secure ? "password" : "tel",
placeholder: s.placeholder,
maxlength: "1",
class: d(["vue-pincode-input", [l.inputClasses, s.spacingClass]]),
onFocus: (o) => i.focusedInputIndex = u,
onKeydown: [
f((o) => l.hadleDelete(u, o), ["delete"]),
(o) => l.hadleKeyDown(o, u)
]
}, null, 42, w)), [
[
I,
i.inputs[u],
void 0,
{ trim: !0 }
]
])), 128))
]);
}
const x = /* @__PURE__ */ y(m, [["render", _]]);
export {
x as default
};