@a-drowned-fish/rox-v 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -0
- package/dist/index.iife.js +1 -0
- package/dist/index.js +75 -0
- package/dist/index.umd.cjs +1 -0
- package/dist/style.css +1 -0
- package/es/components.d.ts +1 -0
- package/es/components.js +69 -0
- package/es/index.d.ts +9 -0
- package/es/index.js +75 -0
- package/es/input-otp/index.css +28 -0
- package/es/input-otp/index.d.ts +3 -0
- package/es/input-otp/index.js +89 -0
- package/es/input-otp/input-otp.vue.d.ts +23 -0
- package/lib/components.d.ts +1 -0
- package/lib/components.js +1 -0
- package/lib/index.d.ts +9 -0
- package/lib/index.js +1 -0
- package/lib/input-otp/index.css +28 -0
- package/lib/input-otp/index.d.ts +3 -0
- package/lib/input-otp/index.js +89 -0
- package/lib/input-otp/input-otp.vue.d.ts +23 -0
- package/package.json +77 -0
- package/resolver/resolver.cjs +25 -0
- package/resolver/resolver.d.ts +13 -0
- package/resolver/resolver.js +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# @a-drowned-fish/rox-v
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
|
|
5
|
+
### Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm add @a-drowned-fish/rox-v
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Import all components
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { createApp } from "vue";
|
|
15
|
+
import RoxV from "@a-drowned-fish/rox-v";
|
|
16
|
+
import "@a-drowned-fish/rox-v/dist/style.css";
|
|
17
|
+
|
|
18
|
+
const app = createApp(App);
|
|
19
|
+
app.use(RoxV);
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Tree-shakable import
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { InputOtp } from "@a-drowned-fish/rox-v";
|
|
26
|
+
import "@a-drowned-fish/rox-v/es/input-otp/index.css";
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Auto Import
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
// vite.config.ts
|
|
33
|
+
import { defineConfig } from "vite";
|
|
34
|
+
import vue from "@vitejs/plugin-vue";
|
|
35
|
+
import Components from "unplugin-vue-components/vite";
|
|
36
|
+
import { RoxVResolver } from "@a-drowned-fish/rox-v/resolver";
|
|
37
|
+
|
|
38
|
+
// https://vitejs.dev/config/
|
|
39
|
+
export default defineConfig({
|
|
40
|
+
plugins: [
|
|
41
|
+
vue(),
|
|
42
|
+
Components({
|
|
43
|
+
resolvers: [RoxVResolver()],
|
|
44
|
+
}),
|
|
45
|
+
],
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## License
|
|
50
|
+
|
|
51
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var RoxV=function(c,e){"use strict";const f=["maxlength"],p=((o,r)=>{const l=o.__vccOpts||o;for(const[s,i]of r)l[s]=i;return l})(e.defineComponent({__name:"input-otp",props:{modelValue:{default:""},length:{default:6},itemClass:{default:""},activeItemClass:{default:""},gap:{default:"10px"}},emits:["update:modelValue","complete"],setup(o,{emit:r}){const l=o,s=r,i=e.ref(null),a=e.ref(l.modelValue);e.watch(()=>l.modelValue,n=>{n!==a.value&&(a.value=n)});function _(n){let t=n.target.value;t=t.replace(/\D/g,""),t=t.slice(0,l.length),a.value=t,s("update:modelValue",t),t.length===l.length&&s("complete",t)}function h(){var n;(n=i.value)==null||n.focus()}function m(n){return n===a.value.length}return(n,t)=>(e.openBlock(),e.createElementBlock("div",{class:"otp-wrapper",onClick:h},[e.withDirectives(e.createElementVNode("input",{inputmode:"numeric",autocomplete:"one-time-code",ref_key:"inputRef",ref:i,"onUpdate:modelValue":t[0]||(t[0]=d=>a.value=d),maxlength:o.length,onInput:_,class:"otp-input"},null,40,f),[[e.vModelText,a.value]]),e.createElementVNode("div",{class:"otp-box",style:e.normalizeStyle({gap:l.gap})},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o.length,(d,u)=>(e.openBlock(),e.createElementBlock("div",{key:u,class:e.normalizeClass(["otp-item",[{active:m(u),[l.activeItemClass]:m(u)},l.itemClass]])},e.toDisplayString(a.value[u]||""),3))),128))],4)]))}}),[["__scopeId","data-v-14ecb7bd"]]),g={version:"1.0.0",install:o=>{o.component("RInputOtp",p)}};return c.InputOtp=p,c.default=g,Object.defineProperties(c,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}}),c}({},Vue);
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { defineComponent as h, ref as d, watch as _, openBlock as i, createElementBlock as p, withDirectives as I, createElementVNode as f, vModelText as V, normalizeStyle as C, Fragment as k, renderList as x, normalizeClass as y, toDisplayString as b } from "vue";
|
|
2
|
+
const w = ["maxlength"], D = /* @__PURE__ */ h({
|
|
3
|
+
__name: "input-otp",
|
|
4
|
+
props: {
|
|
5
|
+
modelValue: { default: "" },
|
|
6
|
+
length: { default: 6 },
|
|
7
|
+
itemClass: { default: "" },
|
|
8
|
+
activeItemClass: { default: "" },
|
|
9
|
+
gap: { default: "10px" }
|
|
10
|
+
},
|
|
11
|
+
emits: ["update:modelValue", "complete"],
|
|
12
|
+
setup(n, { emit: c }) {
|
|
13
|
+
const t = n, o = c, u = d(null), a = d(t.modelValue);
|
|
14
|
+
_(
|
|
15
|
+
() => t.modelValue,
|
|
16
|
+
(l) => {
|
|
17
|
+
l !== a.value && (a.value = l);
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
function v(l) {
|
|
21
|
+
let e = l.target.value;
|
|
22
|
+
e = e.replace(/\D/g, ""), e = e.slice(0, t.length), a.value = e, o("update:modelValue", e), e.length === t.length && o("complete", e);
|
|
23
|
+
}
|
|
24
|
+
function g() {
|
|
25
|
+
var l;
|
|
26
|
+
(l = u.value) == null || l.focus();
|
|
27
|
+
}
|
|
28
|
+
function r(l) {
|
|
29
|
+
return l === a.value.length;
|
|
30
|
+
}
|
|
31
|
+
return (l, e) => (i(), p("div", {
|
|
32
|
+
class: "otp-wrapper",
|
|
33
|
+
onClick: g
|
|
34
|
+
}, [
|
|
35
|
+
I(f("input", {
|
|
36
|
+
inputmode: "numeric",
|
|
37
|
+
autocomplete: "one-time-code",
|
|
38
|
+
ref_key: "inputRef",
|
|
39
|
+
ref: u,
|
|
40
|
+
"onUpdate:modelValue": e[0] || (e[0] = (m) => a.value = m),
|
|
41
|
+
maxlength: n.length,
|
|
42
|
+
onInput: v,
|
|
43
|
+
class: "otp-input"
|
|
44
|
+
}, null, 40, w), [
|
|
45
|
+
[V, a.value]
|
|
46
|
+
]),
|
|
47
|
+
f("div", {
|
|
48
|
+
class: "otp-box",
|
|
49
|
+
style: C({ gap: t.gap })
|
|
50
|
+
}, [
|
|
51
|
+
(i(!0), p(k, null, x(n.length, (m, s) => (i(), p("div", {
|
|
52
|
+
key: s,
|
|
53
|
+
class: y(["otp-item", [
|
|
54
|
+
{ active: r(s), [t.activeItemClass]: r(s) },
|
|
55
|
+
t.itemClass
|
|
56
|
+
]])
|
|
57
|
+
}, b(a.value[s] || ""), 3))), 128))
|
|
58
|
+
], 4)
|
|
59
|
+
]));
|
|
60
|
+
}
|
|
61
|
+
}), O = (n, c) => {
|
|
62
|
+
const t = n.__vccOpts || n;
|
|
63
|
+
for (const [o, u] of c)
|
|
64
|
+
t[o] = u;
|
|
65
|
+
return t;
|
|
66
|
+
}, R = /* @__PURE__ */ O(D, [["__scopeId", "data-v-14ecb7bd"]]), z = "1.0.0", B = (n) => {
|
|
67
|
+
n.component("RInputOtp", R);
|
|
68
|
+
}, S = {
|
|
69
|
+
version: z,
|
|
70
|
+
install: B
|
|
71
|
+
};
|
|
72
|
+
export {
|
|
73
|
+
R as InputOtp,
|
|
74
|
+
S as default
|
|
75
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(o,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(o=typeof globalThis<"u"?globalThis:o||self,e(o.RoxV={},o.Vue))})(this,function(o,e){"use strict";const f=["maxlength"],r=((a,p)=>{const n=a.__vccOpts||a;for(const[s,c]of p)n[s]=c;return n})(e.defineComponent({__name:"input-otp",props:{modelValue:{default:""},length:{default:6},itemClass:{default:""},activeItemClass:{default:""},gap:{default:"10px"}},emits:["update:modelValue","complete"],setup(a,{emit:p}){const n=a,s=p,c=e.ref(null),i=e.ref(n.modelValue);e.watch(()=>n.modelValue,l=>{l!==i.value&&(i.value=l)});function _(l){let t=l.target.value;t=t.replace(/\D/g,""),t=t.slice(0,n.length),i.value=t,s("update:modelValue",t),t.length===n.length&&s("complete",t)}function h(){var l;(l=c.value)==null||l.focus()}function d(l){return l===i.value.length}return(l,t)=>(e.openBlock(),e.createElementBlock("div",{class:"otp-wrapper",onClick:h},[e.withDirectives(e.createElementVNode("input",{inputmode:"numeric",autocomplete:"one-time-code",ref_key:"inputRef",ref:c,"onUpdate:modelValue":t[0]||(t[0]=m=>i.value=m),maxlength:a.length,onInput:_,class:"otp-input"},null,40,f),[[e.vModelText,i.value]]),e.createElementVNode("div",{class:"otp-box",style:e.normalizeStyle({gap:n.gap})},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(a.length,(m,u)=>(e.openBlock(),e.createElementBlock("div",{key:u,class:e.normalizeClass(["otp-item",[{active:d(u),[n.activeItemClass]:d(u)},n.itemClass]])},e.toDisplayString(i.value[u]||""),3))),128))],4)]))}}),[["__scopeId","data-v-14ecb7bd"]]),g={version:"1.0.0",install:a=>{a.component("RInputOtp",r)}};o.InputOtp=r,o.default=g,Object.defineProperties(o,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.otp-wrapper[data-v-14ecb7bd]{position:relative;width:max-content;cursor:pointer}.otp-input[data-v-14ecb7bd]{position:absolute;opacity:0;pointer-events:none}.otp-box[data-v-14ecb7bd]{display:flex}.otp-item[data-v-14ecb7bd]{width:40px;height:50px;border:1px solid #ccc;border-radius:8px;text-align:center;line-height:50px;font-size:20px;transition:all .2s}.otp-item.active[data-v-14ecb7bd]{border-color:#409eff;box-shadow:0 0 0 2px #409eff33}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { InputOtp } from './components/input-otp';
|
package/es/components.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { defineComponent as h, ref as d, watch as _, openBlock as i, createElementBlock as p, withDirectives as V, createElementVNode as f, vModelText as C, normalizeStyle as I, Fragment as k, renderList as y, normalizeClass as x, toDisplayString as b } from "vue";
|
|
2
|
+
const w = ["maxlength"], D = /* @__PURE__ */ h({
|
|
3
|
+
__name: "input-otp",
|
|
4
|
+
props: {
|
|
5
|
+
modelValue: { default: "" },
|
|
6
|
+
length: { default: 6 },
|
|
7
|
+
itemClass: { default: "" },
|
|
8
|
+
activeItemClass: { default: "" },
|
|
9
|
+
gap: { default: "10px" }
|
|
10
|
+
},
|
|
11
|
+
emits: ["update:modelValue", "complete"],
|
|
12
|
+
setup(a, { emit: c }) {
|
|
13
|
+
const t = a, o = c, u = d(null), n = d(t.modelValue);
|
|
14
|
+
_(
|
|
15
|
+
() => t.modelValue,
|
|
16
|
+
(l) => {
|
|
17
|
+
l !== n.value && (n.value = l);
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
function v(l) {
|
|
21
|
+
let e = l.target.value;
|
|
22
|
+
e = e.replace(/\D/g, ""), e = e.slice(0, t.length), n.value = e, o("update:modelValue", e), e.length === t.length && o("complete", e);
|
|
23
|
+
}
|
|
24
|
+
function g() {
|
|
25
|
+
var l;
|
|
26
|
+
(l = u.value) == null || l.focus();
|
|
27
|
+
}
|
|
28
|
+
function r(l) {
|
|
29
|
+
return l === n.value.length;
|
|
30
|
+
}
|
|
31
|
+
return (l, e) => (i(), p("div", {
|
|
32
|
+
class: "otp-wrapper",
|
|
33
|
+
onClick: g
|
|
34
|
+
}, [
|
|
35
|
+
V(f("input", {
|
|
36
|
+
inputmode: "numeric",
|
|
37
|
+
autocomplete: "one-time-code",
|
|
38
|
+
ref_key: "inputRef",
|
|
39
|
+
ref: u,
|
|
40
|
+
"onUpdate:modelValue": e[0] || (e[0] = (m) => n.value = m),
|
|
41
|
+
maxlength: a.length,
|
|
42
|
+
onInput: v,
|
|
43
|
+
class: "otp-input"
|
|
44
|
+
}, null, 40, w), [
|
|
45
|
+
[C, n.value]
|
|
46
|
+
]),
|
|
47
|
+
f("div", {
|
|
48
|
+
class: "otp-box",
|
|
49
|
+
style: I({ gap: t.gap })
|
|
50
|
+
}, [
|
|
51
|
+
(i(!0), p(k, null, y(a.length, (m, s) => (i(), p("div", {
|
|
52
|
+
key: s,
|
|
53
|
+
class: x(["otp-item", [
|
|
54
|
+
{ active: r(s), [t.activeItemClass]: r(s) },
|
|
55
|
+
t.itemClass
|
|
56
|
+
]])
|
|
57
|
+
}, b(n.value[s] || ""), 3))), 128))
|
|
58
|
+
], 4)
|
|
59
|
+
]));
|
|
60
|
+
}
|
|
61
|
+
}), z = (a, c) => {
|
|
62
|
+
const t = a.__vccOpts || a;
|
|
63
|
+
for (const [o, u] of c)
|
|
64
|
+
t[o] = u;
|
|
65
|
+
return t;
|
|
66
|
+
}, E = /* @__PURE__ */ z(D, [["__scopeId", "data-v-14ecb7bd"]]);
|
|
67
|
+
export {
|
|
68
|
+
E as InputOtp
|
|
69
|
+
};
|
package/es/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { App } from 'vue';
|
|
2
|
+
import { default as InputOtp } from './components/input-otp/input-otp.vue';
|
|
3
|
+
export * from './components';
|
|
4
|
+
export { InputOtp };
|
|
5
|
+
declare const _default: {
|
|
6
|
+
version: string;
|
|
7
|
+
install: (app: App) => void;
|
|
8
|
+
};
|
|
9
|
+
export default _default;
|
package/es/index.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { defineComponent as h, ref as d, watch as _, openBlock as i, createElementBlock as p, withDirectives as I, createElementVNode as f, vModelText as V, normalizeStyle as C, Fragment as k, renderList as x, normalizeClass as y, toDisplayString as b } from "vue";
|
|
2
|
+
const w = ["maxlength"], D = /* @__PURE__ */ h({
|
|
3
|
+
__name: "input-otp",
|
|
4
|
+
props: {
|
|
5
|
+
modelValue: { default: "" },
|
|
6
|
+
length: { default: 6 },
|
|
7
|
+
itemClass: { default: "" },
|
|
8
|
+
activeItemClass: { default: "" },
|
|
9
|
+
gap: { default: "10px" }
|
|
10
|
+
},
|
|
11
|
+
emits: ["update:modelValue", "complete"],
|
|
12
|
+
setup(n, { emit: c }) {
|
|
13
|
+
const t = n, o = c, u = d(null), a = d(t.modelValue);
|
|
14
|
+
_(
|
|
15
|
+
() => t.modelValue,
|
|
16
|
+
(l) => {
|
|
17
|
+
l !== a.value && (a.value = l);
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
function v(l) {
|
|
21
|
+
let e = l.target.value;
|
|
22
|
+
e = e.replace(/\D/g, ""), e = e.slice(0, t.length), a.value = e, o("update:modelValue", e), e.length === t.length && o("complete", e);
|
|
23
|
+
}
|
|
24
|
+
function g() {
|
|
25
|
+
var l;
|
|
26
|
+
(l = u.value) == null || l.focus();
|
|
27
|
+
}
|
|
28
|
+
function r(l) {
|
|
29
|
+
return l === a.value.length;
|
|
30
|
+
}
|
|
31
|
+
return (l, e) => (i(), p("div", {
|
|
32
|
+
class: "otp-wrapper",
|
|
33
|
+
onClick: g
|
|
34
|
+
}, [
|
|
35
|
+
I(f("input", {
|
|
36
|
+
inputmode: "numeric",
|
|
37
|
+
autocomplete: "one-time-code",
|
|
38
|
+
ref_key: "inputRef",
|
|
39
|
+
ref: u,
|
|
40
|
+
"onUpdate:modelValue": e[0] || (e[0] = (m) => a.value = m),
|
|
41
|
+
maxlength: n.length,
|
|
42
|
+
onInput: v,
|
|
43
|
+
class: "otp-input"
|
|
44
|
+
}, null, 40, w), [
|
|
45
|
+
[V, a.value]
|
|
46
|
+
]),
|
|
47
|
+
f("div", {
|
|
48
|
+
class: "otp-box",
|
|
49
|
+
style: C({ gap: t.gap })
|
|
50
|
+
}, [
|
|
51
|
+
(i(!0), p(k, null, x(n.length, (m, s) => (i(), p("div", {
|
|
52
|
+
key: s,
|
|
53
|
+
class: y(["otp-item", [
|
|
54
|
+
{ active: r(s), [t.activeItemClass]: r(s) },
|
|
55
|
+
t.itemClass
|
|
56
|
+
]])
|
|
57
|
+
}, b(a.value[s] || ""), 3))), 128))
|
|
58
|
+
], 4)
|
|
59
|
+
]));
|
|
60
|
+
}
|
|
61
|
+
}), O = (n, c) => {
|
|
62
|
+
const t = n.__vccOpts || n;
|
|
63
|
+
for (const [o, u] of c)
|
|
64
|
+
t[o] = u;
|
|
65
|
+
return t;
|
|
66
|
+
}, R = /* @__PURE__ */ O(D, [["__scopeId", "data-v-14ecb7bd"]]), z = "1.0.0", B = (n) => {
|
|
67
|
+
n.component("RInputOtp", R);
|
|
68
|
+
}, S = {
|
|
69
|
+
version: z,
|
|
70
|
+
install: B
|
|
71
|
+
};
|
|
72
|
+
export {
|
|
73
|
+
R as InputOtp,
|
|
74
|
+
S as default
|
|
75
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
.otp-wrapper[data-v-14ecb7bd] {
|
|
3
|
+
position: relative;
|
|
4
|
+
width: max-content;
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
}
|
|
7
|
+
.otp-input[data-v-14ecb7bd] {
|
|
8
|
+
position: absolute;
|
|
9
|
+
opacity: 0;
|
|
10
|
+
pointer-events: none;
|
|
11
|
+
}
|
|
12
|
+
.otp-box[data-v-14ecb7bd] {
|
|
13
|
+
display: flex;
|
|
14
|
+
}
|
|
15
|
+
.otp-item[data-v-14ecb7bd] {
|
|
16
|
+
width: 40px;
|
|
17
|
+
height: 50px;
|
|
18
|
+
border: 1px solid #ccc;
|
|
19
|
+
border-radius: 8px;
|
|
20
|
+
text-align: center;
|
|
21
|
+
line-height: 50px;
|
|
22
|
+
font-size: 20px;
|
|
23
|
+
transition: all 0.2s;
|
|
24
|
+
}
|
|
25
|
+
.otp-item.active[data-v-14ecb7bd] {
|
|
26
|
+
border-color: #409eff;
|
|
27
|
+
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
|
|
28
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { defineComponent, ref, watch, openBlock, createElementBlock, withDirectives, createElementVNode, vModelText, normalizeStyle, Fragment, renderList, normalizeClass, toDisplayString } from "vue";
|
|
2
|
+
const _hoisted_1 = ["maxlength"];
|
|
3
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
4
|
+
__name: "input-otp",
|
|
5
|
+
props: {
|
|
6
|
+
modelValue: { default: "" },
|
|
7
|
+
length: { default: 6 },
|
|
8
|
+
itemClass: { default: "" },
|
|
9
|
+
activeItemClass: { default: "" },
|
|
10
|
+
gap: { default: "10px" }
|
|
11
|
+
},
|
|
12
|
+
emits: ["update:modelValue", "complete"],
|
|
13
|
+
setup(__props, { emit: __emit }) {
|
|
14
|
+
const props = __props;
|
|
15
|
+
const emit = __emit;
|
|
16
|
+
const inputRef = ref(null);
|
|
17
|
+
const innerValue = ref(props.modelValue);
|
|
18
|
+
watch(
|
|
19
|
+
() => props.modelValue,
|
|
20
|
+
(val) => {
|
|
21
|
+
if (val !== innerValue.value) {
|
|
22
|
+
innerValue.value = val;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
function handleInput(e) {
|
|
27
|
+
let value = e.target.value;
|
|
28
|
+
value = value.replace(/\D/g, "");
|
|
29
|
+
value = value.slice(0, props.length);
|
|
30
|
+
innerValue.value = value;
|
|
31
|
+
emit("update:modelValue", value);
|
|
32
|
+
if (value.length === props.length) {
|
|
33
|
+
emit("complete", value);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function focusInput() {
|
|
37
|
+
var _a;
|
|
38
|
+
(_a = inputRef.value) == null ? void 0 : _a.focus();
|
|
39
|
+
}
|
|
40
|
+
function isActive(index) {
|
|
41
|
+
return index === innerValue.value.length;
|
|
42
|
+
}
|
|
43
|
+
return (_ctx, _cache) => {
|
|
44
|
+
return openBlock(), createElementBlock("div", {
|
|
45
|
+
class: "otp-wrapper",
|
|
46
|
+
onClick: focusInput
|
|
47
|
+
}, [
|
|
48
|
+
withDirectives(createElementVNode("input", {
|
|
49
|
+
inputmode: "numeric",
|
|
50
|
+
autocomplete: "one-time-code",
|
|
51
|
+
ref_key: "inputRef",
|
|
52
|
+
ref: inputRef,
|
|
53
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => innerValue.value = $event),
|
|
54
|
+
maxlength: __props.length,
|
|
55
|
+
onInput: handleInput,
|
|
56
|
+
class: "otp-input"
|
|
57
|
+
}, null, 40, _hoisted_1), [
|
|
58
|
+
[vModelText, innerValue.value]
|
|
59
|
+
]),
|
|
60
|
+
createElementVNode("div", {
|
|
61
|
+
class: "otp-box",
|
|
62
|
+
style: normalizeStyle({ gap: props.gap })
|
|
63
|
+
}, [
|
|
64
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.length, (_, index) => {
|
|
65
|
+
return openBlock(), createElementBlock("div", {
|
|
66
|
+
key: index,
|
|
67
|
+
class: normalizeClass(["otp-item", [
|
|
68
|
+
{ active: isActive(index), [props.activeItemClass]: isActive(index) },
|
|
69
|
+
props.itemClass
|
|
70
|
+
]])
|
|
71
|
+
}, toDisplayString(innerValue.value[index] || ""), 3);
|
|
72
|
+
}), 128))
|
|
73
|
+
], 4)
|
|
74
|
+
]);
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
const _export_sfc = (sfc, props) => {
|
|
79
|
+
const target = sfc.__vccOpts || sfc;
|
|
80
|
+
for (const [key, val] of props) {
|
|
81
|
+
target[key] = val;
|
|
82
|
+
}
|
|
83
|
+
return target;
|
|
84
|
+
};
|
|
85
|
+
const InputOtp = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-14ecb7bd"]]);
|
|
86
|
+
export {
|
|
87
|
+
InputOtp,
|
|
88
|
+
InputOtp as default
|
|
89
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
modelValue?: string;
|
|
3
|
+
length?: number;
|
|
4
|
+
itemClass?: string;
|
|
5
|
+
activeItemClass?: string;
|
|
6
|
+
gap?: string;
|
|
7
|
+
}
|
|
8
|
+
declare const _default: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
|
|
9
|
+
"update:modelValue": (value: string) => any;
|
|
10
|
+
complete: (value: string) => any;
|
|
11
|
+
}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{
|
|
12
|
+
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
13
|
+
onComplete?: ((value: string) => any) | undefined;
|
|
14
|
+
}>, {
|
|
15
|
+
modelValue: string;
|
|
16
|
+
length: number;
|
|
17
|
+
itemClass: string;
|
|
18
|
+
activeItemClass: string;
|
|
19
|
+
gap: string;
|
|
20
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
21
|
+
inputRef: HTMLInputElement;
|
|
22
|
+
}, HTMLDivElement>;
|
|
23
|
+
export default _default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { InputOtp } from './components/input-otp';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),f=["maxlength"],v=e.defineComponent({__name:"input-otp",props:{modelValue:{default:""},length:{default:6},itemClass:{default:""},activeItemClass:{default:""},gap:{default:"10px"}},emits:["update:modelValue","complete"],setup(a,{emit:i}){const l=a,u=i,c=e.ref(null),o=e.ref(l.modelValue);e.watch(()=>l.modelValue,n=>{n!==o.value&&(o.value=n)});function m(n){let t=n.target.value;t=t.replace(/\D/g,""),t=t.slice(0,l.length),o.value=t,u("update:modelValue",t),t.length===l.length&&u("complete",t)}function d(){var n;(n=c.value)==null||n.focus()}function r(n){return n===o.value.length}return(n,t)=>(e.openBlock(),e.createElementBlock("div",{class:"otp-wrapper",onClick:d},[e.withDirectives(e.createElementVNode("input",{inputmode:"numeric",autocomplete:"one-time-code",ref_key:"inputRef",ref:c,"onUpdate:modelValue":t[0]||(t[0]=p=>o.value=p),maxlength:a.length,onInput:m,class:"otp-input"},null,40,f),[[e.vModelText,o.value]]),e.createElementVNode("div",{class:"otp-box",style:e.normalizeStyle({gap:l.gap})},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(a.length,(p,s)=>(e.openBlock(),e.createElementBlock("div",{key:s,class:e.normalizeClass(["otp-item",[{active:r(s),[l.activeItemClass]:r(s)},l.itemClass]])},e.toDisplayString(o.value[s]||""),3))),128))],4)]))}}),g=(a,i)=>{const l=a.__vccOpts||a;for(const[u,c]of i)l[u]=c;return l},h=g(v,[["__scopeId","data-v-14ecb7bd"]]);exports.InputOtp=h;
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { App } from 'vue';
|
|
2
|
+
import { default as InputOtp } from './components/input-otp/input-otp.vue';
|
|
3
|
+
export * from './components';
|
|
4
|
+
export { InputOtp };
|
|
5
|
+
declare const _default: {
|
|
6
|
+
version: string;
|
|
7
|
+
install: (app: App) => void;
|
|
8
|
+
};
|
|
9
|
+
export default _default;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),f=["maxlength"],g=e.defineComponent({__name:"input-otp",props:{modelValue:{default:""},length:{default:6},itemClass:{default:""},activeItemClass:{default:""},gap:{default:"10px"}},emits:["update:modelValue","complete"],setup(o,{emit:i}){const l=o,u=i,c=e.ref(null),a=e.ref(l.modelValue);e.watch(()=>l.modelValue,n=>{n!==a.value&&(a.value=n)});function d(n){let t=n.target.value;t=t.replace(/\D/g,""),t=t.slice(0,l.length),a.value=t,u("update:modelValue",t),t.length===l.length&&u("complete",t)}function v(){var n;(n=c.value)==null||n.focus()}function p(n){return n===a.value.length}return(n,t)=>(e.openBlock(),e.createElementBlock("div",{class:"otp-wrapper",onClick:v},[e.withDirectives(e.createElementVNode("input",{inputmode:"numeric",autocomplete:"one-time-code",ref_key:"inputRef",ref:c,"onUpdate:modelValue":t[0]||(t[0]=r=>a.value=r),maxlength:o.length,onInput:d,class:"otp-input"},null,40,f),[[e.vModelText,a.value]]),e.createElementVNode("div",{class:"otp-box",style:e.normalizeStyle({gap:l.gap})},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o.length,(r,s)=>(e.openBlock(),e.createElementBlock("div",{key:s,class:e.normalizeClass(["otp-item",[{active:p(s),[l.activeItemClass]:p(s)},l.itemClass]])},e.toDisplayString(a.value[s]||""),3))),128))],4)]))}}),h=(o,i)=>{const l=o.__vccOpts||o;for(const[u,c]of i)l[u]=c;return l},m=h(g,[["__scopeId","data-v-14ecb7bd"]]),_="1.0.0",k=o=>{o.component("RInputOtp",m)},I={version:_,install:k};exports.InputOtp=m;exports.default=I;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
.otp-wrapper[data-v-14ecb7bd] {
|
|
3
|
+
position: relative;
|
|
4
|
+
width: max-content;
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
}
|
|
7
|
+
.otp-input[data-v-14ecb7bd] {
|
|
8
|
+
position: absolute;
|
|
9
|
+
opacity: 0;
|
|
10
|
+
pointer-events: none;
|
|
11
|
+
}
|
|
12
|
+
.otp-box[data-v-14ecb7bd] {
|
|
13
|
+
display: flex;
|
|
14
|
+
}
|
|
15
|
+
.otp-item[data-v-14ecb7bd] {
|
|
16
|
+
width: 40px;
|
|
17
|
+
height: 50px;
|
|
18
|
+
border: 1px solid #ccc;
|
|
19
|
+
border-radius: 8px;
|
|
20
|
+
text-align: center;
|
|
21
|
+
line-height: 50px;
|
|
22
|
+
font-size: 20px;
|
|
23
|
+
transition: all 0.2s;
|
|
24
|
+
}
|
|
25
|
+
.otp-item.active[data-v-14ecb7bd] {
|
|
26
|
+
border-color: #409eff;
|
|
27
|
+
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
|
|
28
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const vue = require("vue");
|
|
4
|
+
const _hoisted_1 = ["maxlength"];
|
|
5
|
+
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
6
|
+
__name: "input-otp",
|
|
7
|
+
props: {
|
|
8
|
+
modelValue: { default: "" },
|
|
9
|
+
length: { default: 6 },
|
|
10
|
+
itemClass: { default: "" },
|
|
11
|
+
activeItemClass: { default: "" },
|
|
12
|
+
gap: { default: "10px" }
|
|
13
|
+
},
|
|
14
|
+
emits: ["update:modelValue", "complete"],
|
|
15
|
+
setup(__props, { emit: __emit }) {
|
|
16
|
+
const props = __props;
|
|
17
|
+
const emit = __emit;
|
|
18
|
+
const inputRef = vue.ref(null);
|
|
19
|
+
const innerValue = vue.ref(props.modelValue);
|
|
20
|
+
vue.watch(
|
|
21
|
+
() => props.modelValue,
|
|
22
|
+
(val) => {
|
|
23
|
+
if (val !== innerValue.value) {
|
|
24
|
+
innerValue.value = val;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
function handleInput(e) {
|
|
29
|
+
let value = e.target.value;
|
|
30
|
+
value = value.replace(/\D/g, "");
|
|
31
|
+
value = value.slice(0, props.length);
|
|
32
|
+
innerValue.value = value;
|
|
33
|
+
emit("update:modelValue", value);
|
|
34
|
+
if (value.length === props.length) {
|
|
35
|
+
emit("complete", value);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function focusInput() {
|
|
39
|
+
var _a;
|
|
40
|
+
(_a = inputRef.value) == null ? void 0 : _a.focus();
|
|
41
|
+
}
|
|
42
|
+
function isActive(index) {
|
|
43
|
+
return index === innerValue.value.length;
|
|
44
|
+
}
|
|
45
|
+
return (_ctx, _cache) => {
|
|
46
|
+
return vue.openBlock(), vue.createElementBlock("div", {
|
|
47
|
+
class: "otp-wrapper",
|
|
48
|
+
onClick: focusInput
|
|
49
|
+
}, [
|
|
50
|
+
vue.withDirectives(vue.createElementVNode("input", {
|
|
51
|
+
inputmode: "numeric",
|
|
52
|
+
autocomplete: "one-time-code",
|
|
53
|
+
ref_key: "inputRef",
|
|
54
|
+
ref: inputRef,
|
|
55
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => innerValue.value = $event),
|
|
56
|
+
maxlength: __props.length,
|
|
57
|
+
onInput: handleInput,
|
|
58
|
+
class: "otp-input"
|
|
59
|
+
}, null, 40, _hoisted_1), [
|
|
60
|
+
[vue.vModelText, innerValue.value]
|
|
61
|
+
]),
|
|
62
|
+
vue.createElementVNode("div", {
|
|
63
|
+
class: "otp-box",
|
|
64
|
+
style: vue.normalizeStyle({ gap: props.gap })
|
|
65
|
+
}, [
|
|
66
|
+
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.length, (_, index) => {
|
|
67
|
+
return vue.openBlock(), vue.createElementBlock("div", {
|
|
68
|
+
key: index,
|
|
69
|
+
class: vue.normalizeClass(["otp-item", [
|
|
70
|
+
{ active: isActive(index), [props.activeItemClass]: isActive(index) },
|
|
71
|
+
props.itemClass
|
|
72
|
+
]])
|
|
73
|
+
}, vue.toDisplayString(innerValue.value[index] || ""), 3);
|
|
74
|
+
}), 128))
|
|
75
|
+
], 4)
|
|
76
|
+
]);
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
const _export_sfc = (sfc, props) => {
|
|
81
|
+
const target = sfc.__vccOpts || sfc;
|
|
82
|
+
for (const [key, val] of props) {
|
|
83
|
+
target[key] = val;
|
|
84
|
+
}
|
|
85
|
+
return target;
|
|
86
|
+
};
|
|
87
|
+
const InputOtp = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-14ecb7bd"]]);
|
|
88
|
+
exports.InputOtp = InputOtp;
|
|
89
|
+
exports.default = InputOtp;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
modelValue?: string;
|
|
3
|
+
length?: number;
|
|
4
|
+
itemClass?: string;
|
|
5
|
+
activeItemClass?: string;
|
|
6
|
+
gap?: string;
|
|
7
|
+
}
|
|
8
|
+
declare const _default: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
|
|
9
|
+
"update:modelValue": (value: string) => any;
|
|
10
|
+
complete: (value: string) => any;
|
|
11
|
+
}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{
|
|
12
|
+
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
13
|
+
onComplete?: ((value: string) => any) | undefined;
|
|
14
|
+
}>, {
|
|
15
|
+
modelValue: string;
|
|
16
|
+
length: number;
|
|
17
|
+
itemClass: string;
|
|
18
|
+
activeItemClass: string;
|
|
19
|
+
gap: string;
|
|
20
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
21
|
+
inputRef: HTMLInputElement;
|
|
22
|
+
}, HTMLDivElement>;
|
|
23
|
+
export default _default;
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@a-drowned-fish/rox-v",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A Vue 3 UI Component Library",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"module": "es/index.js",
|
|
7
|
+
"types": "es/index.d.ts",
|
|
8
|
+
"browser": "dist/index.iife.js",
|
|
9
|
+
"unpkg": "dist/index.iife.js",
|
|
10
|
+
"jsdelivr": "dist/index.iife.js",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"es",
|
|
14
|
+
"lib",
|
|
15
|
+
"resolver"
|
|
16
|
+
],
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"import": "./es/index.js",
|
|
20
|
+
"require": "./lib/index.js",
|
|
21
|
+
"types": "./es/index.d.ts"
|
|
22
|
+
},
|
|
23
|
+
"./components": {
|
|
24
|
+
"import": "./es/components.js",
|
|
25
|
+
"require": "./lib/components.js",
|
|
26
|
+
"types": "./es/components.d.ts"
|
|
27
|
+
},
|
|
28
|
+
"./resolver": {
|
|
29
|
+
"import": "./resolver/resolver.js",
|
|
30
|
+
"require": "./resolver/resolver.cjs",
|
|
31
|
+
"types": "./resolver/resolver.d.ts"
|
|
32
|
+
},
|
|
33
|
+
"./dist/*": "./dist/*",
|
|
34
|
+
"./es/*": "./es/*",
|
|
35
|
+
"./lib/*": "./lib/*"
|
|
36
|
+
},
|
|
37
|
+
"sideEffects": [
|
|
38
|
+
"*.css",
|
|
39
|
+
"*.vue.css"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsx scripts/build.ts",
|
|
43
|
+
"dev": "vite",
|
|
44
|
+
"type-check": "vue-tsc --noEmit"
|
|
45
|
+
},
|
|
46
|
+
"keywords": [
|
|
47
|
+
"vue",
|
|
48
|
+
"ui",
|
|
49
|
+
"component-library",
|
|
50
|
+
"auto-import",
|
|
51
|
+
"unplugin-vue-components"
|
|
52
|
+
],
|
|
53
|
+
"author": "",
|
|
54
|
+
"license": "MIT",
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"vue": "^3.0.0"
|
|
57
|
+
},
|
|
58
|
+
"peerDependenciesMeta": {
|
|
59
|
+
"unplugin-vue-components": {
|
|
60
|
+
"optional": true
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"vue": "^3.0.0"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@types/node": "^25.6.0",
|
|
68
|
+
"@vitejs/plugin-vue": "^5.2.4",
|
|
69
|
+
"rimraf": "^6.1.3",
|
|
70
|
+
"tsx": "^4.21.0",
|
|
71
|
+
"typescript": "^6.0.3",
|
|
72
|
+
"unplugin-vue-components": "^28.8.0",
|
|
73
|
+
"vite": "^5.4.21",
|
|
74
|
+
"vite-plugin-dts": "^4.5.4",
|
|
75
|
+
"vue-tsc": "^3.2.6"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const componentMap = {
|
|
4
|
+
RInputOtp: "input-otp"
|
|
5
|
+
};
|
|
6
|
+
function RoxVResolver(options = {}) {
|
|
7
|
+
const { cjs = false } = options;
|
|
8
|
+
const moduleType = cjs ? "lib" : "es";
|
|
9
|
+
return {
|
|
10
|
+
type: "component",
|
|
11
|
+
resolve: (name) => {
|
|
12
|
+
const componentName = componentMap[name];
|
|
13
|
+
if (!componentName) {
|
|
14
|
+
return void 0;
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
name,
|
|
18
|
+
path: `rox-v/${moduleType}/${componentName}`,
|
|
19
|
+
sideEffects: `rox-v/${moduleType}/${componentName}/index.css`
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
exports.RoxVResolver = RoxVResolver;
|
|
25
|
+
exports.default = RoxVResolver;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ComponentResolver } from 'unplugin-vue-components/types';
|
|
2
|
+
export interface RoxVResolverOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Use CommonJS build (lib) instead of ES modules (es)
|
|
5
|
+
* @default false
|
|
6
|
+
*/
|
|
7
|
+
cjs?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Create a resolver for rox-v components
|
|
11
|
+
*/
|
|
12
|
+
export declare function RoxVResolver(options?: RoxVResolverOptions): ComponentResolver;
|
|
13
|
+
export default RoxVResolver;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const componentMap = {
|
|
2
|
+
RInputOtp: "input-otp"
|
|
3
|
+
};
|
|
4
|
+
function RoxVResolver(options = {}) {
|
|
5
|
+
const { cjs = false } = options;
|
|
6
|
+
const moduleType = cjs ? "lib" : "es";
|
|
7
|
+
return {
|
|
8
|
+
type: "component",
|
|
9
|
+
resolve: (name) => {
|
|
10
|
+
const componentName = componentMap[name];
|
|
11
|
+
if (!componentName) {
|
|
12
|
+
return void 0;
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
name,
|
|
16
|
+
path: `rox-v/${moduleType}/${componentName}`,
|
|
17
|
+
sideEffects: `rox-v/${moduleType}/${componentName}/index.css`
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
RoxVResolver,
|
|
24
|
+
RoxVResolver as default
|
|
25
|
+
};
|