first build
This commit is contained in:
-194
@@ -1,194 +0,0 @@
|
||||
import { defineComponent as F, ref as f, computed as K, watch as T, onMounted as $, createElementBlock as h, openBlock as c, createElementVNode as B, createCommentVNode as j, normalizeClass as M, Fragment as R, renderList as N, createBlock as W } from "vue";
|
||||
const H = { style: { display: "flex", "align-items": "center" } }, S = ["type", "inputmode", "placeholder", "disabled", "maxlength", "value"], V = { key: 0 }, q = ["innerHTML"], z = /* @__PURE__ */ F({
|
||||
__name: "single-otp-input",
|
||||
props: {
|
||||
inputType: { default: "tel" },
|
||||
inputmode: { default: "numeric" },
|
||||
value: { default: "" },
|
||||
separator: { default: "" },
|
||||
focus: { type: Boolean, default: !1 },
|
||||
inputClasses: { default: "" },
|
||||
conditionalClass: { default: "" },
|
||||
shouldAutoFocus: { type: Boolean, default: !1 },
|
||||
isLastChild: { type: Boolean, default: !1 },
|
||||
placeholder: { default: "" },
|
||||
isDisabled: { type: Boolean, default: !1 }
|
||||
},
|
||||
emits: ["on-change", "on-keydown", "on-paste", "on-focus", "on-blur"],
|
||||
setup(I, { emit: b }) {
|
||||
const s = I, l = b, i = f(s.value || ""), n = f(null), a = (e) => {
|
||||
const u = e.target.value;
|
||||
return u && u.trim().length > 1 ? (e.clipboardData = {
|
||||
getData: () => u.trim()
|
||||
}, l("on-paste", e)) : l("on-change", u);
|
||||
}, v = (e) => e >= 65 && e <= 90, D = (e) => e >= 48 && e <= 57 || e >= 96 && e <= 105, k = (e) => {
|
||||
s.isDisabled && e.preventDefault();
|
||||
const u = e || window.event, r = u.which ? u.which : u.keyCode;
|
||||
if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
|
||||
l("on-keydown", e);
|
||||
return;
|
||||
}
|
||||
D(r) || s.inputType === "letter-numeric" && v(r) || [8, 9, 13, 37, 39, 46, 86].includes(r) ? l("on-keydown", e) : u.preventDefault();
|
||||
}, m = (e) => l("on-paste", e), d = () => (n.value.select(), l("on-focus")), y = () => l("on-blur"), g = K(
|
||||
() => ["letter-numeric", "number"].includes(s.inputType) ? "text" : s.inputType
|
||||
);
|
||||
return T(
|
||||
() => s.value,
|
||||
(e, u) => {
|
||||
e !== u && (i.value = e);
|
||||
}
|
||||
), T(
|
||||
() => s.focus,
|
||||
(e, u) => {
|
||||
u !== e && n.value && s.focus && (n.value.focus(), n.value.select());
|
||||
}
|
||||
), $(() => {
|
||||
n.value && s.focus && s.shouldAutoFocus && (n.value.focus(), n.value.select());
|
||||
}), (e, u) => (c(), h("div", H, [
|
||||
B("input", {
|
||||
"data-test": "single-input",
|
||||
type: g.value,
|
||||
inputmode: e.inputmode,
|
||||
placeholder: e.placeholder,
|
||||
disabled: e.isDisabled,
|
||||
ref_key: "input",
|
||||
ref: n,
|
||||
min: "0",
|
||||
max: "9",
|
||||
maxlength: e.isLastChild ? 1 : void 0,
|
||||
pattern: "[0-9]",
|
||||
value: i.value,
|
||||
class: M([e.inputClasses, e.conditionalClass, { "is-complete": i.value }]),
|
||||
onInput: a,
|
||||
onKeydown: k,
|
||||
onPaste: m,
|
||||
onFocus: d,
|
||||
onBlur: y
|
||||
}, null, 42, S),
|
||||
!e.isLastChild && e.separator ? (c(), h("span", V, [
|
||||
B("span", { innerHTML: e.separator }, null, 8, q)
|
||||
])) : j("", !0)
|
||||
]));
|
||||
}
|
||||
}), G = {
|
||||
style: { display: "flex" },
|
||||
class: "otp-input-container"
|
||||
}, J = {
|
||||
key: 0,
|
||||
autocomplete: "off",
|
||||
name: "hidden",
|
||||
type: "text",
|
||||
style: { display: "none" }
|
||||
}, Q = 8, U = 37, X = 39, Y = 46, x = /* @__PURE__ */ F({
|
||||
__name: "vue3-otp-input",
|
||||
props: {
|
||||
value: { default: "" },
|
||||
numInputs: { default: 4 },
|
||||
separator: { default: "" },
|
||||
inputClasses: { default: "" },
|
||||
conditionalClass: { default: () => [] },
|
||||
inputType: {},
|
||||
inputmode: { default: "text" },
|
||||
shouldAutoFocus: { type: Boolean, default: !1 },
|
||||
placeholder: { default: () => [] },
|
||||
isDisabled: { type: Boolean, default: !1 },
|
||||
shouldFocusOrder: { type: Boolean }
|
||||
},
|
||||
emits: ["update:value", "on-change", "on-complete"],
|
||||
setup(I, { expose: b, emit: s }) {
|
||||
const l = I, i = s, n = f(0), a = f([]), v = f([]);
|
||||
T(
|
||||
() => l.value,
|
||||
(t) => {
|
||||
if (t.length === l.numInputs || a.value.length === 0) {
|
||||
const o = t.split("");
|
||||
a.value = o;
|
||||
}
|
||||
},
|
||||
{ immediate: !0 }
|
||||
);
|
||||
const D = (t) => {
|
||||
n.value = t;
|
||||
}, k = () => {
|
||||
n.value !== l.numInputs - 1 && (n.value = -1);
|
||||
}, m = () => a.value.join("").length === l.numInputs ? (i("update:value", a.value.join("")), i("on-complete", a.value.join(""))) : "Wait until the user enters the required number of characters", d = (t) => {
|
||||
n.value = Math.max(Math.min(l.numInputs - 1, t), 0);
|
||||
}, y = () => {
|
||||
d(n.value + 1);
|
||||
}, g = () => {
|
||||
d(n.value - 1);
|
||||
}, e = (t) => {
|
||||
v.value = Object.assign([], a.value), a.value[n.value] = t.toString(), v.value.join("") !== a.value.join("") && (i("update:value", a.value.join("")), i("on-change", a.value.join("")), m());
|
||||
}, u = (t) => {
|
||||
t.preventDefault();
|
||||
const o = t.clipboardData.getData("text/plain").slice(0, l.numInputs - n.value).split("");
|
||||
if (l.inputType === "number" && !o.join("").match(/^\d+$/) || l.inputType === "letter-numeric" && !o.join("").match(/^\w+$/))
|
||||
return "Invalid pasted data";
|
||||
const p = a.value.slice(0, n.value).concat(o);
|
||||
return p.slice(0, l.numInputs).forEach(function(O, C) {
|
||||
a.value[C] = O;
|
||||
}), d(p.slice(0, l.numInputs).length), m();
|
||||
}, r = (t) => {
|
||||
e(t), n.value < l.numInputs - 1 && y();
|
||||
}, A = () => {
|
||||
a.value.length > 0 && (i("update:value", ""), i("on-change", "")), a.value = [], n.value = 0;
|
||||
}, P = (t) => {
|
||||
const o = t.split("");
|
||||
o.length === l.numInputs && (a.value = o, i("update:value", a.value.join("")), i("on-complete", a.value.join("")));
|
||||
}, E = (t, o) => {
|
||||
switch (t.keyCode) {
|
||||
case Q:
|
||||
t.preventDefault(), e(""), g();
|
||||
break;
|
||||
case Y:
|
||||
t.preventDefault(), e("");
|
||||
break;
|
||||
case U:
|
||||
t.preventDefault(), g();
|
||||
break;
|
||||
case X:
|
||||
t.preventDefault(), y();
|
||||
break;
|
||||
default:
|
||||
L(o);
|
||||
break;
|
||||
}
|
||||
}, L = (t) => {
|
||||
l.shouldFocusOrder && setTimeout(() => {
|
||||
const o = a.value.join("").length;
|
||||
t - o >= 0 && (n.value = o, a.value[t] = "");
|
||||
}, 100);
|
||||
};
|
||||
return b({
|
||||
clearInput: A,
|
||||
fillInput: P
|
||||
}), (t, o) => (c(), h("div", G, [
|
||||
t.inputType === "password" ? (c(), h("input", J)) : j("", !0),
|
||||
(c(!0), h(R, null, N(t.numInputs, (_, p) => {
|
||||
var O, C;
|
||||
return c(), W(z, {
|
||||
key: p,
|
||||
focus: n.value === p,
|
||||
value: a.value[p],
|
||||
separator: t.separator,
|
||||
"input-type": t.inputType,
|
||||
inputmode: t.inputmode,
|
||||
"input-classes": t.inputClasses,
|
||||
conditionalClass: (O = t.conditionalClass) == null ? void 0 : O[p],
|
||||
"is-last-child": p === t.numInputs - 1,
|
||||
"should-auto-focus": t.shouldAutoFocus,
|
||||
placeholder: (C = t.placeholder) == null ? void 0 : C[p],
|
||||
"is-disabled": t.isDisabled,
|
||||
onOnChange: r,
|
||||
onOnKeydown: (w) => E(w, p),
|
||||
onOnPaste: u,
|
||||
onOnFocus: (w) => D(p),
|
||||
onOnBlur: k
|
||||
}, null, 8, ["focus", "value", "separator", "input-type", "inputmode", "input-classes", "conditionalClass", "is-last-child", "should-auto-focus", "placeholder", "is-disabled", "onOnKeydown", "onOnFocus"]);
|
||||
}), 128))
|
||||
]));
|
||||
}
|
||||
});
|
||||
export {
|
||||
x as default
|
||||
};
|
||||
-74
@@ -1,74 +0,0 @@
|
||||
{
|
||||
"name": "vue3-otp-input",
|
||||
"version": "0.5.40",
|
||||
"description": "A fully customizable, OTP (one-time password) input component built with Vue 3.x and Vue Composition API.",
|
||||
"author": "Ejiro Asiuwhu <ejiroasiuwhu10@gmail.com>",
|
||||
"repository": "https://github.com/ejirocodes/vue3-otp-input",
|
||||
"bugs": {
|
||||
"url": "https://github.com/ejirocodes/vue3-otp-input/issues"
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc && vite build",
|
||||
"preview": "vite preview",
|
||||
"test:unit": "vitest",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --build --force"
|
||||
},
|
||||
"main": "dist/vue3-otp-input.umd.cjs",
|
||||
"module": "dist/vue3-otp-input.js",
|
||||
"browser": "dist/vue3-otp-input.js",
|
||||
"unpkg": "dist/vue3-otp-input.min.js",
|
||||
"files": [
|
||||
"dist/*"
|
||||
],
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/vue3-otp-input.js",
|
||||
"require": "./dist/vue3-otp-input.umd.cjs"
|
||||
}
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.*"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.4.27"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jsdom": "^21.1.6",
|
||||
"@types/node": "^20.12.13",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
"esbuild": "0.21.4",
|
||||
"jsdom": "^24.1.0",
|
||||
"typescript": "~5.4.5",
|
||||
"vite": "^5.2.12",
|
||||
"vite-plugin-dts": "^3.9.1",
|
||||
"vitest": "^1.6.0",
|
||||
"vue-tsc": "^2.0.19"
|
||||
},
|
||||
"keywords": [
|
||||
"vue 3 otp input",
|
||||
"vue otp input",
|
||||
"vue",
|
||||
"vue 3",
|
||||
"vue composition API",
|
||||
"otp",
|
||||
"input",
|
||||
"otp input",
|
||||
"one-time-password",
|
||||
"one-time password",
|
||||
"one time password",
|
||||
"one time password input",
|
||||
"one time password input component",
|
||||
"one time password input component built with vue",
|
||||
"one time password input component built with vue 3",
|
||||
"vue split input"
|
||||
],
|
||||
"license": "MIT",
|
||||
"readme": "README.md"
|
||||
}
|
||||
Reference in New Issue
Block a user