vue3-steppy
Version:
A customizable Vue 3 Stepper plugin
171 lines (170 loc) • 8.19 kB
JavaScript
(function(){try{if(typeof document<`u`){var e=document.createElement(`style`);e.appendChild(document.createTextNode(`body[data-v-dc56ec53]{justify-content:center;align-items:center;width:100%;height:100vh;font-family:sans-serif;display:flex}.tx-default-2[data-v-dc56ec53]{color:var(--primaryColor1);font-weight:600}.wrapper-steppy[data-v-dc56ec53]{padding:60px}.steppy[data-v-dc56ec53]{z-index:0;justify-content:space-between;align-items:center;width:auto;margin-bottom:5px;display:flex;position:relative}.steppy-progress[data-v-dc56ec53]{z-index:-1;background-color:#c5c5c5;height:2px;margin:0 auto;position:absolute;left:0;right:0}.steppy-progress-bar[data-v-dc56ec53]{background-color:var(--primaryColor1);width:0;height:100%;transition:all .5s;position:absolute;left:0}.steppy-item[data-v-dc56ec53]{color:#c5c5c5;flex-direction:column;align-items:center;transition:all .5s;display:flex}.steppy-item-counter[data-v-dc56ec53]{background-color:var(--primaryColor2);border:2px solid #c5c5c5;border-radius:100%;place-items:center;width:68px;height:68px;display:grid;position:relative}.steppy-item-counter .icon-success[data-v-dc56ec53]{opacity:0;width:24px;transition:all .5s;position:absolute;transform:scale(0)}.steppy-item-counter .number[data-v-dc56ec53]{font-size:22px;transition:all .5s}.steppy-item .steppy-item-text[data-v-dc56ec53]{text-align:center;flex-direction:column;align-items:center;gap:2px;width:100%;display:flex;position:absolute;bottom:-58px}.steppy-item .steppy-item-title[data-v-dc56ec53]{font-size:14px;font-weight:500}.steppy-item .steppy-item-description[data-v-dc56ec53]{color:#999;font-size:12px;transition:all .5s}.steppy-item.success .steppy-item-counter[data-v-dc56ec53]{border-color:var(--primaryColor1);height:var(--circleSize);width:var(--circleSize);font-weight:600}.steppy-item.success .steppy-item-counter .icon-success[data-v-dc56ec53]{opacity:1;width:calc(var(--circleSize) * .35);transform:scale(1)}.steppy-item.success .steppy-item-counter .number[data-v-dc56ec53]{opacity:0;font-size:calc(var(--circleSize) * .32);transform:scale(0)}.steppy-item.success .steppy-item-title[data-v-dc56ec53]{color:var(--primaryColor1)}.steppy-item.success .steppy-item-description[data-v-dc56ec53]{color:var(--primaryColor1);opacity:.7}.steppy-item.current .steppy-item-counter[data-v-dc56ec53]{border-color:var(--primaryColor1);background-color:var(--primaryColor1);color:#fff;font-weight:600}.steppy-item.current .steppy-item-title[data-v-dc56ec53]{color:#818181}.steppy-item.current .steppy-item-description[data-v-dc56ec53]{color:#999}.steppy-pane[data-v-dc56ec53]{color:#333;text-align:center;background-color:var(--backgroundColor);margin:var(--contentMarginTop) 0 20px 0;border-radius:15px;padding:25px;box-shadow:0 0 10px #0000004d}.controls[data-v-dc56ec53]{display:flex}.btn[data-v-dc56ec53]{text-align:center;vertical-align:middle;cursor:pointer;color:#333;background-color:#f0f0f0;border:1px solid #f0f0f0;border-radius:4px;justify-content:center;align-items:center;width:fit-content;padding:6px 16px;font-size:.75rem;line-height:1.5;transition:all .15s;display:flex}.btn[data-v-dc56ec53]:disabled{opacity:.5;pointer-events:none}.btn--default-2[data-v-dc56ec53]{background-color:var(--primaryColor1);border-color:var(--primaryColor1);color:#fff;margin-left:auto}.loader[data-v-dc56ec53]{box-sizing:border-box;border:2px solid #fff;border-bottom-color:#0000;border-radius:50%;width:20px;height:20px;animation:1s linear infinite rotation-dc56ec53;display:inline-block}@keyframes rotation-dc56ec53{0%{transform:rotate(0)}to{transform:rotate(360deg)}}/*$vite$:1*/`)),document.head.appendChild(e)}}catch(e){console.error(`vite-plugin-css-injected-by-js`,e)}})();
import { Fragment as e, computed as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, normalizeClass as o, normalizeStyle as s, openBlock as c, reactive as l, renderList as u, renderSlot as d, toDisplayString as f } from "vue";
//#region src/components/CheckMark.vue
var p = {
__name: "CheckMark",
props: { color: {
type: String,
default: "black"
} },
setup(e) {
return (t, n) => (c(), i("svg", {
viewBox: "0 0 24 24",
style: s({ fill: e.color })
}, [...n[0] ||= [a("path", { d: "M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z" }, null, -1)]], 4));
}
}, m = (e, t) => {
let n = e.__vccOpts || e;
for (let [e, r] of t) n[e] = r;
return n;
}, h = { class: "steppy" }, g = { class: "steppy-progress" }, _ = ["src"], v = { class: "number" }, y = { class: "steppy-item-text" }, b = { class: "steppy-item-title" }, x = {
key: 0,
class: "steppy-item-description"
}, S = {
key: 0,
class: "steppy-pane"
}, C = { class: "controls" }, w = ["disabled"], T = ["disabled"], E = {
key: 0,
class: "loader"
}, D = { key: 1 }, O = /*#__PURE__*/ m({
__name: "Vue3Steppy",
props: {
step: {
type: Number,
default: 1
},
tabs: {
type: Array,
default: l([
{
title: "Step 1",
iconSuccess: null,
isValid: !0
},
{
title: "Step 2",
iconSuccess: null,
isValid: !0
},
{
title: "Step 3",
iconSuccess: null,
isValid: !0
}
])
},
finalize: {
type: Function,
default: function() {
return {};
}
},
backText: {
type: String,
default: "Back"
},
nextText: {
type: String,
default: "Next"
},
doneText: {
type: String,
default: "Done"
},
loading: {
type: Boolean,
default: !1
},
primaryColor1: {
type: String,
default: "orange"
},
primaryColor2: {
type: String,
default: "#fff"
},
backgroundColor: {
type: String,
default: "#fff"
},
circleSize: {
type: Number,
default: 68
},
contentMarginTop: {
type: Number,
default: 60
}
},
emits: ["update:step"],
setup(l, { emit: m }) {
let O = m, k = l, A = t(() => ({
"--primaryColor1": k.primaryColor1,
"--primaryColor2": k.primaryColor2,
"--backgroundColor": k.backgroundColor,
"--circleSize": `${k.circleSize}px`,
"--contentMarginTop": `${k.contentMarginTop}px`
})), j = () => {
let e = k.step + 1;
O("update:step", e);
}, M = () => {
let e = k.step - 1;
O("update:step", e);
}, N = t(() => 100 / (k.tabs.length - 1) * (k.step - 1) + "%"), P = t(() => ({
height: `${k.circleSize}px`,
width: `${k.circleSize}px`
}));
return (t, m) => (c(), i("div", {
class: "wrapper-steppy",
style: s(A.value)
}, [
a("div", h, [a("div", g, [a("div", {
class: "steppy-progress-bar",
style: s("width:" + N.value)
}, null, 4)]), (c(!0), i(e, null, u(k.tabs, (e, t) => (c(), i("div", {
class: o(["steppy-item", {
current: k.step === t + 1,
success: k.step > t + 1
}]),
key: t
}, [a("div", {
class: "steppy-item-counter",
style: s(P.value)
}, [e.iconSuccess ? (c(), i("img", {
key: 0,
class: "icon-success",
src: e.iconSuccess,
alt: "Check Mark"
}, null, 8, _)) : (c(), n(p, {
key: 1,
class: "icon-success",
color: l.primaryColor1,
alt: "Check Mark"
}, null, 8, ["color"])), a("span", v, f(t + 1), 1)], 4), a("div", y, [a("span", b, f(e.title), 1), e.description ? (c(), i("span", x, f(e.description), 1)) : r("", !0)])], 2))), 128))]),
(c(!0), i(e, null, u(k.tabs.length, (e) => (c(), i("div", {
class: "steppy-content",
key: e
}, [k.step === e ? (c(), i("div", S, [d(t.$slots, e, {}, void 0, !0)])) : r("", !0)]))), 128)),
a("div", C, [k.step === 1 ? r("", !0) : (c(), i("button", {
key: 0,
class: "btn",
type: "button",
onClick: M
}, f(k.backText), 1)), k.step === k.tabs.length ? (c(), i("button", {
key: 2,
class: "btn btn--default-2",
type: "button",
onClick: m[0] ||= (...e) => l.finalize && l.finalize(...e),
disabled: !k.tabs[k.step - 1].isValid || l.loading
}, [l.loading ? (c(), i("span", E)) : (c(), i("span", D, f(k.doneText), 1))], 8, T)) : (c(), i("button", {
key: 1,
class: "btn btn--default-2",
type: "button",
onClick: j,
disabled: !k.tabs[k.step - 1].isValid
}, f(k.nextText), 9, w))])
], 4));
}
}, [["__scopeId", "data-v-dc56ec53"]]);
//#endregion
export { O as Steppy };