UNPKG

vue-smart-ui

Version:

A collection of Vue 3 smart and highly customizable UI components for modern web applications

1,748 lines 100 kB
import { computed as T, ref as A, provide as Me, createElementBlock as o, openBlock as n, unref as J, normalizeClass as L, renderSlot as U, inject as Oe, onMounted as te, onUnmounted as ue, watch as oe, createElementVNode as v, createCommentVNode as w, createTextVNode as se, toDisplayString as j, normalizeStyle as le, nextTick as ie, createVNode as Y, Transition as $e, withCtx as ne, withDirectives as ye, vShow as xe, useSlots as _e, withKeys as Re, createBlock as ce, Teleport as qe, withModifiers as re, Fragment as Q, renderList as Z, resolveDynamicComponent as Le, createApp as je, h as Ee, createSlots as Pe, vModelDynamic as ze, TransitionGroup as Fe, mergeProps as De } from "vue"; let he = 0; function ee(e = "base", x) { const t = () => (he++, `${e}-${he}`); return { autoId: T(() => x.id || t()) }; } const Ne = ["id"], Ke = { __name: "BaseAccordion", props: { id: { type: String, default: "" }, multiple: { type: Boolean, default: !1 }, variant: { type: String, default: "default", validator: (e) => ["default", "bordered", "minimal"].includes(e) } }, setup(e) { const x = e, { autoId: t } = ee("accordion", x), a = A([]); return Me("accordion", { activeItems: a, toggleItem: (l) => { if (x.multiple) { const b = a.value.indexOf(l); b === -1 ? a.value.push(l) : a.value.splice(b, 1); } else a.value = a.value.includes(l) ? [] : [l]; }, variant: x.variant }), (l, b) => (n(), o("div", { class: L(["vsui base-accordion", `base-accordion--${e.variant}`]), id: J(t) }, [ U(l.$slots, "default") ], 10, Ne)); } }, He = ["disabled", "aria-expanded"], Ue = { class: "base-accordion-item__body" }, We = { __name: "BaseAccordionItem", props: { title: { type: String, required: !0 }, disabled: { type: Boolean, default: !1 } }, setup(e) { const x = e, t = Oe("accordion"), a = A(Symbol()), i = A("0px"), l = A(null), b = T(() => t.activeItems.value.includes(a.value)), u = T(() => t.variant), r = () => { x.disabled || t.toggleItem(a.value); }, g = () => { l.value && (i.value = b.value ? `${l.value.scrollHeight}px` : "0px"); }, S = new ResizeObserver(g); return te(() => { l.value && (S.observe(l.value), g()); }), ue(() => { S.disconnect(); }), oe(b, g), ($, R) => (n(), o("div", { class: L(["vsui base-accordion-item", [ `base-accordion-item--${u.value}`, { "base-accordion-item--active": b.value, "base-accordion-item--disabled": e.disabled } ]]) }, [ v("button", { class: "base-accordion-item__header", onClick: r, disabled: e.disabled, "aria-expanded": b.value }, [ $.$slots.icon ? U($.$slots, "icon", { key: 0 }) : w("", !0), U($.$slots, "title", {}, () => [ se(j(e.title), 1) ]), U($.$slots, "chevron", {}, () => [ R[0] || (R[0] = v("svg", { class: "base-accordion-item__chevron", viewBox: "0 0 24 24", width: "1.2em", height: "1.2em" }, [ v("path", { fill: "currentColor", d: "M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" }) ], -1)) ]) ], 8, He), v("div", { class: "base-accordion-item__content", ref_key: "contentRef", ref: l, style: le({ height: i.value }) }, [ v("div", Ue, [ U($.$slots, "default") ]) ], 4) ], 2)); } }, Ge = ["id", "disabled"], Xe = { key: 0, class: "spinner" }, de = /* @__PURE__ */ Object.assign({ inheritAttrs: !1 }, { __name: "BaseButton", props: { id: { type: String, default: "" }, type: { type: String, default: "button", validator: (e) => ["button", "submit", "reset"].includes(e) }, variant: { type: String, default: "primary", validator: (e) => ["primary", "secondary", "gray", "outline", "ghost"].includes(e) }, size: { type: String, default: "medium", validator: (e) => ["small", "medium", "large", "auto"].includes(e) }, block: { type: Boolean, default: !1 }, disabled: { type: Boolean, default: !1 }, loading: { type: Boolean, default: !1 }, iconOnly: { type: Boolean, default: !1 } }, emits: ["click"], setup(e) { const x = e, { autoId: t } = ee("button", x); return (a, i) => (n(), o("button", { id: J(t), class: L(["vsui base-button", [ `base-button--${e.variant}`, `base-button--${e.size}`, { "base-button--block": e.block, "base-button--disabled": e.disabled || e.loading, "base-button--icon-only": e.iconOnly, "base-button--loading": e.loading }, a.$attrs.class ]]), disabled: e.disabled || e.loading, onClick: i[0] || (i[0] = (l) => a.$emit("click", l)) }, [ v("div", { class: L(["button-content", [{ hidden: e.loading }, a.$attrs.class]]) }, [ a.$slots.prefix ? U(a.$slots, "prefix", { key: 0 }) : w("", !0), U(a.$slots, "default"), a.$slots.suffix ? U(a.$slots, "suffix", { key: 1 }) : w("", !0) ], 2), e.loading ? (n(), o("div", Xe)) : w("", !0) ], 10, Ge)); } }), Qe = ["id", "checked", "disabled", "indeterminate"], Je = { class: "base-checkbox__checkmark" }, Ye = { key: 0, viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, Ze = { key: 1, viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, et = { key: 0, class: "base-checkbox__label" }, ve = { __name: "BaseCheckbox", props: { id: { type: String, default: "" }, modelValue: { type: [Boolean, Array], default: !1 }, value: { type: [String, Number, Boolean, Object], default: null }, label: { type: String, default: "" }, size: { type: String, default: "medium", validator: (e) => ["small", "medium", "large"].includes(e) }, disabled: { type: Boolean, default: !1 }, error: { type: Boolean, default: !1 }, indeterminate: { type: Boolean, default: !1 } }, emits: ["update:modelValue"], setup(e, { emit: x }) { const t = e, { autoId: a } = ee("checkbox", t), i = x, l = T(() => Array.isArray(t.modelValue) ? t.modelValue.includes(t.value) : t.modelValue), b = (u) => { if (Array.isArray(t.modelValue)) { const r = [...t.modelValue]; if (u.target.checked) r.push(t.value); else { const g = r.indexOf(t.value); g > -1 && r.splice(g, 1); } i("update:modelValue", r); } else i("update:modelValue", u.target.checked); }; return (u, r) => (n(), o("label", { class: L([ "vsui base-checkbox", `base-checkbox--${e.size}`, { "base-checkbox--disabled": e.disabled, "base-checkbox--error": e.error } ]) }, [ v("input", { id: J(a), type: "checkbox", checked: l.value, disabled: e.disabled, indeterminate: e.indeterminate, class: "base-checkbox__input", onChange: b }, null, 40, Qe), v("span", Je, [ U(u.$slots, "checkmark", {}, () => [ l.value && !e.indeterminate ? (n(), o("svg", Ye, r[0] || (r[0] = [ v("path", { d: "M11.6666 3.5L5.24992 9.91667L2.33325 7", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, null, -1) ]))) : w("", !0), e.indeterminate ? (n(), o("svg", Ze, r[1] || (r[1] = [ v("path", { d: "M2.91675 7H11.0834", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, null, -1) ]))) : w("", !0) ]) ]), u.$slots.default || e.label ? (n(), o("span", et, [ U(u.$slots, "default", {}, () => [ se(j(e.label), 1) ]) ])) : w("", !0) ], 2)); } }, tt = ["id"], at = { __name: "BaseDropdown", props: { id: { type: String, default: "" }, modelValue: { type: Boolean, default: !1 }, variant: { type: String, default: "default", validator: (e) => ["default", "white", "dark"].includes(e) }, width: { type: String, default: "auto" }, closeOnClick: { type: Boolean, default: !0 }, closeOnClickOutside: { type: Boolean, default: !0 } }, emits: ["update:modelValue"], setup(e, { emit: x }) { const t = e, { autoId: a } = ee("dropdown", t), i = x, l = A(null), b = A(null), u = A(t.modelValue), r = () => { if (!b.value || !l.value) return; const $ = b.value.getBoundingClientRect(), R = l.value.getBoundingClientRect(), M = { width: window.innerWidth, height: window.innerHeight }; b.value.style.top = "100%", b.value.style.bottom = "auto", b.value.style.left = "auto", b.value.style.right = "0", R.right + $.width > M.width && (b.value.style.right = "0", b.value.style.left = "auto"), R.right - $.width < 0 && (b.value.style.left = "0", b.value.style.right = "auto"), R.bottom + $.height > M.height && (b.value.style.bottom = "100%", b.value.style.top = "auto", b.value.style.marginTop = "0", b.value.style.marginBottom = "0.5rem"); }; oe( () => t.modelValue, ($) => { u.value = $, $ ? (document.addEventListener("click", g), ie(() => { r(); })) : document.removeEventListener("click", g); } ); const g = ($) => { t.closeOnClickOutside && l.value && !l.value.contains($.target) && i("update:modelValue", !1); }, S = ($) => { t.closeOnClick && !$.target.closest("[data-prevent-close]") && i("update:modelValue", !1); }; return te(() => { t.modelValue && document.addEventListener("click", g), window.addEventListener("scroll", r, !0), window.addEventListener("resize", r); }), ue(() => { document.removeEventListener("click", g), window.removeEventListener("scroll", r, !0), window.removeEventListener("resize", r); }), ($, R) => (n(), o("div", { ref_key: "dropdownRef", ref: l, class: "vsui base-dropdown", id: J(a) }, [ v("div", { class: "base-dropdown__trigger", onClick: R[0] || (R[0] = (M) => i("update:modelValue", !e.modelValue)) }, [ U($.$slots, "trigger") ]), Y($e, { name: "dropdown" }, { default: ne(() => [ ye(v("div", { ref_key: "menuRef", ref: b, class: L(["base-dropdown__menu", `base-dropdown__menu--${e.variant}`]), style: le({ width: e.width }), onClick: S }, [ U($.$slots, "default") ], 6), [ [xe, u.value] ]) ]), _: 3 }) ], 8, tt)); } }, lt = { class: "vsui infinite-scroll" }, st = { class: "infinite-scroll__loader" }, nt = { key: 0 }, ot = { key: 0, class: "infinite-scroll__end" }, rt = { __name: "BaseInfiniteScroll", props: { loading: { type: Boolean, default: !1 }, disabled: { type: Boolean, default: !1 }, threshold: { type: Number, default: 20 // pixels before the end to trigger }, container: { type: String, default: null // If null, uses window }, loadingText: { type: String, default: "Loading more items..." }, endText: { type: String, default: "There are no more items to load" } }, emits: ["load-more"], setup(e, { emit: x }) { const t = e, a = x, i = A(null), l = A(null), b = () => { i.value && i.value.disconnect(), i.value = new IntersectionObserver( (u) => { u[0].isIntersecting && !t.loading && !t.disabled && a("load-more"); }, { threshold: 0, root: t.container ? document.querySelector(t.container) : null, rootMargin: `0px 0px ${t.threshold}px 0px` } ), l.value && i.value.observe(l.value); }; return oe( () => t.loading, (u, r) => { r === !0 && u === !1 && setTimeout(() => { b(); }, 100); } ), te(() => { b(); }), ue(() => { i.value && i.value.disconnect(); }), (u, r) => (n(), o("div", lt, [ U(u.$slots, "default"), v("div", { ref_key: "bottomElement", ref: l, class: "infinite-scroll__trigger" }, [ e.loading ? U(u.$slots, "loading", { key: 0 }, () => [ v("div", st, [ r[0] || (r[0] = v("div", { class: "spinner" }, null, -1)), e.loadingText ? (n(), o("span", nt, j(e.loadingText), 1)) : w("", !0) ]) ]) : e.disabled ? U(u.$slots, "disabled", { key: 1 }, () => [ e.endText ? (n(), o("div", ot, j(e.endText), 1)) : w("", !0) ]) : w("", !0) ], 512) ])); } }, it = { key: 0, class: "base-input__label" }, ut = { key: 0, class: "base-input__required", "aria-hidden": "true" }, dt = { class: "base-input__wrapper" }, ct = { key: 0, class: "base-input__prefix" }, ft = ["id", "type", "value", "placeholder", "disabled", "readonly", "required", "aria-required", "maxlength", "min", "max"], vt = { key: 1, class: "base-input__suffix" }, me = { __name: "BaseInput", props: { id: { type: String, default: "" }, modelValue: { type: [String, Number], default: "" }, variant: { type: String, default: "default", validator: (e) => ["default", "filled", "outlined"].includes(e) }, state: { type: String, default: null, validator: (e) => ["success", "error", "warning"].includes(e) }, type: { type: String, default: "text" }, label: { type: String, default: null }, placeholder: { type: String, default: "" }, disabled: { type: Boolean, default: !1 }, readonly: { type: Boolean, default: !1 }, required: { type: Boolean, default: !1 }, helperText: { type: String, default: null }, errorMessage: { type: String, default: null }, prefixIcon: { type: String, default: null }, suffixIcon: { type: String, default: null }, rules: { type: Array, default: () => [] }, validateOnBlur: { type: Boolean, default: !0 }, validateOnInput: { type: Boolean, default: !1 }, name: { type: String, default: "" }, min: { type: [Number, String], default: null }, max: { type: [Number, String], default: null }, mask: { type: [String, Object], default: null } }, emits: ["update:modelValue", "focus", "blur", "input", "validation", "mounted"], setup(e, { emit: x }) { const t = _e(), a = e, { autoId: i } = ee("input", a), l = x, b = A(null), u = A(!1), r = A(""), g = T(() => ({ "vsui base-input": !0, [`base-input--${a.variant}`]: !0, [`base-input--${h.value}`]: h.value, "base-input--disabled": a.disabled, "base-input--focused": u.value, "base-input--with-prefix": a.prefixIcon || t.prefix, "base-input--with-suffix": a.suffixIcon || t.suffix })), S = { required: (s) => ({ valid: !!(s != null && s.toString().trim()), message: "This field is required" }), email: (s) => ({ valid: !s || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s), message: "Please enter a valid email" }), min: (s, y) => ({ valid: !s || s.length >= y, message: `Must be at least ${y} characters` }), max: (s, y) => ({ valid: !s || s.length <= y, message: `Must be no more than ${y} characters` }), pattern: (s, y) => ({ valid: !s || new RegExp(y).test(s), message: "Invalid format" }), minValue: (s, y) => ({ valid: !s || Number(s) >= y, message: `Value must be at least ${y}` }), maxValue: (s, y) => ({ valid: !s || Number(s) <= y, message: `Value must be no more than ${y}` }), hexColor: (s) => ({ valid: !s || /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(s), message: "Invalid HEX color" }), rgbColor: (s) => ({ valid: !s || /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/.test(s), message: "Invalid RGB color" }), rgbaColor: (s) => ({ valid: !s || /^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0|0?\.\d+|1(\.0)?)\s*\)$/.test(s), message: "Invalid RGBA color" }), hslColor: (s) => ({ valid: !s || /^hsl\(\s*(\d{1,3})\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*\)$/.test(s), message: "Invalid HSL color" }) }, $ = (s) => { if (!a.rules.length) return !0; for (const y of a.rules) { if (typeof y == "string") { const I = S[y]; if (I) { const E = I(s); if (!E.valid) return r.value = E.message, !1; } continue; } if (typeof y == "object") { const [I, E] = Object.entries(y)[0]; console.log(I, E); const W = S[I]; if (W) { const p = W(s, E); if (!p.valid) return r.value = y.message || p.message, !1; } if (typeof y.validator == "function" && !y.validator(s)) return r.value = y.message || "Invalid value", !1; } } return r.value = "", !0; }, R = T({ get: () => a.mask === "currency" && a.modelValue ? M.currency.format(a.modelValue) : a.modelValue, set: (s) => l("update:modelValue", s) }), M = { phone: { patterns: ["(##) ####-####", "(##) #####-####"], match: (s) => s.replace(/\D/g, "").length <= 10 ? 0 : 1 }, currency: { pattern: "currency", format: (s) => { if (!s) return ""; const y = typeof s == "string" ? parseFloat(s.replace(/\D/g, "")) / 100 : s; return new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL", minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(y); }, parse: (s) => { const y = s.replace(/[^\d]/g, ""); return parseFloat(y) / 100; } }, date: "##/##/####", cpf: "###.###.###-##", cnpj: "##.###.###/####-##", cep: "#####-###" }, N = (s, y) => { if (!s) return s; if (y === "currency" || y.pattern === "currency") { const I = M.currency.parse(s); return M.currency.format(I); } if (typeof y == "string") return z(s, y); if (y.patterns) { const I = y.match(s); return z(s, y.patterns[I]); } return s; }, z = (s, y) => { if (!y) return s; const E = s.replace(/\D/g, "").split(""); let W = "", p = 0; for (let k = 0; k < y.length && E[k]; k++) y[p] === "#" ? (W += E[k], p++) : (W += y[p], p++, k--); return W; }, K = (s) => { let y = s.target.value; if (a.mask) { const I = typeof a.mask == "string" ? M[a.mask] || a.mask : a.mask.pattern; y = N(y, I), b.value && (b.value.value = y); } if (a.mask === "currency") { const I = M.currency.parse(y); R.value = I, l("update:modelValue", I); } else R.value = y, l("update:modelValue", y); if (l("input", { ...s, target: { ...s.target, value: y } }), a.validateOnInput) { const I = $(R.value); l("validation", { valid: I, error: r.value }); } }, q = (s) => { u.value = !0, l("enter", s); }, f = (s) => { u.value = !0, l("focus", s); }, d = (s) => { if (u.value = !1, l("blur", s), a.validateOnBlur) { const y = $(R.value); l("validation", { valid: y, error: r.value }); } }, c = () => { var s; (s = b.value) == null || s.focus(); }, h = T(() => r.value ? "error" : a.state), B = T(() => r.value ? r.value : a.errorMessage || a.helperText), O = () => { const s = $(R.value); return l("validation", { valid: s, error: r.value, name: a.name }), s; }, F = T(() => a.required ? !0 : a.rules.some((s) => s === "required" ? !0 : typeof s == "object" ? s.required || Object.keys(s)[0] === "required" : !1)), _ = T(() => { if (!a.mask) return; const s = typeof a.mask == "string" ? M[a.mask] || a.mask : a.mask.pattern; if (typeof s == "string") return s.length; if (s.patterns) return Math.max(...s.patterns.map((y) => y.length)); }); return te(() => { l("mounted", { validate: O, focus: c }); }), (s, y) => (n(), o("div", { class: L(g.value) }, [ e.label ? (n(), o("label", it, [ se(j(e.label) + " ", 1), F.value ? (n(), o("span", ut, "*")) : w("", !0) ])) : w("", !0), v("div", dt, [ s.$slots.prefix || e.prefixIcon ? (n(), o("div", ct, [ U(s.$slots, "prefix", {}, () => [ v("i", { class: L(e.prefixIcon) }, null, 2) ]) ])) : w("", !0), v("input", { id: J(i), ref_key: "inputRef", ref: b, type: e.type, value: R.value, placeholder: e.placeholder, disabled: e.disabled, readonly: e.readonly, required: F.value, "aria-required": F.value, maxlength: _.value, min: e.min, max: e.max, class: "base-input__field", onInput: K, onFocus: f, onBlur: d, onKeydown: Re(q, ["enter"]) }, null, 40, ft), s.$slots.suffix || e.suffixIcon ? (n(), o("div", vt, [ U(s.$slots, "suffix", {}, () => [ v("i", { class: L(e.suffixIcon) }, null, 2) ]) ])) : w("", !0) ]), B.value ? (n(), o("div", { key: 1, class: L(["base-input__helper", { "base-input__helper--error": r.value }]) }, j(B.value), 3)) : w("", !0) ], 2)); } }, mt = { key: 0, class: "base-popup__header" }, bt = { class: "base-popup__content" }, pt = { key: 1, class: "base-popup__footer" }, gt = { __name: "BasePopup", props: { modelValue: { type: Boolean, default: !1 }, variant: { type: String, default: "default", validator: (e) => ["default", "info", "success", "warning", "error"].includes(e) }, size: { type: String, default: "medium", validator: (e) => ["small", "medium", "large"].includes(e) }, position: { type: String, default: "center", validator: (e) => ["center", "top", "bottom", "left", "right"].includes(e) }, disableClickOutside: { type: Boolean, default: !1 }, closeOnEsc: { type: Boolean, default: !0 } }, emits: ["update:modelValue", "close"], setup(e, { emit: x }) { const t = e, a = x, i = A(null), l = (u) => { !t.disableClickOutside && i.value && !i.value.contains(u.target) && (u.target.closest(".base-popup") || (a("update:modelValue", !1), a("close"))); }, b = (u) => { t.closeOnEsc && u.key === "Escape" && (a("update:modelValue", !1), a("close")); }; return te(() => { document.addEventListener("mousedown", l), document.addEventListener("keydown", b); }), ue(() => { document.removeEventListener("mousedown", l), document.removeEventListener("keydown", b); }), (u, r) => (n(), ce(qe, { to: "body" }, [ e.modelValue ? (n(), o("div", { key: 0, class: L(["vsui base-popup-overlay", [`base-popup-overlay--${e.position}`]]) }, [ v("div", { ref_key: "popupRef", ref: i, class: L(["base-popup", [`base-popup--${e.variant}`, `base-popup--${e.size}`, `base-popup--${e.position}`]]) }, [ u.$slots.header ? (n(), o("div", mt, [ U(u.$slots, "header") ])) : w("", !0), v("div", bt, [ U(u.$slots, "default") ]), u.$slots.footer ? (n(), o("div", pt, [ U(u.$slots, "footer") ])) : w("", !0), u.$slots.close ? (n(), o("button", { key: 2, class: "base-popup__close", onClick: r[0] || (r[0] = (g) => u.$emit("update:modelValue", !1)) }, [ U(u.$slots, "close") ])) : w("", !0) ], 2) ], 2)) : w("", !0) ])); } }, ge = { __name: "BaseSkeleton", props: { variant: { type: String, default: "rectangle", validator: (e) => ["rectangle", "circle", "text", "heading", "button"].includes(e) }, width: { type: String, default: "100%" }, height: { type: String, default: null }, animated: { type: Boolean, default: !0 }, rounded: { type: Boolean, default: !1 } }, setup(e) { return (x, t) => (n(), o("div", { class: L(["vsui base-skeleton", [ `base-skeleton--${e.variant}`, { "base-skeleton--animated": e.animated, "base-skeleton--rounded": e.rounded } ]]), style: le({ width: e.width, height: e.height || null }) }, [ U(x.$slots, "default") ], 6)); } }, yt = ["for"], ht = { key: 0, class: "base-slider__required" }, kt = { class: "base-slider__container" }, wt = { class: "base-slider__extremity-value base-slider__extremity-value--min" }, $t = { key: 0, class: "base-slider__mark-label" }, xt = ["onMousedown", "onTouchstart", "onKeydown", "aria-valuemin", "aria-valuemax", "aria-valuenow", "aria-valuetext", "aria-disabled"], _t = { key: 0, class: "base-slider__thumb-value" }, Vt = { class: "base-slider__extremity-value base-slider__extremity-value--max" }, St = { key: 1, class: "base-slider__helper" }, Bt = { __name: "BaseSlider", props: { id: { type: String, default: "" }, modelValue: { type: [Number, Array], default: 0 }, min: { type: Number, default: 0 }, max: { type: Number, default: 100 }, step: { type: Number, default: 1 }, label: { type: String, default: null }, disabled: { type: Boolean, default: !1 }, required: { type: Boolean, default: !1 }, helperText: { type: String, default: null }, errorMessage: { type: String, default: null }, state: { type: String, default: null, validator: (e) => ["success", "error", "warning"].includes(e) }, showValue: { type: Boolean, default: !0 }, range: { type: Boolean, default: !1 }, variant: { type: String, default: "default", validator: (e) => ["default", "filled"].includes(e) }, marks: { type: Array, default: () => [] }, formatValue: { type: Function, default: null } }, emits: ["update:modelValue", "change", "mounted"], setup(e, { emit: x }) { const t = e, a = x, { autoId: i } = ee("slider", t), l = A(t.modelValue), b = A(!1), u = A(null), r = A([]), g = T(() => t.range && Array.isArray(t.modelValue)), S = T(() => t.formatValue ? g.value ? l.value.map((q) => t.formatValue(q)) : t.formatValue(l.value) : l.value), $ = T(() => { if (g.value) { const [q, f] = l.value, d = (q - t.min) / (t.max - t.min) * 100, c = (f - t.min) / (t.max - t.min) * 100; return { left: `${d}%`, width: `${c - d}%` }; } else return { width: `${(l.value - t.min) / (t.max - t.min) * 100}%` }; }), R = T(() => g.value ? l.value.map((q) => `${(q - t.min) / (t.max - t.min) * 100}%`) : [`${(l.value - t.min) / (t.max - t.min) * 100}%`]), M = T(() => ({ "base-slider--disabled": t.disabled, "base-slider--success": t.state === "success", "base-slider--error": t.state === "error", "base-slider--warning": t.state === "warning", "base-slider--filled": t.variant === "filled" })); oe( () => t.modelValue, (q) => { l.value = q; } ), oe(l, (q) => { a("update:modelValue", q); }); const N = (q, f = 0) => { if (t.disabled) return; const d = u.value.getBoundingClientRect(), c = q.clientX - d.left, h = Math.min(Math.max(c / d.width, 0), 1), B = t.min + h * (t.max - t.min), O = Math.round(B / t.step) * t.step, F = Math.min(Math.max(O, t.min), t.max); if (g.value) { const _ = [...l.value]; _[f] = F, f === 0 && _[0] > _[1] ? _[0] = _[1] : f === 1 && _[1] < _[0] && (_[1] = _[0]), l.value = _; } else l.value = F; a("change", l.value); }, z = (q, f = 0) => { if (t.disabled) return; b.value = !0, N(q, f); const d = (h) => N(h, f), c = () => { b.value = !1, document.removeEventListener("mousemove", d), document.removeEventListener("mouseup", c), document.removeEventListener("touchmove", d), document.removeEventListener("touchend", c); }; document.addEventListener("mousemove", d), document.addEventListener("mouseup", c), document.addEventListener("touchmove", d), document.addEventListener("touchend", c); }, K = (q, f = 0) => { if (t.disabled) return; const d = g.value ? l.value[f] : l.value; let c = d; switch (q.key) { case "ArrowRight": case "ArrowUp": c = Math.min(d + t.step, t.max); break; case "ArrowLeft": case "ArrowDown": c = Math.max(d - t.step, t.min); break; case "Home": c = t.min; break; case "End": c = t.max; break; default: return; } if (g.value) { const h = [...l.value]; h[f] = c, f === 0 && h[0] > h[1] ? h[0] = h[1] : f === 1 && h[1] < h[0] && (h[1] = h[0]), l.value = h; } else l.value = c; a("change", l.value), q.preventDefault(); }; return te(() => { g.value && (!Array.isArray(l.value) || l.value.length !== 2) ? l.value = [t.min, t.max] : !g.value && Array.isArray(l.value) && (l.value = t.min), a("mounted", { id: i.value, getValue: () => l.value, setValue: (q) => { l.value = q; } }); }), (q, f) => (n(), o("div", { class: L(["vsui base-slider", M.value]) }, [ e.label ? (n(), o("label", { key: 0, for: J(i), class: "base-slider__label" }, [ se(j(e.label) + " ", 1), e.required ? (n(), o("span", ht, "*")) : w("", !0) ], 8, yt)) : w("", !0), v("div", kt, [ v("div", wt, j(e.formatValue ? e.formatValue(e.min) : e.min), 1), v("div", { ref_key: "sliderTrack", ref: u, class: "base-slider__track", onMousedown: f[0] || (f[0] = (d) => N(d)), onTouchstart: f[1] || (f[1] = re((d) => N(d.touches[0]), ["prevent"])) }, [ v("div", { class: "base-slider__track-fill", style: le($.value) }, null, 4), (n(!0), o(Q, null, Z(e.marks, (d) => (n(), o("div", { key: d.value, class: L(["base-slider__mark", { "base-slider__mark--active": g.value ? d.value >= l.value[0] && d.value <= l.value[1] : d.value <= l.value }]), style: le({ left: `calc(${(d.value - e.min) / (e.max - e.min) * 100}%)` }) }, [ f[2] || (f[2] = v("div", { class: "base-slider__mark-dot" }, null, -1)), d.label ? (n(), o("div", $t, j(d.label), 1)) : w("", !0) ], 6))), 128)), (n(!0), o(Q, null, Z(R.value, (d, c) => (n(), o("div", { key: c, ref_for: !0, ref_key: "thumbRefs", ref: r, class: "base-slider__thumb", style: le({ left: d }), onMousedown: re((h) => z(h, c), ["stop"]), onTouchstart: re((h) => z(h.touches[0], c), ["stop", "prevent"]), onKeydown: (h) => K(h, c), tabindex: "0", role: "slider", "aria-valuemin": e.min, "aria-valuemax": e.max, "aria-valuenow": g.value ? l.value[c] : l.value, "aria-valuetext": g.value ? S.value[c] : S.value, "aria-disabled": e.disabled }, [ e.showValue ? (n(), o("div", _t, j(g.value ? S.value[c] : S.value), 1)) : w("", !0) ], 44, xt))), 128)) ], 544), v("div", Vt, j(e.formatValue ? e.formatValue(e.max) : e.max), 1) ]), e.helperText || e.errorMessage ? (n(), o("div", St, j(e.errorMessage || e.helperText), 1)) : w("", !0) ], 2)); } }, Ct = { key: 0, class: "base-textarea__label" }, It = { key: 0, class: "base-textarea__required", "aria-hidden": "true" }, Tt = { class: "base-textarea__wrapper" }, At = ["id", "value", "rows", "placeholder", "disabled", "readonly", "required", "aria-required"], Mt = { __name: "BaseTextarea", props: { id: { type: String, default: "" }, modelValue: { type: String, default: "" }, variant: { type: String, default: "default", validator: (e) => ["default", "filled", "outlined"].includes(e) }, state: { type: String, default: null, validator: (e) => ["success", "error", "warning"].includes(e) }, label: { type: String, default: null }, placeholder: { type: String, default: "" }, rows: { type: [String, Number], default: 3 }, maxRows: { type: [String, Number], default: null }, disabled: { type: Boolean, default: !1 }, block: { type: Boolean, default: !1 }, readonly: { type: Boolean, default: !1 }, required: { type: Boolean, default: !1 }, helperText: { type: String, default: null }, errorMessage: { type: String, default: null }, rules: { type: Array, default: () => [] }, validateOnBlur: { type: Boolean, default: !0 }, validateOnInput: { type: Boolean, default: !1 }, name: { type: String, default: "" }, resize: { type: String, default: "vertical", validator: (e) => ["none", "both", "horizontal", "vertical"].includes(e) }, autoResize: { type: Boolean, default: !1 } }, emits: ["update:modelValue", "focus", "blur", "input", "validation", "mounted"], setup(e, { emit: x }) { const t = e, { autoId: a } = ee("textarea", t), i = x, l = A(null), b = A(!1), u = A(""), r = T(() => ({ "vsui base-textarea": !0, [`base-textarea--${t.variant}`]: !0, [`base-textarea--${q.value}`]: q.value, "base-textarea--disabled": t.disabled, "base-textarea--focused": b.value, "base-textarea--block": t.block, [`base-textarea--resize-${t.resize}`]: !0 })), g = { required: (c) => ({ valid: !!(c != null && c.toString().trim()), message: "This field is required" }), min: (c, h) => ({ valid: !c || c.toString().length >= h, message: `Must be at least ${h} characters` }), max: (c, h) => ({ valid: !c || c.toString().length <= h, message: `Must be no more than ${h} characters` }) }, S = () => { const c = $(t.modelValue); return i("validation", { valid: c, error: u.value, name: t.name }), c; }, $ = (c) => { if (!t.rules.length) return !0; for (const h of t.rules) { if (typeof h == "string") { const B = g[h]; if (B) { const O = B(c); if (!O.valid) return u.value = O.message, !1; } continue; } if (typeof h == "object") { const [B, O] = Object.entries(h)[0], F = g[B]; if (F) { const _ = F(c, O); if (!_.valid) return u.value = h.message || _.message, !1; } if (typeof h.validator == "function" && !h.validator(c)) return u.value = h.message || "Invalid value", !1; } } return u.value = "", !0; }, R = (c) => { if (i("update:modelValue", c.target.value), i("input", c), t.validateOnInput) { const h = $(c.target.value); i("validation", { valid: h, error: u.value }); } t.autoResize && z(); }, M = (c) => { b.value = !0, i("focus", c); }, N = (c) => { if (b.value = !1, i("blur", c), t.validateOnBlur) { const h = $(c.target.value); i("validation", { valid: h, error: u.value }); } }, z = () => { if (!l.value) return; l.value.style.height = "auto"; let c = l.value.scrollHeight + 2; if (t.maxRows) { const B = parseInt(getComputedStyle(l.value).lineHeight) * t.maxRows; c = Math.min(c, B); } l.value.style.height = `${c}px`; }, K = () => { var c; (c = l.value) == null || c.focus(); }, q = T(() => u.value ? "error" : t.state), f = T(() => u.value ? u.value : t.errorMessage || t.helperText), d = T(() => t.required ? !0 : t.rules.some( (c) => c === "required" || typeof c == "object" && c.required )); return te(() => { t.autoResize && z(), i("mounted", { validate: S, focus: K }); }), (c, h) => (n(), o("div", { class: L(r.value) }, [ e.label ? (n(), o("label", Ct, [ se(j(e.label) + " ", 1), d.value ? (n(), o("span", It, "*")) : w("", !0) ])) : w("", !0), v("div", Tt, [ v("textarea", { id: J(a), ref_key: "textareaRef", ref: l, value: e.modelValue, rows: e.rows, placeholder: e.placeholder, disabled: e.disabled, readonly: e.readonly, required: d.value, "aria-required": d.value, class: "base-textarea__field", onInput: R, onFocus: M, onBlur: N }, null, 40, At) ]), f.value ? (n(), o("div", { key: 1, class: L(["base-textarea__helper", { "base-textarea__helper--error": u.value }]) }, j(f.value), 3)) : w("", !0) ], 2)); } }, be = (e, x) => { const t = e.__vccOpts || e; for (const [a, i] of x) t[a] = i; return t; }, Ot = {}, Rt = { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }; function qt(e, x) { return n(), o("svg", Rt, x[0] || (x[0] = [ v("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }, null, -1), v("polyline", { points: "22 4 12 14.01 9 11.01" }, null, -1) ])); } const Lt = /* @__PURE__ */ be(Ot, [["render", qt]]), jt = {}, Et = { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }; function Pt(e, x) { return n(), o("svg", Et, x[0] || (x[0] = [ v("circle", { cx: "12", cy: "12", r: "10" }, null, -1), v("line", { x1: "15", y1: "9", x2: "9", y2: "15" }, null, -1), v("line", { x1: "9", y1: "9", x2: "15", y2: "15" }, null, -1) ])); } const zt = /* @__PURE__ */ be(jt, [["render", Pt]]), Ft = {}, Dt = { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }; function Nt(e, x) { return n(), o("svg", Dt, x[0] || (x[0] = [ v("path", { d: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }, null, -1), v("line", { x1: "12", y1: "9", x2: "12", y2: "13" }, null, -1), v("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" }, null, -1) ])); } const Kt = /* @__PURE__ */ be(Ft, [["render", Nt]]), Ht = {}, Ut = { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }; function Wt(e, x) { return n(), o("svg", Ut, x[0] || (x[0] = [ v("circle", { cx: "12", cy: "12", r: "10" }, null, -1), v("line", { x1: "12", y1: "16", x2: "12", y2: "12" }, null, -1), v("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" }, null, -1) ])); } const ke = /* @__PURE__ */ be(Ht, [["render", Wt]]), Gt = ["data-toast-id"], Xt = { key: 0, class: "base-toast__icon" }, Qt = { class: "base-toast__content" }, Jt = { key: 0, class: "base-toast__title" }, Yt = { class: "base-toast__message" }, Ve = { __name: "BaseToast", props: { id: { type: [String, Number], required: !0 }, variant: { type: String, default: "default", validator: (e) => ["default", "info", "success", "warning", "error"].includes(e) }, position: { type: String, default: "top-right", validator: (e) => [ "top-right", "top-left", "top-center", "bottom-right", "bottom-left", "bottom-center" ].includes(e) }, duration: { type: Number, default: 3e3 }, closable: { type: Boolean, default: !0 }, message: { type: String, required: !0 }, title: { type: String, default: "" }, simple: { type: Boolean, default: !1 } }, emits: ["close"], setup(e, { emit: x }) { const t = e, a = x, i = A(!1), l = A(null), b = A("100%"), u = () => { t.duration > 0 && (b.value = "100%", requestAnimationFrame(() => { requestAnimationFrame(() => { b.value = "0%"; }); })); }, r = () => { i.value = !1, setTimeout(() => { a("close"); }, 100); }, g = () => { l.value && (l.value.style.animationPlayState = "paused"); }, S = () => { l.value && (l.value.style.animationPlayState = "running"); }, $ = { success: Lt, error: zt, warning: Kt, info: ke, default: ke }, R = T(() => $[t.variant] || $.default); return te(() => { var M; setTimeout(() => { i.value = !0; }, 100), t.duration > 0 && (t.simple ? setTimeout(r, t.duration) : (M = l.value) == null || M.addEventListener("animationend", r, { once: !0 })), u(); }), ue(() => { l.value && l.value.removeEventListener("animationend", r); }), (M, N) => (n(), o("div", { "data-toast-id": e.id, class: L(["vsui base-toast", [ `base-toast--${e.variant}`, `base-toast--${e.position}`, { "base-toast--visible": i.value }, { "base-toast--simple": e.simple } ]]), onMouseenter: g, onMouseleave: S }, [ e.simple ? w("", !0) : (n(), o("div", Xt, [ (n(), ce(Le(R.value), { class: "icon" })) ])), v("div", Qt, [ !e.simple && e.title ? (n(), o("div", Jt, j(e.title), 1)) : w("", !0), v("div", Yt, j(e.message), 1) ]), e.closable ? (n(), o("button", { key: 1, class: "base-toast__close", onClick: r }, N[0] || (N[0] = [ v("span", null, "×", -1) ]))) : w("", !0), !e.simple && e.duration > 0 ? (n(), o("div", { key: 2, ref_key: "progressBarRef", ref: l, class: L(["progress-bar", `progress-bar--${e.variant}`]), style: le({ animationDuration: `${e.duration}ms` }) }, null, 6)) : w("", !0) ], 42, Gt)); } }, fe = A([]); let Zt = 0, we = null; function ea() { const e = () => { if (we) return; const a = document.createElement("div"); a.id = "toast-container", document.body.appendChild(a), we = je({ render: () => Ee(Be) }).mount(a); }, x = ({ message: a, title: i = "", variant: l = "default", position: b = "top-right", duration: u = 3e3, closable: r = !0, simple: g = !1 }) => { e(); const S = ++Zt; return fe.value.push({ id: S, message: a, title: i, variant: l, position: b, duration: u, closable: r, simple: g }), S; }; return { toasts: fe, addToast: x, removeToast: (a) => { const i = fe.value.findIndex((l) => l.id === a); i > -1 && fe.value.splice(i, 1); }, // Convenience methods default: (a, i = {}) => x({ ...i, message: a, variant: "default" }), success: (a, i = {}) => x({ ...i, message: a, variant: "success" }), error: (a, i = {}) => x({ ...i, message: a, variant: "error" }), info: (a, i = {}) => x({ ...i, message: a, variant: "info" }), warning: (a, i = {}) => x({ ...i, message: a, variant: "warning" }) }; } const ta = { class: "vsui base-segmented-buttons-wrapper" }, aa = { key: 0, class: "base-segmented-buttons__label" }, la = { key: 0, class: "base-segmented-buttons__required" }, sa = ["id"], na = ["disabled", "onClick"], oa = { __name: "BaseSegmentedButtons", props: { id: { type: String, default: "" }, modelValue: { type: [String, Number, Array], default: () => [] }, options: { type: Array, default: () => [], required: !0 }, valueKey: { type: String, default: "value" }, labelKey: { type: String, default: "label" }, variant: { type: String, default: "primary", validator: (e) => ["primary", "secondary", "gray"].includes(e) }, size: { type: String, default: "medium", validator: (e) => ["small", "medium", "large"].includes(e) }, disabled: { type: Boolean, default: !1 }, block: { type: Boolean, default: !1 }, multiple: { type: Boolean, default: !1 }, label: { type: String, default: null }, helperText: { type: String, default: null }, errorMessage: { type: String, default: null }, rules: { type: Array, default: () => [] }, validateOnChange: { type: Boolean, default: !0 } }, emits: ["update:modelValue", "change", "validation", "mounted"], setup(e, { emit: x }) { const t = e, { autoId: a } = ee("segmented-buttons", t), i = x, l = A(""), b = A(!1), u = { required: (f) => ({ valid: Array.isArray(f) ? f.length > 0 : !!f, message: "This field is required" }), min: (f, d) => ({ valid: !Array.isArray(f) || f.length >= d, message: `Select at least ${d} option${d > 1 ? "s" : ""}` }), max: (f, d) => ({ valid: !Array.isArray(f) || f.length <= d, message: `Select no more than ${d} option${d > 1 ? "s" : ""}` }) }, r = (f) => { if (!t.rules.length) return !0; for (const d of t.rules) { if (typeof d == "string") { if (d.includes(":")) { const [c, h] = d.split(":"), B = u[c]; if (B) { const O = B(f, parseInt(h, 10)); if (!O.valid) return l.value = O.message, !1; } } else if (u[d]) { const c = u[d](f); if (!c.valid) return l.value = c.message, !1; } continue; } if (typeof d == "object") { if (d.message) { let c, h; for (const O in d) if (O !== "message") { c = O, h = d[O]; break; } const B = u[c]; if (B) { const O = B(f, h); if (!O.valid) return l.value = d.message || O.message, !1; } } else if (typeof d.validator == "function" && !d.validator(f)) return l.value = d.message || "Invalid selection", !1; } } return l.value = "", !0; }, g = T({ get: () => t.modelValue, set: (f) => { if (i("update:modelValue", f), i("change", f), t.validateOnChange) { b.value = !0; const d = r(f); i("validation", { valid: d, error: l.value }); } } }), S = T(() => ({ "vsui base-segmented-buttons"