UNPKG

super-vue3-tabs

Version:

A vue3 tabs component for showing tabs and tab content.

242 lines (241 loc) 15.2 kB
(function(){"use strict";try{if(typeof document<"u"){var t=document.createElement("style");t.appendChild(document.createTextNode('*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.absolute{position:absolute}.relative{position:relative}.left-0{left:0}.right-0{right:0}.m-auto{margin:auto}.mb-1{margin-bottom:.25rem}.mb-4{margin-bottom:1rem}.mt-4{margin-top:1rem}.block{display:block}.flex{display:flex}.h-1{height:.25rem}.h-full{height:100%}.w-1{width:.25rem}.w-6{width:1.5rem}.min-w-max{min-width:-moz-max-content;min-width:max-content}.\\!cursor-default{cursor:default!important}.cursor-pointer{cursor:pointer}.items-center{align-items:center}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.rounded-lg{border-radius:.5rem}.rounded-sm{border-radius:.125rem}.border{border-width:1px}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity))}.p-4{padding:1rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-semibold{font-weight:600}.opacity-50{opacity:.5}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.super-vue3-tabs .tabs{overflow-x:auto;-webkit-user-select:none;-moz-user-select:none;user-select:none;position:relative}.super-vue3-tabs .tabs::-webkit-scrollbar{display:none}.super-vue3-tabs .tabs .underline-marker{position:absolute;bottom:0;left:0;height:3px;transition:left .3s ease;border-radius:16px}.super-vue3-tabs .dropdown{position:absolute;background-color:#f8f8f8;min-width:140px;max-height:300px;overflow:auto;box-shadow:0 4px 20px -2px #0000001a;z-index:1;border-radius:8px}.super-vue3-tabs .dropdown div{padding:8px 12px;margin:4px;text-decoration:none;display:block}.super-vue3-tabs .dropdown div:hover{background-color:#f1f1f1;border-radius:8px}')),document.head.appendChild(t)}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})(); import { getCurrentScope as J, onScopeDispose as K, unref as P, ref as f, computed as C, watch as R, getCurrentInstance as Q, onMounted as Y, defineComponent as F, mergeModels as L, useModel as X, provide as W, onUnmounted as Z, openBlock as v, createElementBlock as h, createElementVNode as k, Fragment as I, renderList as S, normalizeClass as ee, normalizeStyle as A, createBlock as N, resolveDynamicComponent as O, createCommentVNode as E, createTextVNode as z, toDisplayString as j, renderSlot as H, inject as G, useSlots as te, onBeforeMount as oe, withDirectives as ne, vShow as le } from "vue"; const se = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='24'%20height='24'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='currentColor'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%20class='lucide%20lucide-ellipsis-vertical'%3e%3ccircle%20cx='12'%20cy='12'%20r='1'/%3e%3ccircle%20cx='12'%20cy='5'%20r='1'/%3e%3ccircle%20cx='12'%20cy='19'%20r='1'/%3e%3c/svg%3e"; function re(o) { return J() ? (K(o), !0) : !1; } function U(o) { return typeof o == "function" ? o() : P(o); } const ie = typeof window < "u" && typeof document < "u"; typeof WorkerGlobalScope < "u" && globalThis instanceof WorkerGlobalScope; const ae = (o) => o != null, $ = () => { }; function B(o) { var s; const a = U(o); return (s = a == null ? void 0 : a.$el) != null ? s : a; } const q = ie ? window : void 0; function ue() { const o = f(!1), s = Q(); return s && Y(() => { o.value = !0; }, s), o; } function ce(o) { const s = ue(); return C(() => (s.value, !!o())); } function de(o, s, a = {}) { const { root: b, rootMargin: u = "0px", threshold: l = 0.1, window: d = q, immediate: c = !0 } = a, t = ce(() => d && "IntersectionObserver" in d), w = C(() => { const g = U(o); return (Array.isArray(g) ? g : [g]).map(B).filter(ae); }); let p = $; const y = f(c), M = t.value ? R( () => [w.value, B(b), y.value], ([g, V]) => { if (p(), !y.value || !g.length) return; const _ = new IntersectionObserver( s, { root: B(V), rootMargin: u, threshold: l } ); g.forEach((e) => e && _.observe(e)), p = () => { _.disconnect(), p = $; }; }, { immediate: c, flush: "post" } ) : $, T = () => { p(), M(), y.value = !1; }; return re(T), { isSupported: t, isActive: y, pause() { p(), y.value = !1; }, resume() { y.value = !0; }, stop: T }; } function ve(o, s = {}) { const { window: a = q, scrollTarget: b, threshold: u = 0 } = s, l = f(!1); return de( o, (d) => { let c = l.value, t = 0; for (const w of d) w.time >= t && (t = w.time, c = w.isIntersecting); l.value = c; }, { root: b, window: a, threshold: u } ), l; } const fe = { class: "super-vue3-tabs" }, pe = { class: "flex gap-2" }, me = ["id", "onClick"], he = /* @__PURE__ */ k("img", { src: se, width: "16", class: "m-auto" }, null, -1), we = [ he ], ye = { key: 0, class: "dropdown" }, be = ["onClick"], ge = { class: "content" }, xe = /* @__PURE__ */ F({ __name: "Tabs", props: /* @__PURE__ */ L({ themeColor: { default: "#3b82f6" } }, { modelValue: { default: "" }, modelModifiers: {} }), emits: /* @__PURE__ */ L(["change"], ["update:modelValue"]), setup(o, { emit: s }) { const a = o, b = s, u = f(null), l = f([]), d = f({ id: "", value: "" }), c = X(o, "modelValue"), t = f([]), w = f({}), p = f(!1), y = () => { for (let e in t.value) { const r = ve( t.value[e] ); w.value[l.value[e].id] = r; } }, M = C(() => l.value.filter((e) => !w.value[e.id])), T = C(() => { var m, i; const e = l.value.findIndex( (x) => x.id === d.value.id ), r = t.value[e]; return r ? { width: ((m = r == null ? void 0 : r.parentElement) == null ? void 0 : m.offsetWidth) + "px", left: ((i = r == null ? void 0 : r.parentElement) == null ? void 0 : i.offsetLeft) + "px" } : { width: "0px", left: "0px" }; }); W("addTabs", (e) => { l.value.push(e); }), W("activeTab", d), R(t.value, y); const V = function(e) { e.deltaY == 0 || !u.value || (e.preventDefault(), u.value.scrollLeft += e.deltaY); }, _ = ({ tab: e, tabValue: r }) => { var x; if (!e && r && (e = l.value.find((D) => D.value === r)), !e) return; p.value = !1; const n = e.id, m = l.value.findIndex((D) => D.id === n), i = t.value[m]; i && ((x = i == null ? void 0 : i.parentElement) == null || x.scrollIntoView({ behavior: "smooth", block: "nearest" })), d.value = e, c.value = e.value, b("change", e); }; return Y(() => { var e; if ((e = u.value) == null || e.addEventListener("wheel", V), !!l.value.length) { if (c.value) return _({ tabValue: c.value }); _({ tab: l.value[0] }); } }), Z(() => { var e; (e = u.value) == null || e.removeEventListener("wheel", V); }), (e, r) => (v(), h("div", fe, [ k("div", pe, [ k("div", { class: "flex gap-3 tabs", ref_key: "tabsContainerRef", ref: u }, [ (v(!0), h(I, null, S(l.value, (n, m) => (v(), h("div", { key: m, id: n.id, class: ee(["relative flex items-center px-3 py-2 rounded-sm cursor-pointer min-w-max", { "opacity-50 !cursor-default": n.disabled }]), style: A({ color: d.value.id === n.id ? a.themeColor : "", borderBottomColor: d.value.id === n.id ? a.themeColor : "" }), onClick: (i) => n.disabled ? "" : _({ tab: n }) }, [ k("div", { class: "absolute left-0 right-0 w-1 h-1 m-auto tracker-element", ref_for: !0, ref: (i) => { t.value[m] = i; } }, null, 512), n.icon ? (v(!0), h(I, { key: 0 }, S(n.icon(), (i, x) => (v(), N(O(i), { key: x }))), 128)) : E("", !0), z(" " + j(n.value), 1) ], 14, me))), 128)), k("div", { class: "underline-marker", style: A({ width: T.value.width, left: T.value.left, backgroundColor: a.themeColor }) }, null, 4) ], 512), M.value.length ? (v(), h("div", { key: 0, onMouseleave: r[1] || (r[1] = (n) => p.value = !1) }, [ k("button", { class: "w-6 h-full", onMouseover: r[0] || (r[0] = (n) => p.value = !0) }, we, 32), p.value ? (v(), h("div", ye, [ (v(!0), h(I, null, S(M.value, (n) => (v(), h("div", { key: n.id, onClick: (m) => _({ tab: n }), class: "cursor-pointer" }, [ n.icon ? (v(!0), h(I, { key: 0 }, S(n.icon(), (m, i) => (v(), N(O(m), { key: i }))), 128)) : E("", !0), z(" " + j(n.value), 1) ], 8, be))), 128)) ])) : E("", !0) ], 32)) : E("", !0) ]), k("div", ge, [ H(e.$slots, "default") ]) ])); } }), _e = { class: "mt-4" }, Ce = /* @__PURE__ */ F({ __name: "Tab", props: { id: {}, value: {}, disabled: { type: Boolean } }, setup(o) { const s = o, a = f({}), b = G("addTabs", (t) => { console.log(t); }), u = G("activeTab", f({ id: "", value: "" })), l = C(() => s.id || s.value.toLowerCase().replace(/ /g, "-") + "_" + Math.floor(Math.random() * 11)), d = C(() => { var t; return ((t = u == null ? void 0 : u.value) == null ? void 0 : t.id) === l.value; }), c = te(); return oe(() => { let t = { ...s, icon: c == null ? void 0 : c.icon }; t.id || (t.id = l.value), a.value = t, b(t); }), (t, w) => ne((v(), h("div", _e, [ H(t.$slots, "default") ], 512)), [ [le, d.value] ]); } }); export { Ce as Tab, xe as Tabs };