UNPKG

vue-smart-ui

Version:

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

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