@leaflink/stash 48.16.2 → 48.18.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/dist/AppSidebar.js +30 -30
- package/dist/AppSidebar.js.map +1 -1
- package/dist/ConfirmationCodeInput.js +128 -105
- package/dist/ConfirmationCodeInput.js.map +1 -1
- package/dist/ConfirmationCodeInput.vue.d.ts +28 -2
- package/dist/Dialog.js +25 -25
- package/dist/Dialog.js.map +1 -1
- package/dist/Modal.js +2 -2
- package/dist/Modal.js.map +1 -1
- package/dist/components.css +1 -1
- package/package.json +1 -1
package/dist/AppSidebar.js
CHANGED
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
import { defineComponent as
|
|
1
|
+
import { defineComponent as B, useSlots as C, computed as h, ref as O, watchEffect as V, openBlock as s, createElementBlock as a, normalizeClass as w, createVNode as o, Transition as b, withCtx as g, withDirectives as x, withModifiers as $, vShow as y, createElementVNode as d, unref as c, renderSlot as i, createCommentVNode as u } from "vue";
|
|
2
2
|
import z from "./useMediaQuery.js";
|
|
3
3
|
import A from "./Backdrop.js";
|
|
4
4
|
import N from "./Divider.js";
|
|
5
5
|
import { _ as j } from "./_plugin-vue_export-helper-dad06003.js";
|
|
6
6
|
const D = {
|
|
7
|
-
class: "stash-app-sidebar__aside tw-fixed tw-flex tw-h-screen tw-flex-col tw-bg-purple-500",
|
|
8
|
-
"data-test": "stash-app-sidebar__aside"
|
|
9
|
-
}, M = {
|
|
10
7
|
key: 0,
|
|
11
8
|
class: "tw-px-3 tw-pt-6"
|
|
12
|
-
},
|
|
9
|
+
}, M = {
|
|
13
10
|
key: 1,
|
|
14
11
|
class: "tw-px-3 tw-pt-6"
|
|
15
|
-
},
|
|
12
|
+
}, P = {
|
|
16
13
|
key: 2,
|
|
17
14
|
class: "tw-pt-6"
|
|
18
|
-
},
|
|
15
|
+
}, I = {
|
|
19
16
|
role: "menubar",
|
|
20
17
|
"aria-orientation": "vertical"
|
|
21
|
-
},
|
|
18
|
+
}, L = /* @__PURE__ */ B({
|
|
22
19
|
__name: "AppSidebar",
|
|
23
20
|
props: {
|
|
24
21
|
isOpen: { type: Boolean, default: !1 }
|
|
25
22
|
},
|
|
26
23
|
emits: ["dismiss", "update:is-open"],
|
|
27
|
-
setup(
|
|
28
|
-
const v =
|
|
29
|
-
function
|
|
24
|
+
setup(k, { emit: S }) {
|
|
25
|
+
const v = k, n = C(), m = S, l = z("screen and (min-width: 1321px)"), e = h(() => v.isOpen && !l.value), r = O({ height: "", overflow: "" }), f = h(() => v.isOpen || l.value);
|
|
26
|
+
function E() {
|
|
30
27
|
m("dismiss"), m("update:is-open", !1);
|
|
31
28
|
}
|
|
32
29
|
function p() {
|
|
33
30
|
return document.scrollingElement || document.body;
|
|
34
31
|
}
|
|
35
|
-
return
|
|
36
|
-
|
|
32
|
+
return V(() => {
|
|
33
|
+
l.value || (e.value && Object.assign(r.value, {
|
|
37
34
|
overflow: p().style.overflow,
|
|
38
35
|
height: p().style.height
|
|
39
36
|
}), Object.assign(p().style, {
|
|
40
|
-
overflow: e.value ? "hidden" :
|
|
37
|
+
overflow: e.value ? "hidden" : r.value.overflow,
|
|
41
38
|
// Prevents page from scrolling when AppSidebar is open
|
|
42
|
-
height: e.value ? "100%" :
|
|
39
|
+
height: e.value ? "100%" : r.value.height
|
|
43
40
|
// Ensures the backdrop covers the entire page when AppSidebar is open
|
|
44
41
|
}));
|
|
45
42
|
}), (t, _) => (s(), a("div", {
|
|
46
43
|
id: "stash-app-sidebar",
|
|
47
|
-
class:
|
|
44
|
+
class: w(["stash-app-sidebar tw-relative", {
|
|
48
45
|
"stash-app-sidebar--is-open": f.value,
|
|
49
46
|
"tw-z-modal": e.value,
|
|
50
47
|
"tw-z-[301]": !e.value
|
|
51
48
|
}]),
|
|
52
49
|
"data-test": "stash-app-sidebar"
|
|
53
50
|
}, [
|
|
54
|
-
o(
|
|
55
|
-
default:
|
|
56
|
-
|
|
51
|
+
o(b, { name: "backdrop" }, {
|
|
52
|
+
default: g(() => [
|
|
53
|
+
x(o(A, {
|
|
57
54
|
class: "stash-app-sidebar__backdrop",
|
|
58
|
-
onClick: $(
|
|
55
|
+
onClick: $(E, ["stop"])
|
|
59
56
|
}, null, 512), [
|
|
60
57
|
[y, e.value]
|
|
61
58
|
])
|
|
62
59
|
]),
|
|
63
60
|
_: 1
|
|
64
61
|
}),
|
|
65
|
-
o(
|
|
66
|
-
default:
|
|
67
|
-
|
|
62
|
+
o(b, { name: "aside" }, {
|
|
63
|
+
default: g(() => [
|
|
64
|
+
x(d("aside", {
|
|
65
|
+
class: w(["stash-app-sidebar__aside tw-fixed tw-flex tw-h-screen tw-flex-col tw-bg-purple-500", { "tw-shadow-3xl": e.value }]),
|
|
66
|
+
"data-test": "stash-app-sidebar__aside"
|
|
67
|
+
}, [
|
|
68
68
|
o(N, { class: "stash-app-sidebar__divider" }),
|
|
69
|
-
c(n)["app-context"] ? (s(), a("div",
|
|
69
|
+
c(n)["app-context"] ? (s(), a("div", D, [
|
|
70
70
|
i(t.$slots, "app-context", {}, void 0, !0)
|
|
71
71
|
])) : u("", !0),
|
|
72
|
-
c(n)["company-context"] ? (s(), a("div",
|
|
72
|
+
c(n)["company-context"] ? (s(), a("div", M, [
|
|
73
73
|
i(t.$slots, "company-context", {}, void 0, !0)
|
|
74
74
|
])) : u("", !0),
|
|
75
|
-
c(n).navigation ? (s(), a("nav",
|
|
76
|
-
d("ul",
|
|
75
|
+
c(n).navigation ? (s(), a("nav", P, [
|
|
76
|
+
d("ul", I, [
|
|
77
77
|
i(t.$slots, "navigation", {}, void 0, !0)
|
|
78
78
|
])
|
|
79
79
|
])) : u("", !0),
|
|
80
80
|
_[0] || (_[0] = d("div", { class: "tw-flex-1" }, null, -1)),
|
|
81
81
|
i(t.$slots, "footer", {}, void 0, !0)
|
|
82
|
-
],
|
|
82
|
+
], 2), [
|
|
83
83
|
[y, f.value]
|
|
84
84
|
])
|
|
85
85
|
]),
|
|
@@ -88,8 +88,8 @@ const D = {
|
|
|
88
88
|
], 2));
|
|
89
89
|
}
|
|
90
90
|
});
|
|
91
|
-
const
|
|
91
|
+
const H = /* @__PURE__ */ j(L, [["__scopeId", "data-v-8ae19347"]]);
|
|
92
92
|
export {
|
|
93
|
-
|
|
93
|
+
H as default
|
|
94
94
|
};
|
|
95
95
|
//# sourceMappingURL=AppSidebar.js.map
|
package/dist/AppSidebar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppSidebar.js","sources":["../src/components/AppSidebar/AppSidebar.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, useSlots, watchEffect } from 'vue';\n\n import useMediaQuery from '../../composables/useMediaQuery/useMediaQuery';\n import Backdrop from '../Backdrop/Backdrop.vue';\n import Divider from '../Divider/Divider.vue';\n\n export interface AppSidebarProps {\n /**\n * Controls wether the sidebar is opened or not\n */\n isOpen?: boolean;\n }\n\n const props = withDefaults(defineProps<AppSidebarProps>(), {\n isOpen: false,\n });\n\n const slots = useSlots();\n\n const emit = defineEmits<{\n /**\n * @deprecated Use the `update:is-open` event instead\n */\n (e: 'dismiss'): void;\n (e: 'update:is-open', isOpen: boolean): void;\n }>();\n\n const isExtraLargeScreen = useMediaQuery('screen and (min-width: 1321px)');\n const isBackdropVisible = computed(() => props.isOpen && !isExtraLargeScreen.value);\n const initialPageScrollingElementStyle = ref({ height: '', overflow: '' });\n const isSidebarOpen = computed(() => props.isOpen || isExtraLargeScreen.value);\n\n function onBackdropClick() {\n emit('dismiss');\n emit('update:is-open', false);\n }\n\n function getPageScrollingElement() {\n return (document.scrollingElement || document.body) as HTMLElement;\n }\n\n watchEffect(() => {\n if (isExtraLargeScreen.value) {\n return;\n }\n\n if (isBackdropVisible.value) {\n Object.assign(initialPageScrollingElementStyle.value, {\n overflow: getPageScrollingElement().style.overflow,\n height: getPageScrollingElement().style.height,\n });\n }\n\n Object.assign(getPageScrollingElement().style, {\n overflow: isBackdropVisible.value ? 'hidden' : initialPageScrollingElementStyle.value.overflow, // Prevents page from scrolling when AppSidebar is open\n height: isBackdropVisible.value ? '100%' : initialPageScrollingElementStyle.value.height, // Ensures the backdrop covers the entire page when AppSidebar is open\n });\n });\n</script>\n\n<template>\n <div\n id=\"stash-app-sidebar\"\n class=\"stash-app-sidebar tw-relative\"\n :class=\"{\n 'stash-app-sidebar--is-open': isSidebarOpen,\n 'tw-z-modal': isBackdropVisible,\n 'tw-z-[301]': !isBackdropVisible,\n }\"\n data-test=\"stash-app-sidebar\"\n >\n <Transition name=\"backdrop\">\n <Backdrop v-show=\"isBackdropVisible\" class=\"stash-app-sidebar__backdrop\" @click.stop=\"onBackdropClick\" />\n </Transition>\n <Transition name=\"aside\">\n <aside\n v-show=\"isSidebarOpen\"\n class=\"stash-app-sidebar__aside tw-fixed tw-flex tw-h-screen tw-flex-col tw-bg-purple-500\"\n data-test=\"stash-app-sidebar__aside\"\n >\n <Divider class=\"stash-app-sidebar__divider\" />\n <div v-if=\"slots['app-context']\" class=\"tw-px-3 tw-pt-6\">\n <!-- @slot App Context component slot, ideally for rendering the context switcher -->\n <slot name=\"app-context\"></slot>\n </div>\n <div v-if=\"slots['company-context']\" class=\"tw-px-3 tw-pt-6\">\n <!-- @slot Company Context component slot, ideally for rendering the company picker -->\n <slot name=\"company-context\"></slot>\n </div>\n <nav v-if=\"slots['navigation']\" class=\"tw-pt-6\">\n <ul role=\"menubar\" aria-orientation=\"vertical\">\n <!-- @slot Navigation component slot, for rendering navigation items -->\n <slot name=\"navigation\"></slot>\n </ul>\n </nav>\n <div class=\"tw-flex-1\"></div>\n <!-- @slot Footer component slot, for rendering version/environment notes -->\n <slot name=\"footer\"></slot>\n </aside>\n </Transition>\n </div>\n</template>\n\n<style scoped>\n .stash-app-sidebar__aside {\n padding-top: calc(theme('height.topbar') - 1px); /* -1px to compensate for the border height */\n width: theme('width.sidebar');\n }\n\n .stash-app-sidebar__divider::before,\n .stash-app-sidebar__divider::after {\n border-bottom: 1px solid rgb(255 255 255 / 12%);\n }\n\n .backdrop-enter-active,\n .backdrop-leave-active {\n transition: opacity 200ms ease-in-out;\n }\n\n .backdrop-enter-from,\n .backdrop-leave-to {\n opacity: 0;\n }\n\n .aside-enter-active,\n .aside-leave-active {\n transition: opacity 200ms ease-in-out, transform 200ms ease-in-out;\n }\n\n .aside-enter-from,\n .aside-leave-to {\n opacity: 0;\n transform: translateX(-20%);\n }\n</style>\n"],"names":["props","__props","slots","useSlots","emit","__emit","isExtraLargeScreen","useMediaQuery","isBackdropVisible","computed","initialPageScrollingElementStyle","ref","isSidebarOpen","onBackdropClick","getPageScrollingElement","watchEffect"],"mappings":"
|
|
1
|
+
{"version":3,"file":"AppSidebar.js","sources":["../src/components/AppSidebar/AppSidebar.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, useSlots, watchEffect } from 'vue';\n\n import useMediaQuery from '../../composables/useMediaQuery/useMediaQuery';\n import Backdrop from '../Backdrop/Backdrop.vue';\n import Divider from '../Divider/Divider.vue';\n\n export interface AppSidebarProps {\n /**\n * Controls wether the sidebar is opened or not\n */\n isOpen?: boolean;\n }\n\n const props = withDefaults(defineProps<AppSidebarProps>(), {\n isOpen: false,\n });\n\n const slots = useSlots();\n\n const emit = defineEmits<{\n /**\n * @deprecated Use the `update:is-open` event instead\n */\n (e: 'dismiss'): void;\n (e: 'update:is-open', isOpen: boolean): void;\n }>();\n\n const isExtraLargeScreen = useMediaQuery('screen and (min-width: 1321px)');\n const isBackdropVisible = computed(() => props.isOpen && !isExtraLargeScreen.value);\n const initialPageScrollingElementStyle = ref({ height: '', overflow: '' });\n const isSidebarOpen = computed(() => props.isOpen || isExtraLargeScreen.value);\n\n function onBackdropClick() {\n emit('dismiss');\n emit('update:is-open', false);\n }\n\n function getPageScrollingElement() {\n return (document.scrollingElement || document.body) as HTMLElement;\n }\n\n watchEffect(() => {\n if (isExtraLargeScreen.value) {\n return;\n }\n\n if (isBackdropVisible.value) {\n Object.assign(initialPageScrollingElementStyle.value, {\n overflow: getPageScrollingElement().style.overflow,\n height: getPageScrollingElement().style.height,\n });\n }\n\n Object.assign(getPageScrollingElement().style, {\n overflow: isBackdropVisible.value ? 'hidden' : initialPageScrollingElementStyle.value.overflow, // Prevents page from scrolling when AppSidebar is open\n height: isBackdropVisible.value ? '100%' : initialPageScrollingElementStyle.value.height, // Ensures the backdrop covers the entire page when AppSidebar is open\n });\n });\n</script>\n\n<template>\n <div\n id=\"stash-app-sidebar\"\n class=\"stash-app-sidebar tw-relative\"\n :class=\"{\n 'stash-app-sidebar--is-open': isSidebarOpen,\n 'tw-z-modal': isBackdropVisible,\n 'tw-z-[301]': !isBackdropVisible,\n }\"\n data-test=\"stash-app-sidebar\"\n >\n <Transition name=\"backdrop\">\n <Backdrop v-show=\"isBackdropVisible\" class=\"stash-app-sidebar__backdrop\" @click.stop=\"onBackdropClick\" />\n </Transition>\n <Transition name=\"aside\">\n <aside\n v-show=\"isSidebarOpen\"\n class=\"stash-app-sidebar__aside tw-fixed tw-flex tw-h-screen tw-flex-col tw-bg-purple-500\"\n :class=\"{ 'tw-shadow-3xl': isBackdropVisible }\"\n data-test=\"stash-app-sidebar__aside\"\n >\n <Divider class=\"stash-app-sidebar__divider\" />\n <div v-if=\"slots['app-context']\" class=\"tw-px-3 tw-pt-6\">\n <!-- @slot App Context component slot, ideally for rendering the context switcher -->\n <slot name=\"app-context\"></slot>\n </div>\n <div v-if=\"slots['company-context']\" class=\"tw-px-3 tw-pt-6\">\n <!-- @slot Company Context component slot, ideally for rendering the company picker -->\n <slot name=\"company-context\"></slot>\n </div>\n <nav v-if=\"slots['navigation']\" class=\"tw-pt-6\">\n <ul role=\"menubar\" aria-orientation=\"vertical\">\n <!-- @slot Navigation component slot, for rendering navigation items -->\n <slot name=\"navigation\"></slot>\n </ul>\n </nav>\n <div class=\"tw-flex-1\"></div>\n <!-- @slot Footer component slot, for rendering version/environment notes -->\n <slot name=\"footer\"></slot>\n </aside>\n </Transition>\n </div>\n</template>\n\n<style scoped>\n .stash-app-sidebar__aside {\n padding-top: calc(theme('height.topbar') - 1px); /* -1px to compensate for the border height */\n width: theme('width.sidebar');\n }\n\n .stash-app-sidebar__divider::before,\n .stash-app-sidebar__divider::after {\n border-bottom: 1px solid rgb(255 255 255 / 12%);\n }\n\n .backdrop-enter-active,\n .backdrop-leave-active {\n transition: opacity 200ms ease-in-out;\n }\n\n .backdrop-enter-from,\n .backdrop-leave-to {\n opacity: 0;\n }\n\n .aside-enter-active,\n .aside-leave-active {\n transition: opacity 200ms ease-in-out, transform 200ms ease-in-out;\n }\n\n .aside-enter-from,\n .aside-leave-to {\n opacity: 0;\n transform: translateX(-20%);\n }\n</style>\n"],"names":["props","__props","slots","useSlots","emit","__emit","isExtraLargeScreen","useMediaQuery","isBackdropVisible","computed","initialPageScrollingElementStyle","ref","isSidebarOpen","onBackdropClick","getPageScrollingElement","watchEffect"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAcE,UAAMA,IAAQC,GAIRC,IAAQC,KAERC,IAAOC,GAQPC,IAAqBC,EAAc,gCAAgC,GACnEC,IAAoBC,EAAS,MAAMT,EAAM,UAAU,CAACM,EAAmB,KAAK,GAC5EI,IAAmCC,EAAI,EAAE,QAAQ,IAAI,UAAU,IAAI,GACnEC,IAAgBH,EAAS,MAAMT,EAAM,UAAUM,EAAmB,KAAK;AAE7E,aAASO,IAAkB;AACzB,MAAAT,EAAK,SAAS,GACdA,EAAK,kBAAkB,EAAK;AAAA,IAC9B;AAEA,aAASU,IAA0B;AACzB,aAAA,SAAS,oBAAoB,SAAS;AAAA,IAChD;AAEA,WAAAC,EAAY,MAAM;AAChB,MAAIT,EAAmB,UAInBE,EAAkB,SACb,OAAA,OAAOE,EAAiC,OAAO;AAAA,QACpD,UAAUI,IAA0B,MAAM;AAAA,QAC1C,QAAQA,IAA0B,MAAM;AAAA,MAAA,CACzC,GAGI,OAAA,OAAOA,EAAwB,EAAE,OAAO;AAAA,QAC7C,UAAUN,EAAkB,QAAQ,WAAWE,EAAiC,MAAM;AAAA;AAAA,QACtF,QAAQF,EAAkB,QAAQ,SAASE,EAAiC,MAAM;AAAA;AAAA,MAAA,CACnF;AAAA,IAAA,CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,125 +1,148 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { _ as
|
|
3
|
-
const
|
|
1
|
+
import { defineComponent as I, useCssVars as v, useCssModule as E, ref as V, onMounted as B, watch as P, openBlock as a, createElementBlock as r, normalizeClass as x, unref as l, createElementVNode as z, Fragment as A, renderList as M, toDisplayString as p, createCommentVNode as f } from "vue";
|
|
2
|
+
import { _ as F } from "./_plugin-vue_export-helper-dad06003.js";
|
|
3
|
+
const K = { class: "tw-mb-3 tw-flex tw-gap-6" }, S = ["value", "onInput"], U = {
|
|
4
|
+
key: 0,
|
|
5
|
+
class: "tw-mt-1 tw-block tw-whitespace-pre-line tw-pr-6 tw-text-center tw-text-red-500",
|
|
6
|
+
"data-test": "field-error"
|
|
7
|
+
}, j = {
|
|
8
|
+
key: 1,
|
|
9
|
+
class: "tw-mt-1 tw-block tw-whitespace-pre-line tw-pr-6 tw-text-center tw-text-green-500",
|
|
10
|
+
"data-test": "field-success"
|
|
11
|
+
}, L = {
|
|
12
|
+
key: 2,
|
|
13
|
+
class: "tw-mt-1 tw-block tw-whitespace-pre-line tw-pr-6 tw-text-center tw-text-ice-700",
|
|
14
|
+
"data-test": "field-hint"
|
|
15
|
+
}, R = /* @__PURE__ */ I({
|
|
4
16
|
__name: "ConfirmationCodeInput",
|
|
5
17
|
props: {
|
|
6
18
|
digitCount: { default: 6 },
|
|
7
19
|
errorText: { default: void 0 },
|
|
8
|
-
successText: { default: void 0 }
|
|
20
|
+
successText: { default: void 0 },
|
|
21
|
+
hintText: { default: void 0 },
|
|
22
|
+
modelValue: { default: void 0 }
|
|
9
23
|
},
|
|
10
|
-
emits: ["update:model-value"],
|
|
11
|
-
setup(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
24
|
+
emits: ["update:model-value", "change", "focus", "blur"],
|
|
25
|
+
setup(g, { emit: b }) {
|
|
26
|
+
v((t) => ({
|
|
27
|
+
b1b2f1d6: t.digitCount
|
|
28
|
+
}));
|
|
29
|
+
const c = E(), o = g, i = b, s = V([]);
|
|
30
|
+
B(() => {
|
|
31
|
+
var t;
|
|
32
|
+
o.modelValue && (s.value = (t = o.modelValue) == null ? void 0 : t.split(""));
|
|
33
|
+
});
|
|
34
|
+
function k(t, e) {
|
|
35
|
+
var n;
|
|
36
|
+
s.value[e] = (n = t.target) == null ? void 0 : n.value, m(t), t.inputType === "deleteContentBackward" ? d(t) : (t.inputType === "insertText" || t.inputType === "deleteContentForward") && w(t);
|
|
15
37
|
}
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
let t = 0;
|
|
22
|
-
s.value.forEach((u, r) => {
|
|
23
|
-
u && (t = r + 1);
|
|
24
|
-
}), n.value[t].focus();
|
|
38
|
+
function m(t) {
|
|
39
|
+
const e = s.value.join("");
|
|
40
|
+
i("update:model-value", e), i("change", { originalEvent: t, value: e });
|
|
25
41
|
}
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
42
|
+
function d(t) {
|
|
43
|
+
const e = h(t.target);
|
|
44
|
+
e && (e.focus(), e.select());
|
|
45
|
+
}
|
|
46
|
+
function w(t) {
|
|
47
|
+
const e = _(t.target);
|
|
48
|
+
e && (e.focus(), e.select());
|
|
49
|
+
}
|
|
50
|
+
function h(t) {
|
|
51
|
+
const e = t.previousElementSibling;
|
|
52
|
+
if (e)
|
|
53
|
+
return e.nodeName === "INPUT" ? e : h(e);
|
|
54
|
+
}
|
|
55
|
+
function _(t) {
|
|
56
|
+
const e = t.nextElementSibling;
|
|
57
|
+
if (e)
|
|
58
|
+
return e.nodeName === "INPUT" ? e : _(e);
|
|
59
|
+
}
|
|
60
|
+
function T(t) {
|
|
61
|
+
t.target.select(), i("focus", t);
|
|
62
|
+
}
|
|
63
|
+
function y(t) {
|
|
64
|
+
i("blur", t);
|
|
65
|
+
}
|
|
66
|
+
function C(t) {
|
|
67
|
+
var e;
|
|
68
|
+
if (!(t.ctrlKey || t.metaKey))
|
|
69
|
+
switch (t.code) {
|
|
70
|
+
case "ArrowLeft":
|
|
71
|
+
d(t), t.preventDefault();
|
|
72
|
+
break;
|
|
73
|
+
case "ArrowUp":
|
|
74
|
+
case "ArrowDown":
|
|
75
|
+
t.preventDefault();
|
|
76
|
+
break;
|
|
77
|
+
case "Backspace":
|
|
78
|
+
((e = t.target) == null ? void 0 : e.value.length) === 0 && (d(t), t.preventDefault());
|
|
79
|
+
break;
|
|
80
|
+
case "ArrowRight":
|
|
81
|
+
w(t), t.preventDefault();
|
|
82
|
+
break;
|
|
83
|
+
case "Enter":
|
|
84
|
+
case "NumpadEnter":
|
|
85
|
+
case "Tab":
|
|
86
|
+
break;
|
|
87
|
+
default:
|
|
88
|
+
(!(t.code !== "Space" && Number(t.key) >= 0 && Number(t.key) <= 9) || s.value.join("").length >= o.digitCount && t.code !== "Delete") && t.preventDefault();
|
|
89
|
+
break;
|
|
36
90
|
}
|
|
37
|
-
if (s.value[o])
|
|
38
|
-
return;
|
|
39
|
-
s.value[t] = "", n.value[t].focus();
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
if (!new RegExp("^([0-9])$").test(e.key) && !s.value[o]) {
|
|
43
|
-
s.value[t] = "", n.value[t].focus();
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
91
|
}
|
|
47
|
-
function
|
|
48
|
-
var
|
|
49
|
-
const
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
92
|
+
function N(t) {
|
|
93
|
+
var n;
|
|
94
|
+
const e = (n = t.clipboardData) == null ? void 0 : n.getData("text");
|
|
95
|
+
if (e != null && e.length) {
|
|
96
|
+
const u = e == null ? void 0 : e.substring(0, o.digitCount), D = parseInt(u);
|
|
97
|
+
isNaN(D) || (s.value = u.split(""), m(t));
|
|
53
98
|
}
|
|
54
|
-
|
|
55
|
-
if (o)
|
|
56
|
-
for (let r = 1; r < o.length; r++)
|
|
57
|
-
t && (s.value[r] = o[r], t = t.nextElementSibling);
|
|
99
|
+
t.preventDefault();
|
|
58
100
|
}
|
|
59
|
-
return
|
|
60
|
-
() =>
|
|
61
|
-
(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
d("update:model-value", Number(e.value.join("")));
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
{ deep: !0 }
|
|
73
|
-
), (e, o) => (c(), i("form", {
|
|
74
|
-
ref: "otpCont",
|
|
75
|
-
class: "stash-confirmation-code-input tw-inline-block",
|
|
76
|
-
"data-test": "stash-confirmation-code-input",
|
|
77
|
-
onInput: h
|
|
101
|
+
return P(
|
|
102
|
+
() => o.modelValue,
|
|
103
|
+
(t) => {
|
|
104
|
+
s.value = t ? t.split("") : new Array(o.digitCount);
|
|
105
|
+
}
|
|
106
|
+
), (t, e) => (a(), r("div", {
|
|
107
|
+
class: x(["stash-confirmation-code-input tw-inline-block", [l(c)["stash-confirmation-code-input-container"]]]),
|
|
108
|
+
"data-test": "stash-confirmation-code-input"
|
|
78
109
|
}, [
|
|
79
|
-
|
|
80
|
-
(
|
|
81
|
-
key:
|
|
82
|
-
ref_for: !0,
|
|
83
|
-
ref_key: "inputEl",
|
|
84
|
-
ref: n,
|
|
85
|
-
"onUpdate:modelValue": (r) => s.value[t - 1] = r,
|
|
110
|
+
z("div", K, [
|
|
111
|
+
(a(!0), r(A, null, M(o.digitCount, (n) => (a(), r("input", {
|
|
112
|
+
key: n,
|
|
86
113
|
"data-test": "stash-confirmation-code-input__otp",
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
{ [f(l)["has-error"]]: !!a.errorText },
|
|
92
|
-
{ [f(l)["has-success"]]: !!a.successText }
|
|
114
|
+
class: x(["tw-border tw-bg-white tw-p-2 tw-text-center tw-text-base tw-font-medium tw-text-ice-900 focus:tw-border-blue-500", [
|
|
115
|
+
l(c)["otp-code-input"],
|
|
116
|
+
{ [l(c)["has-error"]]: !!o.errorText },
|
|
117
|
+
{ [l(c)["has-success"]]: !!o.successText }
|
|
93
118
|
]]),
|
|
119
|
+
type: "text",
|
|
94
120
|
inputmode: "numeric",
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
121
|
+
maxlength: "1",
|
|
122
|
+
value: s.value[n - 1],
|
|
123
|
+
pattern: "[0-9]",
|
|
124
|
+
autocomplete: "one-time-code",
|
|
125
|
+
onInput: (u) => k(u, n - 1),
|
|
126
|
+
onKeydown: C,
|
|
127
|
+
onPaste: N,
|
|
128
|
+
onFocus: T,
|
|
129
|
+
onBlur: y
|
|
130
|
+
}, null, 42, S))), 128))
|
|
101
131
|
]),
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}, v(a.errorText), 3)) : _("", !0),
|
|
107
|
-
a.successText ? (c(), i("small", {
|
|
108
|
-
key: 1,
|
|
109
|
-
class: p(["tw-block tw-text-center tw-text-green-500", f(l).error]),
|
|
110
|
-
"data-test": "field-error"
|
|
111
|
-
}, v(a.successText), 3)) : _("", !0)
|
|
112
|
-
], 544));
|
|
132
|
+
o.errorText ? (a(), r("small", U, p(o.errorText), 1)) : f("", !0),
|
|
133
|
+
o.successText ? (a(), r("small", j, p(o.successText), 1)) : f("", !0),
|
|
134
|
+
o.hintText ? (a(), r("small", L, p(o.hintText), 1)) : f("", !0)
|
|
135
|
+
], 2));
|
|
113
136
|
}
|
|
114
|
-
}),
|
|
115
|
-
|
|
116
|
-
"
|
|
117
|
-
"has-
|
|
118
|
-
|
|
119
|
-
},
|
|
120
|
-
$style:
|
|
121
|
-
},
|
|
137
|
+
}), $ = {
|
|
138
|
+
"stash-confirmation-code-input-container": "_stash-confirmation-code-input-container_kwgaz_2",
|
|
139
|
+
"otp-code-input": "_otp-code-input_kwgaz_9",
|
|
140
|
+
"has-error": "_has-error_kwgaz_16",
|
|
141
|
+
"has-success": "_has-success_kwgaz_20"
|
|
142
|
+
}, q = {
|
|
143
|
+
$style: $
|
|
144
|
+
}, J = /* @__PURE__ */ F(R, [["__cssModules", q]]);
|
|
122
145
|
export {
|
|
123
|
-
|
|
146
|
+
J as default
|
|
124
147
|
};
|
|
125
148
|
//# sourceMappingURL=ConfirmationCodeInput.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfirmationCodeInput.js","sources":["../src/components/ConfirmationCodeInput/ConfirmationCodeInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { Ref, ref, useCssModule, watch } from 'vue';\n\n const classes = useCssModule();\n\n export interface VerificationCodeInputProps {\n digitCount?: number;\n /**\n * Error text to display.\n */\n errorText?: string;\n /**\n * Success text to display.\n */\n successText?: string;\n }\n\n const props = withDefaults(defineProps<VerificationCodeInputProps>(), {\n digitCount: 6,\n errorText: undefined,\n successText: undefined,\n });\n\n const emit = defineEmits<{\n (e: 'update:model-value', value:
|
|
1
|
+
{"version":3,"file":"ConfirmationCodeInput.js","sources":["../src/components/ConfirmationCodeInput/ConfirmationCodeInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { onMounted, Ref, ref, useCssModule, watch } from 'vue';\n\n const classes = useCssModule();\n\n export interface VerificationCodeInputProps {\n digitCount?: number;\n /**\n * Error text to display.\n */\n errorText?: string;\n /**\n * Success text to display.\n */\n successText?: string;\n /**\n * Hint text to display.\n */\n hintText?: string;\n /**\n * One time password/code\n */\n modelValue?: string;\n }\n\n const props = withDefaults(defineProps<VerificationCodeInputProps>(), {\n digitCount: 6,\n errorText: undefined,\n successText: undefined,\n hintText: undefined,\n modelValue: undefined,\n });\n\n const emit = defineEmits<{\n (e: 'update:model-value', value: string | null): void;\n (e: 'change', params: { originalEvent: Event; value: string | null }): void;\n (e: 'focus', params: Event): void;\n (e: 'blur', params: Event): void;\n }>();\n\n const data: Ref<Array<string>> = ref([]);\n\n onMounted(() => {\n if (props.modelValue) {\n data.value = props.modelValue?.split('');\n }\n });\n\n function handleInput(event: InputEvent, index) {\n data.value[index] = event.target?.['value'];\n updateModel(event);\n\n if (event.inputType === 'deleteContentBackward') {\n moveToPrev(event);\n } else if (event.inputType === 'insertText' || event.inputType === 'deleteContentForward') {\n moveToNext(event);\n }\n }\n\n function updateModel(event: Event) {\n const newValue = data.value.join('');\n emit('update:model-value', newValue);\n emit('change', { originalEvent: event, value: newValue });\n }\n\n function moveToPrev(event: InputEvent | KeyboardEvent) {\n const prevInput: HTMLInputElement = findPrevInput(event.target as HTMLInputElement);\n\n if (prevInput) {\n prevInput.focus();\n prevInput.select();\n }\n }\n\n function moveToNext(event: InputEvent | KeyboardEvent) {\n const nextInput: HTMLInputElement = findNextInput(event.target as HTMLInputElement);\n\n if (nextInput) {\n nextInput.focus();\n nextInput.select();\n }\n }\n\n function findPrevInput(element: HTMLInputElement) {\n const prevElement = element.previousElementSibling;\n\n if (!prevElement) return;\n\n return prevElement.nodeName === 'INPUT' ? prevElement : findPrevInput(prevElement as HTMLInputElement);\n }\n\n function findNextInput(element: HTMLInputElement) {\n const nextElement = element.nextElementSibling;\n\n if (!nextElement) return;\n\n return nextElement.nodeName === 'INPUT' ? nextElement : findNextInput(nextElement as HTMLInputElement);\n }\n\n function handleFocus(event) {\n event.target.select();\n emit('focus', event);\n }\n\n function handleBlur(event: Event) {\n emit('blur', event);\n }\n\n function handleKeyDown(event: KeyboardEvent) {\n if (event.ctrlKey || event.metaKey) {\n return;\n }\n\n switch (event.code) {\n case 'ArrowLeft':\n moveToPrev(event);\n event.preventDefault();\n break;\n\n case 'ArrowUp':\n case 'ArrowDown':\n event.preventDefault();\n break;\n\n case 'Backspace':\n if (event.target?.['value'].length === 0) {\n moveToPrev(event);\n event.preventDefault();\n }\n break;\n\n case 'ArrowRight':\n moveToNext(event);\n event.preventDefault();\n\n break;\n\n case 'Enter':\n case 'NumpadEnter':\n case 'Tab':\n break;\n\n default:\n if (\n !(event.code !== 'Space' && Number(event.key) >= 0 && Number(event.key) <= 9) ||\n (data.value.join('').length >= props.digitCount && event.code !== 'Delete')\n ) {\n event.preventDefault();\n }\n\n break;\n }\n }\n\n function handlePaste(event: ClipboardEvent) {\n const paste = event.clipboardData?.getData('text');\n\n if (paste?.length) {\n const pastedCode = paste?.substring(0, props.digitCount);\n\n const parsed = parseInt(pastedCode);\n\n if (!isNaN(parsed)) {\n data.value = pastedCode.split('');\n updateModel(event);\n }\n }\n\n event.preventDefault();\n }\n\n watch(\n () => props.modelValue,\n (newValue) => {\n data.value = newValue ? newValue.split('') : new Array(props.digitCount);\n },\n );\n</script>\n\n<template>\n <div\n class=\"stash-confirmation-code-input tw-inline-block\"\n data-test=\"stash-confirmation-code-input\"\n :class=\"[classes['stash-confirmation-code-input-container']]\"\n >\n <div class=\"tw-mb-3 tw-flex tw-gap-6\">\n <template v-for=\"field in props.digitCount\" :key=\"field\">\n <input\n data-test=\"stash-confirmation-code-input__otp\"\n class=\"tw-border tw-bg-white tw-p-2 tw-text-center tw-text-base tw-font-medium tw-text-ice-900 focus:tw-border-blue-500\"\n :class=\"[\n classes['otp-code-input'],\n { [classes['has-error']]: !!props.errorText },\n { [classes['has-success']]: !!props.successText },\n ]\"\n type=\"text\"\n inputmode=\"numeric\"\n maxlength=\"1\"\n :value=\"data[field - 1]\"\n pattern=\"[0-9]\"\n autocomplete=\"one-time-code\"\n @input=\"handleInput($event as InputEvent, field - 1)\"\n @keydown=\"handleKeyDown\"\n @paste=\"handlePaste\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n />\n </template>\n </div>\n <small\n v-if=\"props.errorText\"\n class=\"tw-mt-1 tw-block tw-whitespace-pre-line tw-pr-6 tw-text-center tw-text-red-500\"\n data-test=\"field-error\"\n >\n {{ props.errorText }}\n </small>\n <small\n v-if=\"props.successText\"\n class=\"tw-mt-1 tw-block tw-whitespace-pre-line tw-pr-6 tw-text-center tw-text-green-500\"\n data-test=\"field-success\"\n >\n {{ props.successText }}\n </small>\n <small\n v-if=\"props.hintText\"\n class=\"tw-mt-1 tw-block tw-whitespace-pre-line tw-pr-6 tw-text-center tw-text-ice-700\"\n data-test=\"field-hint\"\n >\n {{ props.hintText }}\n </small>\n </div>\n</template>\n\n<style module>\n .stash-confirmation-code-input-container {\n --otp-digits: v-bind(digitCount);\n --otp-container-width: calc(var(--otp-digits) * 60px);\n\n width: var(--otp-container-width);\n }\n\n .otp-code-input {\n border-radius: 4px;\n caret-color: transparent;\n height: 36px;\n width: 36px;\n }\n\n .otp-code-input.has-error:not(:focus) {\n border-color: var(--color-red-500);\n }\n\n .otp-code-input.has-success:not(:focus) {\n border-color: var(--color-green-500);\n }\n\n .otp-code-input:focus {\n box-shadow: 0 0 0 3px rgb(0 114 240 / 15%);\n outline: none;\n }\n</style>\n"],"names":["classes","useCssModule","props","__props","emit","__emit","data","ref","onMounted","_a","handleInput","event","index","updateModel","moveToPrev","moveToNext","newValue","prevInput","findPrevInput","nextInput","findNextInput","element","prevElement","nextElement","handleFocus","handleBlur","handleKeyDown","handlePaste","paste","pastedCode","parsed","watch"],"mappings":"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"}
|
|
@@ -30,16 +30,34 @@ declare const _default: DefineComponent<ExtractPropTypes<__VLS_WithDefaults<__VL
|
|
|
30
30
|
digitCount: number;
|
|
31
31
|
errorText: undefined;
|
|
32
32
|
successText: undefined;
|
|
33
|
+
hintText: undefined;
|
|
34
|
+
modelValue: undefined;
|
|
33
35
|
}>>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
|
|
34
|
-
"update:model-value": (value:
|
|
36
|
+
"update:model-value": (value: string | null) => void;
|
|
37
|
+
change: (params: {
|
|
38
|
+
originalEvent: Event;
|
|
39
|
+
value: string | null;
|
|
40
|
+
}) => void;
|
|
41
|
+
focus: (params: Event) => void;
|
|
42
|
+
blur: (params: Event) => void;
|
|
35
43
|
}, string, PublicProps, Readonly<ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<VerificationCodeInputProps>, {
|
|
36
44
|
digitCount: number;
|
|
37
45
|
errorText: undefined;
|
|
38
46
|
successText: undefined;
|
|
47
|
+
hintText: undefined;
|
|
48
|
+
modelValue: undefined;
|
|
39
49
|
}>>> & Readonly<{
|
|
40
|
-
|
|
50
|
+
onBlur?: ((params: Event) => any) | undefined;
|
|
51
|
+
onChange?: ((params: {
|
|
52
|
+
originalEvent: Event;
|
|
53
|
+
value: string | null;
|
|
54
|
+
}) => any) | undefined;
|
|
55
|
+
onFocus?: ((params: Event) => any) | undefined;
|
|
56
|
+
"onUpdate:model-value"?: ((value: string | null) => any) | undefined;
|
|
41
57
|
}>, {
|
|
42
58
|
errorText: string;
|
|
59
|
+
hintText: string;
|
|
60
|
+
modelValue: string;
|
|
43
61
|
digitCount: number;
|
|
44
62
|
successText: string;
|
|
45
63
|
}, {}, {}, {}, string, ComponentProvideOptions, true, {}, any>;
|
|
@@ -55,6 +73,14 @@ export declare interface VerificationCodeInputProps {
|
|
|
55
73
|
* Success text to display.
|
|
56
74
|
*/
|
|
57
75
|
successText?: string;
|
|
76
|
+
/**
|
|
77
|
+
* Hint text to display.
|
|
78
|
+
*/
|
|
79
|
+
hintText?: string;
|
|
80
|
+
/**
|
|
81
|
+
* One time password/code
|
|
82
|
+
*/
|
|
83
|
+
modelValue?: string;
|
|
58
84
|
}
|
|
59
85
|
|
|
60
86
|
export { }
|