vue3-router-tab 1.4.2 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- (function(E,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("vue"),require("vue-router")):typeof define=="function"&&define.amd?define(["exports","vue","vue-router"],n):(E=typeof globalThis<"u"?globalThis:E||self,n(E["vue3-router-tab"]={},E.Vue,E.VueRouter))})(this,(function(E,n,Ie){"use strict";function xe(e={}){return{initialTabs:e.initialTabs??[],keepAlive:e.keepAlive??!0,maxAlive:e.maxAlive??0,keepLastTab:e.keepLastTab??!0,appendPosition:e.appendPosition??"last",defaultRoute:e.defaultRoute??"/"}}function I(e,a){const r=e.resolve(a);if(!r||!r.matched.length)throw new Error(`[RouterTabs] Unable to resolve route: ${String(a)}`);return r}const De={path:e=>e.path,fullpath:e=>e.fullPath,fullname:e=>e.fullPath,full:e=>e.fullPath,name:e=>e.name?String(e.name):e.fullPath};function V(e){const a=e.meta?.key;if(typeof a=="function"){const r=a(e);if(typeof r=="string"&&r.length)return r}else if(typeof a=="string"&&a.length){const r=De[a.toLowerCase()];return r?r(e):a}return e.fullPath}function te(e,a){const r=e.meta?.keepAlive;return typeof r=="boolean"?r:a}function ne(e,a){const r=e.meta?.reuse;return typeof r=="boolean"?r:a}function he(e){const a=e.meta??{},r={};return"title"in a&&(r.title=a.title),"tips"in a&&(r.tips=a.tips),"icon"in a&&(r.icon=a.icon),"closable"in a&&(r.closable=a.closable),"tabClass"in a&&(r.tabClass=a.tabClass),"target"in a&&(r.target=a.target),"href"in a&&(r.href=a.href),r}function W(e,a,r){const c=he(e);return{id:V(e),to:e.fullPath,fullPath:e.fullPath,matched:e,alive:te(e,r),reusable:ne(e,!1),closable:c.closable??!0,renderKey:typeof a.renderKey=="number"?a.renderKey:0,...c,...a}}function oe(e,a,r,c){if(!e.find(g=>g.id===a.id)){if(r==="next"&&c){const g=e.findIndex(w=>w.id===c);if(g!==-1){e.splice(g+1,0,a);return}}e.push(a)}}function J(e,a,r,c){if(!a||a<=0)return;const i=e.filter(g=>g.alive);for(;i.length>a;){const g=i.shift();if(!g||g.id===r)continue;const w=e.findIndex(l=>l.id===g.id);if(w>-1){const l=e[w],y=`${l.id}::${l.renderKey??0}`;c.delete(y),l.alive=!1}}}function Me(e){return{to:e.to,title:e.title,tips:e.tips,icon:e.icon,tabClass:e.tabClass,closable:e.closable,renderKey:e.renderKey}}function Le(e){const a={};return"title"in e&&(a.title=e.title),"tips"in e&&(a.tips=e.tips),"icon"in e&&(a.icon=e.icon),"tabClass"in e&&(a.tabClass=e.tabClass),"closable"in e&&(a.closable=e.closable),"renderKey"in e&&typeof e.renderKey=="number"&&(a.renderKey=e.renderKey),a}function Ve(e,a={}){const r=xe(a),c=n.reactive([]),i=n.ref(null),g=n.shallowRef(),w=n.ref(null),l=n.reactive(new Set),y=n.computed(()=>Array.from(l));let h=!1;function v(u){const b=typeof u.matched=="object"?u:I(e,u);return{key:V(b),fullPath:b.fullPath,alive:te(b,r.keepAlive),reusable:ne(b,!1),matched:b}}function S(u){const b=V(u);let d=c.find(k=>k.id===b);const T=te(u,r.keepAlive);if(d){d.fullPath=u.fullPath,d.to=u.fullPath,d.matched=u,d.reusable=ne(u,d.reusable),typeof d.renderKey!="number"&&(d.renderKey=0);const k=`${b}::${d.renderKey}`;return T?l.has(k)?d.alive||(d.alive=!0):(l.add(k),d.alive=!0):d.alive&&(l.delete(k),d.alive=!1),Object.assign(d,he(u)),d}if(d=W(u,{},r.keepAlive),d.alive){const k=`${b}::${d.renderKey??0}`;l.add(k)}return oe(c,d,r.appendPosition,i.value),J(c,r.maxAlive,i.value,l),d}async function $(u,b=!1,d="sameTab"){const T=I(e,u),k=V(T),B=i.value===k;d==="sameTab"&&(d=B),d&&await M(k,!0),await e[b?"replace":"push"](T),B&&await U()}function x(u){const b=c.findIndex(K=>K.id===u);if(b===-1)return r.defaultRoute;const d=c[b+1],T=c[b-1],k=c.find(K=>K.id!==u),B=d||T||k;return B?B.to:r.defaultRoute}async function D(u=i.value,b={}){if(!u)return;if(!b.force&&r.keepLastTab&&c.length===1)throw new Error("[RouterTabs] Unable to close the final tab when keepLastTab is true.");const T=i.value===u&&b.redirect!==null,k=T?b.redirect??x(u):null;await _(u,{force:b.force}),b.redirect!==null&&T&&k&&await e.replace(k)}async function _(u,b={}){const d=c.findIndex(B=>B.id===u);if(d===-1)return;const T=c[d],k=`${u}::${T.renderKey??0}`;l.delete(k),T.alive=!1,c.splice(d,1),w.value===u&&(w.value=null),i.value===u&&(i.value=null,g.value=void 0)}async function M(u=i.value??void 0,b=!1){if(!u)return;const d=c.find(K=>K.id===u);if(!d)return;const T=r.keepAlive&&d.alive,k=`${u}::${d.renderKey??0}`;T&&(l.delete(k),d.alive=!1,await n.nextTick()),d.renderKey=(d.renderKey??0)+1;const B=`${u}::${d.renderKey}`;T&&(l.add(B),d.alive=!0),w.value=u,await n.nextTick(),b||await n.nextTick(),w.value=null}async function se(u=!1){for(const b of c)await M(b.id,u)}function ce(u,b){const d=c.find(k=>k.id===u);if(!d)return;const T=`${u}::${d.renderKey??0}`;b?(l.add(T),d.alive=!0,J(c,r.maxAlive,i.value,l)):(l.delete(T),d.alive=!1)}function C(u){const b=c.find(T=>T.id===u);if(!b)return;const d=`${u}::${b.renderKey??0}`;l.delete(d),b.alive=!1,b.renderKey=(b.renderKey??0)+1}function Z(){l.clear(),c.forEach(u=>{u.alive=!1})}function L(){return y.value.slice()}async function A(u=r.defaultRoute){c.splice(0,c.length),i.value=null,g.value=void 0;for(const b of r.initialTabs){const d=I(e,b.to),T=W(d,b,r.keepAlive);c.push(T)}await e.replace(u)}async function U(){const u=i.value;u&&await M(u,!0)}function z(u){return typeof u.matched=="object"?V(u):V(I(e,u))}function R(){const u=c.find(b=>b.id===i.value);return{tabs:c.map(Me),active:u?u.to:null}}async function ue(u){h=!0,c.splice(0,c.length),i.value=null,g.value=void 0;const b=u?.tabs??[];for(const T of b)try{const k=I(e,T.to),B=Le(T),K=W(k,B,r.keepAlive);oe(c,K,"last",null)}catch(k){console.warn("[RouterTabs] Failed to restore tab",T,k)}h=!1;const d=u?.active??b[b.length-1]?.to??r.defaultRoute;if(d)try{const T=I(e,d),k=e.currentRoute.value;if(T.fullPath===k.fullPath){const B=S(k);i.value=B.id,g.value=B,J(c,r.maxAlive,i.value,l);return}await e.replace(T)}catch(T){console.warn("[RouterTabs] Failed to navigate to restored route",d,T)}}return n.watch(()=>e.currentRoute.value,u=>{if(h)return;const b=S(u);i.value=b.id,g.value=b,J(c,r.maxAlive,i.value,l)},{immediate:!0}),r.initialTabs.length&&r.initialTabs.forEach(u=>{const b=I(e,u.to),d=W(b,u,r.keepAlive);oe(c,d,"last",null)}),{options:r,tabs:c,activeId:i,current:g,includeKeys:y,refreshingKey:w,openTab:$,closeTab:D,removeTab:_,refreshTab:M,refreshAll:se,setTabAlive:ce,evictCache:C,clearCache:Z,getCacheKeys:L,reset:A,reload:U,getRouteKey:z,matchRoute:v,snapshot:R,hydrate:ue,ensureTab:S}}function ye(e){return e?typeof e=="string"?{name:e}:e:{}}const O=Symbol("RouterTabsContext"),q="router-tabs:snapshot";function re(e={}){const{optional:a=!1}=e,r=n.inject(O,null);if(r)return r;const c=n.inject("$tabs",null);if(c)return c;const g=n.getCurrentInstance()?.appContext.config.globalProperties.$tabs;if(g)return g;if(!a)throw new Error("[RouterTabs] useRouterTabs must be used within <router-tab>.");return null}const Ne=864e5;function Oe(e){if(typeof document>"u")return null;const a=`${encodeURIComponent(e)}=`,r=document.cookie?document.cookie.split("; "):[];for(const c of r)if(c.startsWith(a))return decodeURIComponent(c.slice(a.length));return null}function Te(e,a,r){if(typeof document>"u")return;const{expiresInDays:c=7,path:i="/",domain:g,secure:w,sameSite:l="lax"}=r,y=[`${encodeURIComponent(e)}=${encodeURIComponent(a)}`];if(c!==1/0){const h=new Date(Date.now()+c*Ne).toUTCString();y.push(`Expires=${h}`)}i&&y.push(`Path=${i}`),g&&y.push(`Domain=${g}`),w&&y.push("Secure"),l&&y.push(`SameSite=${l.charAt(0).toUpperCase()}${l.slice(1)}`),document.cookie=y.join("; ")}function ke(e,a){if(typeof document>"u")return;const{path:r="/",domain:c}=a,i=[`${encodeURIComponent(e)}=`];i.push("Expires=Thu, 01 Jan 1970 00:00:01 GMT"),r&&i.push(`Path=${r}`),c&&i.push(`Domain=${c}`),document.cookie=i.join("; ")}const je=e=>JSON.stringify(e??null),_e=e=>{if(!e)return null;try{return JSON.parse(e)}catch{return null}};function ae(e={}){const{cookieKey:a=q,serialize:r=je,deserialize:c=_e}=e,i=re({optional:!0}),g=n.ref(!0),w=(l,y="hook")=>{const h=async()=>{g.value=!0;try{const v=c(Oe(a));if(v&&v.tabs?.length){if(await l.hydrate(v),v.active){await n.nextTick();const $=l.tabs.find(x=>x.to===v.active);$&&(l.activeId.value=$.id,l.current.value=$)}}else if(Object.prototype.hasOwnProperty.call(e,"fallbackRoute")){const $=e.fallbackRoute??l.options.defaultRoute;await l.reset($)}const S=l.snapshot();S.tabs.length?Te(a,r(S),e):ke(a,e)}finally{g.value=!1}};y==="immediate"?h():n.onBeforeMount(()=>{h()}),n.watch(()=>({tabs:l.tabs.map(v=>({to:v.to,title:v.title,tips:v.tips,icon:v.icon,tabClass:v.tabClass,closable:v.closable,renderKey:v.renderKey})),active:l.activeId.value}),()=>{if(g.value)return;const v=l.snapshot();v.tabs.length?Te(a,r(v),e):ke(a,e)},{deep:!0})};return i?w(i):n.onMounted(()=>{const l=re({optional:!0});l&&w(l,"immediate")}),{hydrating:g}}const Ue=n.defineComponent({name:"RouterTab",components:{RouterView:Ie.RouterView},props:{tabs:{type:Array,default:()=>[]},keepAlive:{type:Boolean,default:!0},maxAlive:{type:Number,default:0},keepLastTab:{type:Boolean,default:!0},append:{type:String,default:"last"},defaultPage:{type:[String,Object],default:"/"},tabTransition:{type:[String,Object],default:"router-tab-zoom"},pageTransition:{type:[String,Object],default:()=>({name:"router-tab-swap",mode:"out-in"})},contextmenu:{type:[Boolean,Array],default:!0},cookieKey:{type:String,default:q},persistence:{type:Object,default:null},sortable:{type:Boolean,default:!0}},emits:["tab-sort","tab-sorted"],setup(e,{emit:a}){const r=n.getCurrentInstance();if(!r)throw new Error("[RouterTab] component must be used within a Vue application context.");const c=r.appContext.app.config.globalProperties.$router;if(!c)throw new Error("[RouterTab] Vue Router is required. Make sure to call app.use(router) before RouterTab.");const i=Ve(c,{initialTabs:e.tabs,keepAlive:e.keepAlive,maxAlive:e.maxAlive,keepLastTab:e.keepLastTab,appendPosition:e.append,defaultRoute:e.defaultPage});n.provide(O,i),r.appContext.config.globalProperties.$tabs=i;const g=n.computed(()=>!!r?.slots?.default),w=n.computed(()=>!!r?.slots?.start),l=n.computed(()=>!!r?.slots?.end),y=n.ref(0),h=n.computed(()=>{y.value;const t={};return i.tabs.forEach(o=>{const s=typeof o.title=="string"?o.title:String(o.title||de(o));t[o.id]=s}),t});function v(){y.value++}const S=new Map,$=new Map;function x(t,o){if(!(!o||S.has(t)))try{S.set(t,o);const s=i.tabs.find(p=>i.getRouteKey(p.to)===t);if(!s){console.warn(`[RouterTab] Cannot setup watching: tab not found for ${t}`);return}const m=[];if(o.routeTabTitle!==void 0)try{const p=n.watch(()=>{const f=o.routeTabTitle;return f&&typeof f=="object"&&"value"in f?f.value:f},f=>{if(f!=null){const N=String(f);s.title=N,v()}},{immediate:!0});m.push(p)}catch(p){console.error(`[RouterTab] Error watching routeTabTitle for ${t}:`,p)}if(o.routeTabIcon!==void 0)try{const p=n.watch(()=>{const f=o.routeTabIcon;return f&&typeof f=="object"&&"value"in f?f.value:f},f=>{f!=null&&(s.icon=String(f),v())},{immediate:!0});m.push(p)}catch(p){console.error(`[RouterTab] Error watching routeTabIcon for ${t}:`,p)}if(o.routeTabClosable!==void 0)try{const p=n.watch(()=>{const f=o.routeTabClosable;return f&&typeof f=="object"&&"value"in f?f.value:f},f=>{f!=null&&(s.closable=!!f,v())},{immediate:!0});m.push(p)}catch(p){console.error(`[RouterTab] Error watching routeTabClosable for ${t}:`,p)}if(o.routeTabMeta!==void 0)try{const p=n.watch(()=>{const f=o.routeTabMeta;return f&&typeof f=="object"&&"value"in f?f.value:f},f=>{f&&typeof f=="object"&&(Object.assign(s,f),v())},{immediate:!0,deep:!0});m.push(p)}catch(p){console.error(`[RouterTab] Error watching routeTabMeta for ${t}:`,p)}$.set(t,m)}catch(s){console.error(`[RouterTab] Error in setupComponentWatching for ${t}:`,s),D(t)}}function D(t){try{const o=$.get(t);o&&(o.forEach(s=>{try{s()}catch(m){console.error(`[RouterTab] Error cleaning up watcher for ${t}:`,m)}}),$.delete(t)),S.delete(t)}catch(o){console.error(`[RouterTab] Error in cleanupComponentWatching for ${t}:`,o)}}function _(t,o){try{t?t.routeTabTitle!==void 0||t.routeTabIcon!==void 0||t.routeTabClosable!==void 0?x(o,t):t.$&&(t.$.routeTabTitle!==void 0||t.$.routeTabIcon!==void 0||t.$.routeTabClosable!==void 0)&&x(o,t.$):t===null&&D(o)}catch(s){console.error(`[RouterTab] Error handling component ref for ${o}:`,s),D(o)}}n.onErrorCaptured((t,o,s)=>(console.error("[RouterTab] Error captured from component:",t,s),!1));let M=n.ref(!1);if(e.cookieKey!==null||e.persistence){const t={...e.persistence??{}};e.cookieKey!==null?t.cookieKey=e.cookieKey||q:t.cookieKey||(t.cookieKey=q),M=ae(t).hydrating}const se=n.computed(()=>ye(e.tabTransition)),ce=n.computed(()=>ye(e.pageTransition)),C=n.reactive({visible:!1,target:null,position:{x:0,y:0}}),Z=n.ref(null),L=n.ref([]),A=n.ref(-1),U=n.ref(null),z=new Map,R=n.reactive({dragging:!1,dragIndex:-1,dropIndex:-1,dragTab:null}),ue=["refresh","refreshAll","close","closeLefts","closeRights","closeOthers"];function u(t){return i.tabs.findIndex(o=>o.id===t)}function b(t){const o=u(t.id);return o>0?i.tabs.slice(0,o):[]}function d(t){const o=u(t.id);return o>-1?i.tabs.slice(o+1):[]}function T(t){return i.tabs.filter(o=>o.id!==t.id)}async function k(t,o){const s=t.filter(m=>m.closable!==!1);if(s.length){for(const m of s)i.activeId.value===m.id?await i.closeTab(m.id,{redirect:o.to,force:!0}):await i.removeTab(m.id,{force:!0});i.activeId.value!==o.id&&await i.openTab(o.to,!0,!1)}}const B={refresh:{label:"Refresh",handler:async({target:t})=>{await i.refreshTab(t.id,!0)}},refreshAll:{label:"Refresh All",handler:async()=>{await i.refreshAll(!0)}},close:{label:"Close",handler:async({target:t})=>{await i.closeTab(t.id)},enable:({target:t})=>be(t)},closeLefts:{label:"Close to the Left",handler:async({target:t})=>{await k(b(t),t)},enable:({target:t})=>b(t).some(o=>o.closable!==!1)},closeRights:{label:"Close to the Right",handler:async({target:t})=>{await k(d(t),t)},enable:({target:t})=>d(t).some(o=>o.closable!==!1)},closeOthers:{label:"Close Others",handler:async({target:t})=>{await k(T(t),t)},enable:({target:t})=>T(t).some(o=>o.closable!==!1)}};function K(){C.visible=!1,C.target=null,A.value=-1,L.value=[]}function ut(t,o){e.contextmenu&&(C.target=t,C.position.x=o.clientX,C.position.y=o.clientY,n.nextTick(()=>{C.visible=!0,document.addEventListener("click",K,{once:!0}),n.nextTick(()=>{ft()})}))}function dt(t,o){const s=typeof t=="string"?{id:t}:t,m=B[s.id],p=s.label??m?.label??String(s.id),f=s.visible??m?.visible??!0;if(!(typeof f=="function"?f(o):f!==!1))return null;const ge=s.enable??m?.enable??!0,xt=typeof ge=="function"?ge(o):ge!==!1,Ae=s.handler??m?.handler;if(!Ae)return null;const Dt=async()=>{await Promise.resolve(Ae(o))};return{id:String(s.id),label:p,disabled:!xt,action:Dt}}const F=n.computed(()=>{if(!C.visible||!C.target||e.contextmenu===!1)return[];const t=Array.isArray(e.contextmenu)?e.contextmenu:ue,o={target:C.target,controller:i};return t.map(s=>dt(s,o)).filter(s=>!!s)});function ft(){const t=Z.value;if(!t)return;const o=8,{innerWidth:s,innerHeight:m}=window,p=t.getBoundingClientRect();let f=C.position.x,N=C.position.y;p.right>s-o&&(f=Math.max(o,s-p.width-o)),p.bottom>m-o&&(N=Math.max(o,m-p.height-o)),(f!==C.position.x||N!==C.position.y)&&(C.position.x=f,C.position.y=N)}function bt(t,o){L.value[o]=t??null}function mt(t){if(t<0)return;L.value[t]?.focus({preventScroll:!0})}function ee(t,o,s=F.value){if(!s.length)return-1;const m=s.length;let p=t;for(let f=0;f<m;f++)if(p=(p+o+m)%m,!s[p].disabled)return p;return-1}function Y(t){A.value=t,!(t<0)&&n.nextTick(()=>mt(t))}function Be(t){const o=ee(A.value,t);o!==-1&&Y(o)}function pt(t){if(!C.visible)return;const o=t.key,s=F.value;if(!s.length)return;if(o==="Tab"){K();return}if(["ArrowDown","ArrowUp","ArrowRight","ArrowLeft","Home","End","Enter"," ","Spacebar","Escape"].includes(o))switch(t.preventDefault(),o){case"ArrowDown":case"ArrowRight":Be(1);break;case"ArrowUp":case"ArrowLeft":Be(-1);break;case"Home":Y(ee(-1,1));break;case"End":Y(ee(s.length,-1));break;case"Enter":case" ":case"Spacebar":{const p=A.value;if(p>-1){const f=s[p];f.disabled||Pe(f)}break}case"Escape":K();break}}async function Pe(t){t.disabled||(K(),await t.action())}function de(t){return typeof t.title=="string"&&t.title.trim()?t.title:Array.isArray(t.title)&&t.title.length&&String(t.title[0]).trim()?String(t.title[0]):"Untitled"}function gt(t){return h.value[t.id]||de(t)}function $e(t,o){return n.defineComponent({name:o,setup(s,{attrs:m,slots:p}){return()=>n.h(t,m,p)}})}const H=new Map,fe=n.ref(0);function ht(t,o,s){H.has(s)||(H.set(s,o),fe.value++),t&&_(t,s)}function yt(t,o){return t&&((!t.name||t.name!==o)&&(t.name=o),t)}function Tt(t,o){if(!t)return t;const s=H.get(o);if(s)return s;const m=$e(t,o);return H.set(o,m),fe.value++,m}function kt(t){const o=i.getRouteKey(t),s=c.currentRoute.value,m=i.getRouteKey(s);return o===m}function vt(t){const o=i.getRouteKey(t),s=i.tabs.find(f=>f.id===o);if(!s)return console.warn("[RouterTab] Tab not found for route:",o),`${o}::0`;const m=s.renderKey??0,p=`${o}::${m}`;return(o.includes("students")||o.includes("classroom")||o.includes("quiz"))&&console.log(`[getComponentCacheKey] Route: ${t.fullPath}`,{routeKey:o,renderKey:m,cacheKey:p,tabAlive:s.alive,includeKeys:pe.value,isIncluded:pe.value.includes(p)}),p}function be(t){return!(t.closable===!1||i.options.keepLastTab&&i.tabs.length<=1)}async function wt(t){await i.closeTab(t.id)}function Ct(t,o){o?z.set(t,o):z.delete(t)}function me(t){n.nextTick(()=>{const o=z.get(t),s=U.value;if(o&&s){const m=o.getBoundingClientRect(),p=s.getBoundingClientRect();(m.left<p.left||m.right>p.right)&&o.scrollIntoView({behavior:"smooth",block:"nearest",inline:"nearest"})}})}function Rt(t){if(t.href&&typeof window<"u"){t.target&&t.target!=="_self"?window.open(t.href,t.target):window.location.assign(t.href);return}i.activeId.value!==t.id&&(i.openTab(t.to,!1),me(t.id))}function Et(t){return["router-tab__item",{"is-active":i.activeId.value===t.id,"is-closable":be(t),"is-dragging":R.dragging&&R.dragTab?.id===t.id,"is-drag-over":R.dropIndex===u(t.id)},t.tabClass]}function Kt(t){const o=i.getRouteKey(t),s=i.tabs.find(m=>m.id===o);return s?s.alive:!1}function Bt(t){const o=i.getRouteKey(t);return!!i.tabs.find(m=>m.id===o)}function Pt(t,o,s){e.sortable&&(R.dragging=!0,R.dragIndex=o,R.dragTab=t,s.dataTransfer&&(s.dataTransfer.effectAllowed="move",s.dataTransfer.setData("text/plain",t.id)),a("tab-sort",{tab:t,index:o}))}function $t(t,o){!e.sortable||!R.dragging||(o.preventDefault(),o.dataTransfer&&(o.dataTransfer.dropEffect="move"))}function St(t){!e.sortable||!R.dragging||(R.dropIndex=t)}function At(){!e.sortable||R.dragging}function It(t,o){if(!(!e.sortable||!R.dragging)){if(o.preventDefault(),R.dragIndex!==-1&&R.dragIndex!==t){const s=i.tabs.splice(R.dragIndex,1)[0];i.tabs.splice(t,0,s),a("tab-sorted",{tab:s,fromIndex:R.dragIndex,toIndex:t})}Se()}}function Se(){R.dragging=!1,R.dragIndex=-1,R.dropIndex=-1,R.dragTab=null}n.onMounted(()=>{document.addEventListener("keydown",K)}),n.onBeforeUnmount(()=>{document.removeEventListener("keydown",K),r.appContext.config.globalProperties.$tabs=null,$.forEach(t=>{t.forEach(o=>{try{o()}catch(s){console.error("[RouterTab] Error during cleanup:",s)}})}),$.clear(),S.clear()}),n.watch(()=>e.keepAlive,t=>{i.options.keepAlive=t}),n.watch(()=>i.activeId.value,t=>{t&&me(t),K()}),n.watch(()=>i.tabs.length,()=>{const t=new Set(i.tabs.map(s=>s.id));Array.from(S.keys()).forEach(s=>{t.has(s)||(console.log(`[RouterTab] Cleaning up stale component instance: ${s}`),D(s))})}),n.watch(()=>e.contextmenu,t=>{t||K()}),n.watch(()=>F.value.length,t=>{C.visible&&t===0&&K()},{flush:"post"}),n.watch(F,t=>{if(!C.visible)return;L.value=new Array(t.length).fill(null);const o=ee(-1,1,t);Y(o)},{flush:"post"}),n.watch(()=>C.visible,t=>{t||(A.value=-1,L.value=[])});const pe=i.includeKeys;return{controller:i,tabs:i.tabs,includeKeys:pe,persistenceHydrating:M,componentCache:H,componentCacheTrigger:fe,cacheCurrentComponent:ht,tabTransitionProps:se,pageTransitionProps:ce,buildTabClass:Et,activate:Rt,close:wt,context:C,menuItems:F,handleMenuAction:Pe,showContextMenu:ut,hideContextMenu:K,getTabTitle:de,isClosable:be,isTabCached:Kt,isTabReady:Bt,hasCustomSlot:g,hasStartSlot:w,hasEndSlot:l,onDragStart:Pt,onDragOver:$t,onDragEnter:St,onDragLeave:At,onDrop:It,onDragEnd:Se,setupComponentWatching:x,cleanupComponentWatching:D,handleComponentRef:_,getReactiveTabTitle:gt,getComponentCacheKey:vt,createNamedComponent:$e,ensureNamedComponent:yt,getNamedComponent:Tt,shouldRenderRoute:kt,triggerTabUpdate:v,menuRef:Z,highlightedIndex:A,setMenuItemRef:bt,onMenuKeydown:pt,highlightMenuIndex:Y,scrollContainer:U,setTabRef:Ct,scrollTabIntoView:me}}}),ze=(e,a)=>{const r=e.__vccOpts||e;for(const[c,i]of a)r[c]=i;return r},Fe={class:"router-tab"},Ye={class:"router-tab__header"},He={class:"router-tab__scroll",ref:"scrollContainer"},We=["data-title","draggable","onClick","onAuxclick","onContextmenu","onDragstart","onDragover","onDragenter","onDrop"],Je=["title"],qe=["onClick"],Ge={class:"router-tab__container"},Xe={key:1,class:"router-tab__hydrating","aria-hidden":"true"},Qe=["aria-disabled","disabled","tabindex","onMouseenter","onClick"];function Ze(e,a,r,c,i,g){const w=n.resolveComponent("RouterView");return n.openBlock(),n.createElementBlock("div",Fe,[n.createElementVNode("header",Ye,[n.createElementVNode("div",{class:n.normalizeClass(["router-tab__slot-start",{"has-content":e.hasStartSlot}])},[n.renderSlot(e.$slots,"start")],2),n.createElementVNode("div",He,[n.createVNode(n.TransitionGroup,n.mergeProps({tag:"ul",class:"router-tab__nav"},e.tabTransitionProps),{default:n.withCtx(()=>[(n.openBlock(!0),n.createElementBlock(n.Fragment,null,n.renderList(e.tabs,(l,y)=>(n.openBlock(),n.createElementBlock("li",{key:l.id,class:n.normalizeClass(e.buildTabClass(l)),"data-title":e.getTabTitle(l),draggable:e.sortable,ref_for:!0,ref:h=>e.setTabRef(l.id,h),onClick:h=>e.activate(l),onAuxclick:n.withModifiers(h=>e.close(l),["middle","prevent"]),onContextmenu:n.withModifiers(h=>e.showContextMenu(l,h),["prevent"]),onDragstart:h=>e.onDragStart(l,y,h),onDragover:h=>e.onDragOver(y,h),onDragenter:h=>e.onDragEnter(y),onDragleave:a[0]||(a[0]=(...h)=>e.onDragLeave&&e.onDragLeave(...h)),onDrop:h=>e.onDrop(y,h),onDragend:a[1]||(a[1]=(...h)=>e.onDragEnd&&e.onDragEnd(...h))},[l.icon?(n.openBlock(),n.createElementBlock("i",{key:0,class:n.normalizeClass(["router-tab__item-icon",l.icon])},null,2)):n.createCommentVNode("",!0),n.createElementVNode("span",{class:"router-tab__item-title",title:e.getReactiveTabTitle(l)},n.toDisplayString(e.getReactiveTabTitle(l)),9,Je),e.isClosable(l)?(n.openBlock(),n.createElementBlock("a",{key:1,class:"router-tab__item-close",onClick:n.withModifiers(h=>e.close(l),["stop"])},null,8,qe)):n.createCommentVNode("",!0)],42,We))),128))]),_:1},16)],512),n.createElementVNode("div",{class:n.normalizeClass(["router-tab__slot-end",{"has-content":e.hasEndSlot}])},[n.renderSlot(e.$slots,"end")],2)]),n.createElementVNode("div",Ge,[e.persistenceHydrating?(n.openBlock(),n.createElementBlock("div",Xe)):(n.openBlock(),n.createBlock(w,{key:0},{default:n.withCtx(({Component:l,route:y})=>[e.hasCustomSlot?n.renderSlot(e.$slots,"default",n.normalizeProps(n.mergeProps({key:0},{Component:l,route:y,controller:e.controller,pageRef:h=>e.handleComponentRef(h,e.controller.getRouteKey(y))}))):(n.openBlock(),n.createElementBlock(n.Fragment,{key:1},[e.controller.options.keepAlive?(n.openBlock(),n.createBlock(n.KeepAlive,{key:0,include:e.includeKeys},[l?(n.openBlock(),n.createBlock(n.resolveDynamicComponent(e.getNamedComponent(l,e.getComponentCacheKey(y))),{key:e.getComponentCacheKey(y),ref:h=>e.handleComponentRef(h,e.controller.getRouteKey(y)),class:"router-tab-page"})):n.createCommentVNode("",!0)],1032,["include"])):(n.openBlock(),n.createBlock(n.Transition,n.mergeProps({key:1},e.pageTransitionProps,{appear:""}),{default:n.withCtx(()=>[l?(n.openBlock(),n.createBlock(n.resolveDynamicComponent(l),{key:e.controller.getRouteKey(y),ref:h=>e.handleComponentRef(h,e.controller.getRouteKey(y)),class:"router-tab-page"})):n.createCommentVNode("",!0)]),_:2},1040))],64))]),_:3}))]),n.withDirectives(n.createElementVNode("div",{ref:"menuRef",class:"router-tab__contextmenu",role:"menu",onKeydown:a[2]||(a[2]=(...l)=>e.onMenuKeydown&&e.onMenuKeydown(...l)),style:n.normalizeStyle({left:e.context.position.x+"px",top:e.context.position.y+"px"})},[(n.openBlock(!0),n.createElementBlock(n.Fragment,null,n.renderList(e.menuItems,(l,y)=>(n.openBlock(),n.createElementBlock("a",{key:l.id,role:"menuitem",class:n.normalizeClass(["router-tab__contextmenu-item",{"is-focused":y===e.highlightedIndex}]),"aria-disabled":l.disabled,disabled:l.disabled,tabindex:l.disabled?-1:y===e.highlightedIndex?0:-1,ref_for:!0,ref:h=>e.setMenuItemRef(h,y),onMouseenter:h=>!l.disabled&&e.highlightMenuIndex(y),onClick:h=>e.handleMenuAction(l)},n.toDisplayString(l.label),43,Qe))),128))],36),[[n.vShow,e.context.visible&&e.context.target]])])}const ie=ze(Ue,[["render",Ze]]),et={class:"router-tabs","aria-hidden":"true"},G=n.defineComponent({name:"RouterTabs",__name:"RouterTabs",props:{cookieKey:{},expiresInDays:{},path:{},domain:{},secure:{type:Boolean},sameSite:{},serialize:{type:Function},deserialize:{type:Function},fallbackRoute:{}},setup(e){return ae(e),(r,c)=>(n.openBlock(),n.createElementBlock("span",et))}}),ve="tab-theme-style",we="tab-theme-primary-color",tt="system",Ce="(prefers-color-scheme: dark)";let j=null;const P={primary:"#034960",background:"#ffffff",text:"#1e293b",border:"#e2e8f0",activeBackground:"#034960",activeText:"#ffffff",activeBorder:"#034960",headerBackground:"#ffffff",buttonBackground:"#f8fafc",buttonColor:"#034960",activeButtonBackground:"#034960",activeButtonColor:"#ffffff",iconColor:"#475569"},nt={primary:"#38bdf8",background:"#0f172a",text:"#f1f5f9",border:"#334155",activeBackground:"#1e293b",activeText:"#38bdf8",activeBorder:"#38bdf8",headerBackground:"#0c4a6e",buttonBackground:"#1e293b",buttonColor:"#f1f5f9",activeButtonBackground:"#38bdf8",activeButtonColor:"#0f172a",iconColor:"#cbd5e1"};function ot(e){if(typeof window>"u")return null;const a=window.localStorage.getItem(e);if(!a)return null;try{const r=JSON.parse(a);return r&&typeof r=="object"?r:null}catch{return null}}function le(e){typeof document>"u"||(document.documentElement.style.setProperty("--router-tab-primary",e.primary??P.primary),document.documentElement.style.setProperty("--router-tab-header-bg",e.headerBackground??P.headerBackground),document.documentElement.style.setProperty("--router-tab-background",e.background??P.background),document.documentElement.style.setProperty("--router-tab-active-background",e.activeBackground??P.activeBackground),document.documentElement.style.setProperty("--router-tab-text",e.text??P.text),document.documentElement.style.setProperty("--router-tab-active-text",e.activeText??P.activeText),document.documentElement.style.setProperty("--router-tab-border",e.border??P.border),document.documentElement.style.setProperty("--router-tab-active-border",e.activeBorder??P.activeBorder),document.documentElement.style.setProperty("--router-tab-button-color",e.buttonColor??P.buttonColor),document.documentElement.style.setProperty("--router-tab-active-button-color",e.activeButtonColor??P.activeButtonColor),document.documentElement.style.setProperty("--router-tab-button-background",e.buttonBackground??P.buttonBackground),document.documentElement.style.setProperty("--router-tab-active-button-background",e.activeButtonBackground??P.activeButtonBackground),document.documentElement.style.setProperty("--router-tab-icon-color",e.iconColor??P.iconColor))}function Re(e){if(typeof document>"u")return;const a=document.documentElement,r=window.matchMedia(Ce),c=()=>{a.dataset.theme=r.matches?"dark":"light"};j&&(r.removeEventListener("change",j),j=null),e==="system"?(c(),j=()=>c(),r.addEventListener("change",j)):a.dataset.theme=e}function Ee(e={}){if(typeof window>"u")return;const{styleKey:a=ve,primaryKey:r=we,defaultStyle:c=tt,defaultPrimary:i}=e,g=window.localStorage.getItem(a)??c;Re(g);const l=g==="dark"||g==="system"&&window.matchMedia(Ce).matches?{...nt}:{...P};i&&(l.primary=i);const y=ot(r);le(y?{...l,...y}:l)}function rt(e,a){if(typeof window>"u")return;const r=a?.styleKey??ve;window.localStorage.setItem(r,e),Re(e)}function at(e,a){if(typeof window>"u")return;const r=a?.primaryKey??we;window.localStorage.setItem(r,JSON.stringify(e)),le(e)}function X(e,a){if(n.isRef(e)){const c=!n.isReadonly(e);return{value:e,update:c?i=>{e.value=i}:()=>{}}}if(typeof e=="function"){const c=e;return{value:n.computed(c),update:()=>{}}}const r=n.ref(e===void 0?a:e);return{value:r,update:c=>{r.value=c}}}function Q(e={}){const a=X(e.title,"Untitled"),r=X(e.icon,""),c=X(e.closable,!0),i=X(e.meta,{});return{routeTabTitle:a.value,routeTabIcon:r.value,routeTabClosable:c.value,routeTabMeta:i.value,updateTitle:a.update,updateIcon:r.update,updateClosable:c.update,updateMeta:i.update}}function it(e,a="Page"){return Q({title:n.computed(()=>e.value?"Loading...":a),icon:n.computed(()=>e.value?"mdi-loading mdi-spin":"mdi-page"),closable:n.computed(()=>!e.value)})}function lt(e,a="Page",r="mdi-page"){return Q({title:n.computed(()=>e.value>0?`${a} (${e.value})`:a),icon:n.computed(()=>e.value>0?"mdi-bell-badge":r)})}function st(e,a="Page"){const r={normal:{suffix:"",icon:"mdi-page"},loading:{suffix:" - Loading",icon:"mdi-loading mdi-spin"},error:{suffix:" - Error",icon:"mdi-alert"},success:{suffix:" - Success",icon:"mdi-check-circle"}};return Q({title:n.computed(()=>a+r[e.value].suffix),icon:n.computed(()=>r[e.value].icon),closable:n.computed(()=>e.value!=="loading")})}let Ke=!1;const ct={install(e,a){if(Ke)return;Ke=!0;const{initTheme:r=!0,themeOptions:c,componentName:i=ie.name||"RouterTab",tabsComponentName:g=G.name||"RouterTabs"}=a??{};r&&Ee(c??{}),e.component(i,ie),e.component(g,G),g.toLowerCase()!=="router-tabs"&&e.component("router-tabs",G),Object.defineProperty(e.config.globalProperties,"$tabs",{configurable:!0,enumerable:!1,get(){return e._context.provides[O]},set(w){w&&e.provide(O,w)}})}};E.RouterTab=ie,E.RouterTabs=G,E.default=ct,E.initRouterTabsTheme=Ee,E.routerTabsKey=O,E.setRouterTabsPrimary=at,E.setRouterTabsTheme=rt,E.useLoadingTab=it,E.useNotificationTab=lt,E.useReactiveTab=Q,E.useRouterTabs=re,E.useRouterTabsPersistence=ae,E.useStatusTab=st,Object.defineProperties(E,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
1
+ (function(E,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("vue"),require("vue-router")):typeof define=="function"&&define.amd?define(["exports","vue","vue-router"],n):(E=typeof globalThis<"u"?globalThis:E||self,n(E["vue3-router-tab"]={},E.Vue,E.VueRouter))})(this,(function(E,n,xe){"use strict";function De(e={}){return{initialTabs:e.initialTabs??[],keepAlive:e.keepAlive??!0,maxAlive:e.maxAlive??0,keepLastTab:e.keepLastTab??!0,appendPosition:e.appendPosition??"last",defaultRoute:e.defaultRoute??"/"}}function x(e,a){const r=e.resolve(a);if(!r||!r.matched.length)throw new Error(`[RouterTabs] Unable to resolve route: ${String(a)}`);return r}const Me={path:e=>e.path,fullpath:e=>e.fullPath,fullname:e=>e.fullPath,full:e=>e.fullPath,name:e=>e.name?String(e.name):e.fullPath};function N(e){const a=e.meta?.key;if(typeof a=="function"){const r=a(e);if(typeof r=="string"&&r.length)return r}else if(typeof a=="string"&&a.length){const r=Me[a.toLowerCase()];return r?r(e):a}return e.fullPath}function oe(e,a){const r=e.meta?.keepAlive;return typeof r=="boolean"?r:a}function re(e,a){const r=e.meta?.reuse;return typeof r=="boolean"?r:a}function ye(e){const a=e.meta??{},r={};return"title"in a&&(r.title=a.title),"tips"in a&&(r.tips=a.tips),"icon"in a&&(r.icon=a.icon),"closable"in a&&(r.closable=a.closable),"tabClass"in a&&(r.tabClass=a.tabClass),"target"in a&&(r.target=a.target),"href"in a&&(r.href=a.href),r}function J(e,a,r){const s=ye(e);return{id:N(e),to:e.fullPath,fullPath:e.fullPath,matched:e,alive:oe(e,r),reusable:re(e,!1),closable:s.closable??!0,renderKey:typeof a.renderKey=="number"?a.renderKey:0,...s,...a}}function ae(e,a,r,s){if(!e.find(p=>p.id===a.id)){if(r==="next"&&s){const p=e.findIndex(w=>w.id===s);if(p!==-1){e.splice(p+1,0,a);return}}e.push(a)}}function q(e,a,r,s){if(!a||a<=0)return;const i=e.filter(p=>p.alive);for(;i.length>a;){const p=i.shift();if(!p||p.id===r)continue;const w=e.findIndex(l=>l.id===p.id);if(w>-1){const l=e[w],y=`${l.id}::${l.renderKey??0}`;s.delete(y),l.alive=!1}}}function Le(e){return{to:e.to,title:e.title,tips:e.tips,icon:e.icon,tabClass:e.tabClass,closable:e.closable,renderKey:e.renderKey}}function Ve(e){const a={};return"title"in e&&(a.title=e.title),"tips"in e&&(a.tips=e.tips),"icon"in e&&(a.icon=e.icon),"tabClass"in e&&(a.tabClass=e.tabClass),"closable"in e&&(a.closable=e.closable),"renderKey"in e&&typeof e.renderKey=="number"&&(a.renderKey=e.renderKey),a}function Ne(e,a={}){const r=De(a),s=n.reactive([]),i=n.ref(null),p=n.shallowRef(),w=n.ref(null),l=n.reactive(new Set),y=n.computed(()=>Array.from(l));let g=!1;function v(u){const b=typeof u.matched=="object"?u:x(e,u);return{key:N(b),fullPath:b.fullPath,alive:oe(b,r.keepAlive),reusable:re(b,!1),matched:b}}function S(u){const b=N(u);let f=s.find(k=>k.id===b);const T=oe(u,r.keepAlive);if(f){f.fullPath=u.fullPath,f.to=u.fullPath,f.matched=u,f.reusable=re(u,f.reusable),typeof f.renderKey!="number"&&(f.renderKey=0);const k=`${b}::${f.renderKey}`;return T?l.has(k)?f.alive||(f.alive=!0):(l.add(k),f.alive=!0):f.alive&&(l.delete(k),f.alive=!1),Object.assign(f,ye(u)),f}if(f=J(u,{},r.keepAlive),f.alive){const k=`${b}::${f.renderKey??0}`;l.add(k)}return ae(s,f,r.appendPosition,i.value),q(s,r.maxAlive,i.value,l),f}async function $(u,b=!1,f="sameTab"){const T=x(e,u),k=N(T),K=i.value===k;f==="sameTab"&&(f=K),f&&await L(k,!0),await e[b?"replace":"push"](T),K&&await U()}function D(u){const b=s.findIndex(B=>B.id===u);if(b===-1)return r.defaultRoute;const f=s[b+1],T=s[b-1],k=s.find(B=>B.id!==u),K=f||T||k;return K?K.to:r.defaultRoute}async function M(u=i.value,b={}){if(!u)return;if(!b.force&&r.keepLastTab&&s.length===1)throw new Error("[RouterTabs] Unable to close the final tab when keepLastTab is true.");const T=i.value===u&&b.redirect!==null,k=T?b.redirect??D(u):null;await _(u,{force:b.force}),b.redirect!==null&&T&&k&&await e.replace(k)}async function _(u,b={}){const f=s.findIndex(K=>K.id===u);if(f===-1)return;const T=s[f],k=`${u}::${T.renderKey??0}`;l.delete(k),T.alive=!1,s.splice(f,1),w.value===u&&(w.value=null),i.value===u&&(i.value=null,p.value=void 0)}async function L(u=i.value??void 0,b=!1){if(!u)return;const f=s.find(B=>B.id===u);if(!f)return;const T=r.keepAlive&&f.alive,k=`${u}::${f.renderKey??0}`;T&&(l.delete(k),f.alive=!1,await n.nextTick()),f.renderKey=(f.renderKey??0)+1;const K=`${u}::${f.renderKey}`;T&&(l.add(K),f.alive=!0),w.value=u,await n.nextTick(),b||await n.nextTick(),w.value=null}async function ue(u=!1){for(const b of s)await L(b.id,u)}function de(u,b){const f=s.find(k=>k.id===u);if(!f)return;const T=`${u}::${f.renderKey??0}`;b?(l.add(T),f.alive=!0,q(s,r.maxAlive,i.value,l)):(l.delete(T),f.alive=!1)}function C(u){const b=s.find(T=>T.id===u);if(!b)return;const f=`${u}::${b.renderKey??0}`;l.delete(f),b.alive=!1,b.renderKey=(b.renderKey??0)+1}function ee(){l.clear(),s.forEach(u=>{u.alive=!1})}function V(){return y.value.slice()}async function I(u=r.defaultRoute){s.splice(0,s.length),i.value=null,p.value=void 0;for(const b of r.initialTabs){const f=x(e,b.to),T=J(f,b,r.keepAlive);s.push(T)}await e.replace(u)}async function U(){const u=i.value;u&&await L(u,!0)}function z(u){return typeof u.matched=="object"?N(u):N(x(e,u))}function R(){const u=s.find(b=>b.id===i.value);return{tabs:s.map(Le),active:u?u.to:null}}async function fe(u){g=!0,s.splice(0,s.length),i.value=null,p.value=void 0;const b=u?.tabs??[];for(const T of b)try{const k=x(e,T.to),K=Ve(T),B=J(k,K,r.keepAlive);ae(s,B,"last",null)}catch(k){console.warn("[RouterTabs] Failed to restore tab",T,k)}g=!1;const f=u?.active??b[b.length-1]?.to??r.defaultRoute;if(f)try{const T=x(e,f),k=e.currentRoute.value;if(T.fullPath===k.fullPath){const K=S(k);i.value=K.id,p.value=K,q(s,r.maxAlive,i.value,l);return}await e.replace(T)}catch(T){console.warn("[RouterTabs] Failed to navigate to restored route",f,T)}}return n.watch(()=>e.currentRoute.value,u=>{if(g)return;const b=S(u);i.value=b.id,p.value=b,q(s,r.maxAlive,i.value,l)},{immediate:!0}),r.initialTabs.length&&r.initialTabs.forEach(u=>{const b=x(e,u.to),f=J(b,u,r.keepAlive);ae(s,f,"last",null)}),{options:r,tabs:s,activeId:i,current:p,includeKeys:y,refreshingKey:w,openTab:$,closeTab:M,removeTab:_,refreshTab:L,refreshAll:ue,setTabAlive:de,evictCache:C,clearCache:ee,getCacheKeys:V,reset:I,reload:U,getRouteKey:z,matchRoute:v,snapshot:R,hydrate:fe,ensureTab:S}}function Te(e){return e?typeof e=="string"?{name:e}:e:{}}const O=Symbol("RouterTabsContext"),G="router-tabs:snapshot";function ie(e={}){const{optional:a=!1}=e,r=n.inject(O,null);if(r)return r;const s=n.inject("$tabs",null);if(s)return s;const p=n.getCurrentInstance()?.appContext.config.globalProperties.$tabs;if(p)return p;if(!a)throw new Error("[RouterTabs] useRouterTabs must be used within <router-tab>.");return null}const Oe=864e5;function je(e){if(typeof document>"u")return null;const a=`${encodeURIComponent(e)}=`,r=document.cookie?document.cookie.split("; "):[];for(const s of r)if(s.startsWith(a))return decodeURIComponent(s.slice(a.length));return null}function ke(e,a,r){if(typeof document>"u")return;const{expiresInDays:s=7,path:i="/",domain:p,secure:w,sameSite:l="lax"}=r,y=[`${encodeURIComponent(e)}=${encodeURIComponent(a)}`];if(s!==1/0){const g=new Date(Date.now()+s*Oe).toUTCString();y.push(`Expires=${g}`)}i&&y.push(`Path=${i}`),p&&y.push(`Domain=${p}`),w&&y.push("Secure"),l&&y.push(`SameSite=${l.charAt(0).toUpperCase()}${l.slice(1)}`),document.cookie=y.join("; ")}function ve(e,a){if(typeof document>"u")return;const{path:r="/",domain:s}=a,i=[`${encodeURIComponent(e)}=`];i.push("Expires=Thu, 01 Jan 1970 00:00:01 GMT"),r&&i.push(`Path=${r}`),s&&i.push(`Domain=${s}`),document.cookie=i.join("; ")}const _e=e=>JSON.stringify(e??null),Ue=e=>{if(!e)return null;try{return JSON.parse(e)}catch{return null}};function le(e={}){const{cookieKey:a=G,serialize:r=_e,deserialize:s=Ue}=e,i=ie({optional:!0}),p=n.ref(!0),w=(l,y="hook")=>{const g=async()=>{p.value=!0;try{const v=s(je(a));if(v&&v.tabs?.length){if(await l.hydrate(v),v.active){await n.nextTick();const $=l.tabs.find(D=>D.to===v.active);$&&(l.activeId.value=$.id,l.current.value=$)}}else if(Object.prototype.hasOwnProperty.call(e,"fallbackRoute")){const $=e.fallbackRoute??l.options.defaultRoute;await l.reset($)}const S=l.snapshot();S.tabs.length?ke(a,r(S),e):ve(a,e)}finally{p.value=!1}};y==="immediate"?g():n.onBeforeMount(()=>{g()}),n.watch(()=>({tabs:l.tabs.map(v=>({to:v.to,title:v.title,tips:v.tips,icon:v.icon,tabClass:v.tabClass,closable:v.closable,renderKey:v.renderKey})),active:l.activeId.value}),()=>{if(p.value)return;const v=l.snapshot();v.tabs.length?ke(a,r(v),e):ve(a,e)},{deep:!0})};return i?w(i):n.onMounted(()=>{const l=ie({optional:!0});l&&w(l,"immediate")}),{hydrating:p}}const ze=n.defineComponent({name:"RouterTab",components:{RouterView:xe.RouterView},props:{tabs:{type:Array,default:()=>[]},keepAlive:{type:Boolean,default:!0},maxAlive:{type:Number,default:0},keepLastTab:{type:Boolean,default:!0},append:{type:String,default:"last"},defaultPage:{type:[String,Object],default:"/"},tabTransition:{type:[String,Object],default:"router-tab-zoom"},pageTransition:{type:[String,Object],default:()=>({name:"router-tab-swap",mode:"out-in"})},contextmenu:{type:[Boolean,Array],default:!0},cookieKey:{type:String,default:G},persistence:{type:Object,default:null},sortable:{type:Boolean,default:!0}},emits:["tab-sort","tab-sorted"],setup(e,{emit:a}){const r=n.getCurrentInstance();if(!r)throw new Error("[RouterTab] component must be used within a Vue application context.");const s=r.appContext.app.config.globalProperties.$router;if(!s)throw new Error("[RouterTab] Vue Router is required. Make sure to call app.use(router) before RouterTab.");const i=Ne(s,{initialTabs:e.tabs,keepAlive:e.keepAlive,maxAlive:e.maxAlive,keepLastTab:e.keepLastTab,appendPosition:e.append,defaultRoute:e.defaultPage});n.provide(O,i),r.appContext.config.globalProperties.$tabs=i;const p=n.computed(()=>!!r?.slots?.default),w=n.computed(()=>!!r?.slots?.start),l=n.computed(()=>!!r?.slots?.end),y=n.ref(0),g=n.computed(()=>{y.value;const t={};return i.tabs.forEach(o=>{const c=typeof o.title=="string"?o.title:String(o.title||be(o));t[o.id]=c}),t});function v(){y.value++}const S=new Map,$=new Map;function D(t,o){if(!(!o||S.has(t)))try{S.set(t,o);const c=i.tabs.find(h=>i.getRouteKey(h.to)===t);if(!c){console.warn(`[RouterTab] Cannot setup watching: tab not found for ${t}`);return}const m=[];if(o.routeTabTitle!==void 0)try{const h=n.watch(()=>{const d=o.routeTabTitle;return d&&typeof d=="object"&&"value"in d?d.value:d},d=>{if(d!=null){const A=String(d);c.title=A,v()}},{immediate:!0});m.push(h)}catch(h){console.error(`[RouterTab] Error watching routeTabTitle for ${t}:`,h)}if(o.routeTabIcon!==void 0)try{const h=n.watch(()=>{const d=o.routeTabIcon;return d&&typeof d=="object"&&"value"in d?d.value:d},d=>{d!=null&&(c.icon=String(d),v())},{immediate:!0});m.push(h)}catch(h){console.error(`[RouterTab] Error watching routeTabIcon for ${t}:`,h)}if(o.routeTabClosable!==void 0)try{const h=n.watch(()=>{const d=o.routeTabClosable;return d&&typeof d=="object"&&"value"in d?d.value:d},d=>{d!=null&&(c.closable=!!d,v())},{immediate:!0});m.push(h)}catch(h){console.error(`[RouterTab] Error watching routeTabClosable for ${t}:`,h)}if(o.routeTabMeta!==void 0)try{const h=n.watch(()=>{const d=o.routeTabMeta;return d&&typeof d=="object"&&"value"in d?d.value:d},d=>{d&&typeof d=="object"&&(Object.assign(c,d),v())},{immediate:!0,deep:!0});m.push(h)}catch(h){console.error(`[RouterTab] Error watching routeTabMeta for ${t}:`,h)}$.set(t,m)}catch(c){console.error(`[RouterTab] Error in setupComponentWatching for ${t}:`,c),M(t)}}function M(t){try{const o=$.get(t);o&&(o.forEach(c=>{try{c()}catch(m){console.error(`[RouterTab] Error cleaning up watcher for ${t}:`,m)}}),$.delete(t)),S.delete(t)}catch(o){console.error(`[RouterTab] Error in cleanupComponentWatching for ${t}:`,o)}}function _(t,o){try{t?t.routeTabTitle!==void 0||t.routeTabIcon!==void 0||t.routeTabClosable!==void 0?D(o,t):t.$&&(t.$.routeTabTitle!==void 0||t.$.routeTabIcon!==void 0||t.$.routeTabClosable!==void 0)&&D(o,t.$):t===null&&M(o)}catch(c){console.error(`[RouterTab] Error handling component ref for ${o}:`,c),M(o)}}n.onErrorCaptured((t,o,c)=>(console.error("[RouterTab] Error captured from component:",t,c),!1));let L=n.ref(!1);if(e.cookieKey!==null||e.persistence){const t={...e.persistence??{}};e.cookieKey!==null?t.cookieKey=e.cookieKey||G:t.cookieKey||(t.cookieKey=G),L=le(t).hydrating}const ue=n.computed(()=>Te(e.tabTransition)),de=n.computed(()=>Te(e.pageTransition)),C=n.reactive({visible:!1,target:null,position:{x:0,y:0}}),ee=n.ref(null),V=n.ref([]),I=n.ref(-1),U=n.ref(null),z=new Map,R=n.reactive({dragging:!1,dragIndex:-1,dropIndex:-1,dragTab:null}),fe=["refresh","refreshAll","close","closeLefts","closeRights","closeOthers"];function u(t){return i.tabs.findIndex(o=>o.id===t)}function b(t){const o=u(t.id);return o>0?i.tabs.slice(0,o):[]}function f(t){const o=u(t.id);return o>-1?i.tabs.slice(o+1):[]}function T(t){return i.tabs.filter(o=>o.id!==t.id)}async function k(t,o){const c=t.filter(m=>m.closable!==!1);if(c.length){for(const m of c)i.activeId.value===m.id?await i.closeTab(m.id,{redirect:o.to,force:!0}):await i.removeTab(m.id,{force:!0});i.activeId.value!==o.id&&await i.openTab(o.to,!0,!1)}}const K={refresh:{label:"Refresh",handler:async({target:t})=>{await i.refreshTab(t.id,!0)}},refreshAll:{label:"Refresh All",handler:async()=>{await i.refreshAll(!0)}},close:{label:"Close",handler:async({target:t})=>{await i.closeTab(t.id)},enable:({target:t})=>pe(t)},closeLefts:{label:"Close to the Left",handler:async({target:t})=>{await k(b(t),t)},enable:({target:t})=>b(t).some(o=>o.closable!==!1)},closeRights:{label:"Close to the Right",handler:async({target:t})=>{await k(f(t),t)},enable:({target:t})=>f(t).some(o=>o.closable!==!1)},closeOthers:{label:"Close Others",handler:async({target:t})=>{await k(T(t),t)},enable:({target:t})=>T(t).some(o=>o.closable!==!1)}};function B(){C.visible=!1,C.target=null,I.value=-1,V.value=[]}function dt(t,o){e.contextmenu&&(C.target=t,C.position.x=o.clientX,C.position.y=o.clientY,n.nextTick(()=>{C.visible=!0,document.addEventListener("click",B,{once:!0}),n.nextTick(()=>{bt()})}))}function ft(t,o){const c=typeof t=="string"?{id:t}:t,m=K[c.id],h=c.label??m?.label??String(c.id),d=c.visible??m?.visible??!0;if(!(typeof d=="function"?d(o):d!==!1))return null;const W=c.enable??m?.enable??!0,Ie=typeof W=="function"?W(o):W!==!1,ne=c.handler??m?.handler;if(!ne)return null;const he=async()=>{await Promise.resolve(ne(o))};return{id:String(c.id),label:h,disabled:!Ie,action:he}}const F=n.computed(()=>{if(!C.visible||!C.target||e.contextmenu===!1)return[];const t=Array.isArray(e.contextmenu)?e.contextmenu:fe,o={target:C.target,controller:i};return t.map(c=>ft(c,o)).filter(c=>!!c)});function bt(){const t=ee.value;if(!t)return;const o=8,{innerWidth:c,innerHeight:m}=window,h=t.getBoundingClientRect();let d=C.position.x,A=C.position.y;h.right>c-o&&(d=Math.max(o,c-h.width-o)),h.bottom>m-o&&(A=Math.max(o,m-h.height-o)),(d!==C.position.x||A!==C.position.y)&&(C.position.x=d,C.position.y=A)}function mt(t,o){V.value[o]=t??null}function pt(t){if(t<0)return;V.value[t]?.focus({preventScroll:!0})}function te(t,o,c=F.value){if(!c.length)return-1;const m=c.length;let h=t;for(let d=0;d<m;d++)if(h=(h+o+m)%m,!c[h].disabled)return h;return-1}function Y(t){I.value=t,!(t<0)&&n.nextTick(()=>pt(t))}function Pe(t){const o=te(I.value,t);o!==-1&&Y(o)}function gt(t){if(!C.visible)return;const o=t.key,c=F.value;if(!c.length)return;if(o==="Tab"){B();return}if(["ArrowDown","ArrowUp","ArrowRight","ArrowLeft","Home","End","Enter"," ","Spacebar","Escape"].includes(o))switch(t.preventDefault(),o){case"ArrowDown":case"ArrowRight":Pe(1);break;case"ArrowUp":case"ArrowLeft":Pe(-1);break;case"Home":Y(te(-1,1));break;case"End":Y(te(c.length,-1));break;case"Enter":case" ":case"Spacebar":{const h=I.value;if(h>-1){const d=c[h];d.disabled||$e(d)}break}case"Escape":B();break}}async function $e(t){t.disabled||(B(),await t.action())}function be(t){return typeof t.title=="string"&&t.title.trim()?t.title:Array.isArray(t.title)&&t.title.length&&String(t.title[0]).trim()?String(t.title[0]):"Untitled"}function ht(t){return g.value[t.id]||be(t)}function Se(t,o){return n.defineComponent({name:o,setup(c,{attrs:m,slots:h}){const d=n.ref(),A=n.getCurrentInstance();if(A?.proxy){const W=A.proxy;Object.entries({routeTabTitle:()=>d.value?.routeTabTitle,routeTabIcon:()=>d.value?.routeTabIcon,routeTabClosable:()=>d.value?.routeTabClosable,routeTabMeta:()=>d.value?.routeTabMeta,$:()=>d.value}).forEach(([ne,he])=>{Object.defineProperty(W,ne,{get:he,configurable:!0})})}return()=>n.h(t,{...m,ref:d},h)}})}const H=new Map,me=n.ref(0);function yt(t,o,c){H.has(c)||(H.set(c,o),me.value++),t&&_(t,c)}function Tt(t,o){return t&&((!t.name||t.name!==o)&&(t.name=o),t)}function kt(t,o){if(!t)return t;const c=H.get(o);if(c)return c;const m=Se(t,o);return H.set(o,m),me.value++,m}function vt(t){const o=i.getRouteKey(t),c=s.currentRoute.value,m=i.getRouteKey(c);return o===m}function wt(t){const o=i.getRouteKey(t),c=i.tabs.find(d=>d.id===o);if(!c)return`${o}::0`;const m=c.renderKey??0;return`${o}::${m}`}function pe(t){return!(t.closable===!1||i.options.keepLastTab&&i.tabs.length<=1)}async function Ct(t){await i.closeTab(t.id)}function Rt(t,o){o?z.set(t,o):z.delete(t)}function ge(t){n.nextTick(()=>{const o=z.get(t),c=U.value;if(o&&c){const m=o.getBoundingClientRect(),h=c.getBoundingClientRect();(m.left<h.left||m.right>h.right)&&o.scrollIntoView({behavior:"smooth",block:"nearest",inline:"nearest"})}})}function Et(t){if(t.href&&typeof window<"u"){t.target&&t.target!=="_self"?window.open(t.href,t.target):window.location.assign(t.href);return}i.activeId.value!==t.id&&(i.openTab(t.to,!1),ge(t.id))}function Bt(t){return["router-tab__item",{"is-active":i.activeId.value===t.id,"is-closable":pe(t),"is-dragging":R.dragging&&R.dragTab?.id===t.id,"is-drag-over":R.dropIndex===u(t.id)},t.tabClass]}function Kt(t){const o=i.getRouteKey(t),c=i.tabs.find(m=>m.id===o);return c?c.alive:!1}function Pt(t){const o=i.getRouteKey(t);return!!i.tabs.find(m=>m.id===o)}function $t(t,o,c){e.sortable&&(R.dragging=!0,R.dragIndex=o,R.dragTab=t,c.dataTransfer&&(c.dataTransfer.effectAllowed="move",c.dataTransfer.setData("text/plain",t.id)),a("tab-sort",{tab:t,index:o}))}function St(t,o){!e.sortable||!R.dragging||(o.preventDefault(),o.dataTransfer&&(o.dataTransfer.dropEffect="move"))}function At(t){!e.sortable||!R.dragging||(R.dropIndex=t)}function It(){!e.sortable||R.dragging}function xt(t,o){if(!(!e.sortable||!R.dragging)){if(o.preventDefault(),R.dragIndex!==-1&&R.dragIndex!==t){const c=i.tabs.splice(R.dragIndex,1)[0];i.tabs.splice(t,0,c),a("tab-sorted",{tab:c,fromIndex:R.dragIndex,toIndex:t})}Ae()}}function Ae(){R.dragging=!1,R.dragIndex=-1,R.dropIndex=-1,R.dragTab=null}n.onMounted(()=>{document.addEventListener("keydown",B)}),n.onBeforeUnmount(()=>{document.removeEventListener("keydown",B),r.appContext.config.globalProperties.$tabs=null,$.forEach(t=>{t.forEach(o=>{try{o()}catch(c){console.error("[RouterTab] Error during cleanup:",c)}})}),$.clear(),S.clear()}),n.watch(()=>e.keepAlive,t=>{i.options.keepAlive=t}),n.watch(()=>i.activeId.value,t=>{t&&ge(t),B()}),n.watch(()=>i.tabs.length,()=>{const t=new Set(i.tabs.map(c=>c.id));Array.from(S.keys()).forEach(c=>{t.has(c)||M(c)})}),n.watch(()=>e.contextmenu,t=>{t||B()}),n.watch(()=>F.value.length,t=>{C.visible&&t===0&&B()},{flush:"post"}),n.watch(F,t=>{if(!C.visible)return;V.value=new Array(t.length).fill(null);const o=te(-1,1,t);Y(o)},{flush:"post"}),n.watch(()=>C.visible,t=>{t||(I.value=-1,V.value=[])});const Dt=i.includeKeys;return{controller:i,tabs:i.tabs,includeKeys:Dt,persistenceHydrating:L,componentCache:H,componentCacheTrigger:me,cacheCurrentComponent:yt,tabTransitionProps:ue,pageTransitionProps:de,buildTabClass:Bt,activate:Et,close:Ct,context:C,menuItems:F,handleMenuAction:$e,showContextMenu:dt,hideContextMenu:B,getTabTitle:be,isClosable:pe,isTabCached:Kt,isTabReady:Pt,hasCustomSlot:p,hasStartSlot:w,hasEndSlot:l,onDragStart:$t,onDragOver:St,onDragEnter:At,onDragLeave:It,onDrop:xt,onDragEnd:Ae,setupComponentWatching:D,cleanupComponentWatching:M,handleComponentRef:_,getReactiveTabTitle:ht,getComponentCacheKey:wt,createNamedComponent:Se,ensureNamedComponent:Tt,getNamedComponent:kt,shouldRenderRoute:vt,triggerTabUpdate:v,menuRef:ee,highlightedIndex:I,setMenuItemRef:mt,onMenuKeydown:gt,highlightMenuIndex:Y,scrollContainer:U,setTabRef:Rt,scrollTabIntoView:ge}}}),Fe=(e,a)=>{const r=e.__vccOpts||e;for(const[s,i]of a)r[s]=i;return r},Ye={class:"router-tab"},He={class:"router-tab__header"},We={class:"router-tab__scroll",ref:"scrollContainer"},Je=["data-title","draggable","onClick","onAuxclick","onContextmenu","onDragstart","onDragover","onDragenter","onDrop"],qe=["title"],Ge=["onClick"],Xe={class:"router-tab__container"},Qe={key:1,class:"router-tab__hydrating","aria-hidden":"true"},Ze=["aria-disabled","disabled","tabindex","onMouseenter","onClick"];function et(e,a,r,s,i,p){const w=n.resolveComponent("RouterView");return n.openBlock(),n.createElementBlock("div",Ye,[n.createElementVNode("header",He,[n.createElementVNode("div",{class:n.normalizeClass(["router-tab__slot-start",{"has-content":e.hasStartSlot}])},[n.renderSlot(e.$slots,"start")],2),n.createElementVNode("div",We,[n.createVNode(n.TransitionGroup,n.mergeProps({tag:"ul",class:"router-tab__nav"},e.tabTransitionProps),{default:n.withCtx(()=>[(n.openBlock(!0),n.createElementBlock(n.Fragment,null,n.renderList(e.tabs,(l,y)=>(n.openBlock(),n.createElementBlock("li",{key:l.id,class:n.normalizeClass(e.buildTabClass(l)),"data-title":e.getTabTitle(l),draggable:e.sortable,ref_for:!0,ref:g=>e.setTabRef(l.id,g),onClick:g=>e.activate(l),onAuxclick:n.withModifiers(g=>e.close(l),["middle","prevent"]),onContextmenu:n.withModifiers(g=>e.showContextMenu(l,g),["prevent"]),onDragstart:g=>e.onDragStart(l,y,g),onDragover:g=>e.onDragOver(y,g),onDragenter:g=>e.onDragEnter(y),onDragleave:a[0]||(a[0]=(...g)=>e.onDragLeave&&e.onDragLeave(...g)),onDrop:g=>e.onDrop(y,g),onDragend:a[1]||(a[1]=(...g)=>e.onDragEnd&&e.onDragEnd(...g))},[l.icon?(n.openBlock(),n.createElementBlock("i",{key:0,class:n.normalizeClass(["router-tab__item-icon",l.icon])},null,2)):n.createCommentVNode("",!0),n.createElementVNode("span",{class:"router-tab__item-title",title:e.getReactiveTabTitle(l)},n.toDisplayString(e.getReactiveTabTitle(l)),9,qe),e.isClosable(l)?(n.openBlock(),n.createElementBlock("a",{key:1,class:"router-tab__item-close",onClick:n.withModifiers(g=>e.close(l),["stop"])},null,8,Ge)):n.createCommentVNode("",!0)],42,Je))),128))]),_:1},16)],512),n.createElementVNode("div",{class:n.normalizeClass(["router-tab__slot-end",{"has-content":e.hasEndSlot}])},[n.renderSlot(e.$slots,"end")],2)]),n.createElementVNode("div",Xe,[e.persistenceHydrating?(n.openBlock(),n.createElementBlock("div",Qe)):(n.openBlock(),n.createBlock(w,{key:0},{default:n.withCtx(({Component:l,route:y})=>[e.hasCustomSlot?n.renderSlot(e.$slots,"default",n.normalizeProps(n.mergeProps({key:0},{Component:l,route:y,controller:e.controller,pageRef:g=>e.handleComponentRef(g,e.controller.getRouteKey(y))}))):(n.openBlock(),n.createElementBlock(n.Fragment,{key:1},[e.controller.options.keepAlive?(n.openBlock(),n.createBlock(n.KeepAlive,{key:0,include:e.includeKeys},[l?(n.openBlock(),n.createBlock(n.resolveDynamicComponent(e.getNamedComponent(l,e.getComponentCacheKey(y))),{key:e.getComponentCacheKey(y),ref:g=>e.handleComponentRef(g,e.controller.getRouteKey(y)),class:"router-tab-page"})):n.createCommentVNode("",!0)],1032,["include"])):(n.openBlock(),n.createBlock(n.Transition,n.mergeProps({key:1},e.pageTransitionProps,{appear:""}),{default:n.withCtx(()=>[l?(n.openBlock(),n.createBlock(n.resolveDynamicComponent(l),{key:e.controller.getRouteKey(y),ref:g=>e.handleComponentRef(g,e.controller.getRouteKey(y)),class:"router-tab-page"})):n.createCommentVNode("",!0)]),_:2},1040))],64))]),_:3}))]),n.withDirectives(n.createElementVNode("div",{ref:"menuRef",class:"router-tab__contextmenu",role:"menu",onKeydown:a[2]||(a[2]=(...l)=>e.onMenuKeydown&&e.onMenuKeydown(...l)),style:n.normalizeStyle({left:e.context.position.x+"px",top:e.context.position.y+"px"})},[(n.openBlock(!0),n.createElementBlock(n.Fragment,null,n.renderList(e.menuItems,(l,y)=>(n.openBlock(),n.createElementBlock("a",{key:l.id,role:"menuitem",class:n.normalizeClass(["router-tab__contextmenu-item",{"is-focused":y===e.highlightedIndex}]),"aria-disabled":l.disabled,disabled:l.disabled,tabindex:l.disabled?-1:y===e.highlightedIndex?0:-1,ref_for:!0,ref:g=>e.setMenuItemRef(g,y),onMouseenter:g=>!l.disabled&&e.highlightMenuIndex(y),onClick:g=>e.handleMenuAction(l)},n.toDisplayString(l.label),43,Ze))),128))],36),[[n.vShow,e.context.visible&&e.context.target]])])}const se=Fe(ze,[["render",et]]),tt={class:"router-tabs","aria-hidden":"true"},X=n.defineComponent({name:"RouterTabs",__name:"RouterTabs",props:{cookieKey:{},expiresInDays:{},path:{},domain:{},secure:{type:Boolean},sameSite:{},serialize:{type:Function},deserialize:{type:Function},fallbackRoute:{}},setup(e){return le(e),(r,s)=>(n.openBlock(),n.createElementBlock("span",tt))}}),we="tab-theme-style",Ce="tab-theme-primary-color",nt="system",Re="(prefers-color-scheme: dark)";let j=null;const P={primary:"#034960",background:"#ffffff",text:"#1e293b",border:"#e2e8f0",activeBackground:"#034960",activeText:"#ffffff",activeBorder:"#034960",headerBackground:"#ffffff",buttonBackground:"#f8fafc",buttonColor:"#034960",activeButtonBackground:"#034960",activeButtonColor:"#ffffff",iconColor:"#475569"},ot={primary:"#38bdf8",background:"#0f172a",text:"#f1f5f9",border:"#334155",activeBackground:"#1e293b",activeText:"#38bdf8",activeBorder:"#38bdf8",headerBackground:"#0c4a6e",buttonBackground:"#1e293b",buttonColor:"#f1f5f9",activeButtonBackground:"#38bdf8",activeButtonColor:"#0f172a",iconColor:"#cbd5e1"};function rt(e){if(typeof window>"u")return null;const a=window.localStorage.getItem(e);if(!a)return null;try{const r=JSON.parse(a);return r&&typeof r=="object"?r:null}catch{return null}}function ce(e){typeof document>"u"||(document.documentElement.style.setProperty("--router-tab-primary",e.primary??P.primary),document.documentElement.style.setProperty("--router-tab-header-bg",e.headerBackground??P.headerBackground),document.documentElement.style.setProperty("--router-tab-background",e.background??P.background),document.documentElement.style.setProperty("--router-tab-active-background",e.activeBackground??P.activeBackground),document.documentElement.style.setProperty("--router-tab-text",e.text??P.text),document.documentElement.style.setProperty("--router-tab-active-text",e.activeText??P.activeText),document.documentElement.style.setProperty("--router-tab-border",e.border??P.border),document.documentElement.style.setProperty("--router-tab-active-border",e.activeBorder??P.activeBorder),document.documentElement.style.setProperty("--router-tab-button-color",e.buttonColor??P.buttonColor),document.documentElement.style.setProperty("--router-tab-active-button-color",e.activeButtonColor??P.activeButtonColor),document.documentElement.style.setProperty("--router-tab-button-background",e.buttonBackground??P.buttonBackground),document.documentElement.style.setProperty("--router-tab-active-button-background",e.activeButtonBackground??P.activeButtonBackground),document.documentElement.style.setProperty("--router-tab-icon-color",e.iconColor??P.iconColor))}function Ee(e){if(typeof document>"u")return;const a=document.documentElement,r=window.matchMedia(Re),s=()=>{a.dataset.theme=r.matches?"dark":"light"};j&&(r.removeEventListener("change",j),j=null),e==="system"?(s(),j=()=>s(),r.addEventListener("change",j)):a.dataset.theme=e}function Be(e={}){if(typeof window>"u")return;const{styleKey:a=we,primaryKey:r=Ce,defaultStyle:s=nt,defaultPrimary:i}=e,p=window.localStorage.getItem(a)??s;Ee(p);const l=p==="dark"||p==="system"&&window.matchMedia(Re).matches?{...ot}:{...P};i&&(l.primary=i);const y=rt(r);ce(y?{...l,...y}:l)}function at(e,a){if(typeof window>"u")return;const r=a?.styleKey??we;window.localStorage.setItem(r,e),Ee(e)}function it(e,a){if(typeof window>"u")return;const r=a?.primaryKey??Ce;window.localStorage.setItem(r,JSON.stringify(e)),ce(e)}function Q(e,a){if(n.isRef(e)){const s=!n.isReadonly(e);return{value:e,update:s?i=>{e.value=i}:()=>{}}}if(typeof e=="function"){const s=e;return{value:n.computed(s),update:()=>{}}}const r=n.ref(e===void 0?a:e);return{value:r,update:s=>{r.value=s}}}function Z(e={}){const a=Q(e.title,"Untitled"),r=Q(e.icon,""),s=Q(e.closable,!0),i=Q(e.meta,{});return{routeTabTitle:a.value,routeTabIcon:r.value,routeTabClosable:s.value,routeTabMeta:i.value,updateTitle:a.update,updateIcon:r.update,updateClosable:s.update,updateMeta:i.update}}function lt(e,a="Page"){return Z({title:n.computed(()=>e.value?"Loading...":a),icon:n.computed(()=>e.value?"mdi-loading mdi-spin":"mdi-page"),closable:n.computed(()=>!e.value)})}function st(e,a="Page",r="mdi-page"){return Z({title:n.computed(()=>e.value>0?`${a} (${e.value})`:a),icon:n.computed(()=>e.value>0?"mdi-bell-badge":r)})}function ct(e,a="Page"){const r={normal:{suffix:"",icon:"mdi-page"},loading:{suffix:" - Loading",icon:"mdi-loading mdi-spin"},error:{suffix:" - Error",icon:"mdi-alert"},success:{suffix:" - Success",icon:"mdi-check-circle"}};return Z({title:n.computed(()=>a+r[e.value].suffix),icon:n.computed(()=>r[e.value].icon),closable:n.computed(()=>e.value!=="loading")})}let Ke=!1;const ut={install(e,a){if(Ke)return;Ke=!0;const{initTheme:r=!0,themeOptions:s,componentName:i=se.name||"RouterTab",tabsComponentName:p=X.name||"RouterTabs"}=a??{};r&&Be(s??{}),e.component(i,se),e.component(p,X),p.toLowerCase()!=="router-tabs"&&e.component("router-tabs",X),Object.defineProperty(e.config.globalProperties,"$tabs",{configurable:!0,enumerable:!1,get(){return e._context.provides[O]},set(w){w&&e.provide(O,w)}})}};E.RouterTab=se,E.RouterTabs=X,E.default=ut,E.initRouterTabsTheme=Be,E.routerTabsKey=O,E.setRouterTabsPrimary=it,E.setRouterTabsTheme=at,E.useLoadingTab=lt,E.useNotificationTab=st,E.useReactiveTab=Z,E.useRouterTabs=ie,E.useRouterTabsPersistence=le,E.useStatusTab=ct,Object.defineProperties(E,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
@@ -785,7 +785,29 @@ export default defineComponent({
785
785
  return defineComponent({
786
786
  name,
787
787
  setup(_, { attrs, slots }) {
788
- return () => h(component, attrs, slots)
788
+ const innerRef = ref<any>()
789
+
790
+ // Forward tab props to the wrapper proxy so handleComponentRef can see them
791
+ const instance = getCurrentInstance()
792
+ if (instance?.proxy) {
793
+ const proxy = instance.proxy as any
794
+ const forwardProps: Record<string, () => any> = {
795
+ routeTabTitle: () => innerRef.value?.routeTabTitle,
796
+ routeTabIcon: () => innerRef.value?.routeTabIcon,
797
+ routeTabClosable: () => innerRef.value?.routeTabClosable,
798
+ routeTabMeta: () => innerRef.value?.routeTabMeta,
799
+ $: () => innerRef.value
800
+ }
801
+
802
+ Object.entries(forwardProps).forEach(([key, getter]) => {
803
+ Object.defineProperty(proxy, key, {
804
+ get: getter,
805
+ configurable: true
806
+ })
807
+ })
808
+ }
809
+
810
+ return () => h(component, { ...attrs, ref: innerRef }, slots)
789
811
  }
790
812
  })
791
813
  }
@@ -866,25 +888,11 @@ export default defineComponent({
866
888
  const tab = controller.tabs.find(item => item.id === routeKey)
867
889
 
868
890
  if (!tab) {
869
- console.warn('[RouterTab] Tab not found for route:', routeKey)
870
891
  return `${routeKey}::0`
871
892
  }
872
893
 
873
894
  const renderKey = tab.renderKey ?? 0
874
895
  const cacheKey = `${routeKey}::${renderKey}`
875
-
876
- // Debug logging for specific routes
877
- if (routeKey.includes('students') || routeKey.includes('classroom') || routeKey.includes('quiz')) {
878
- console.log(`[getComponentCacheKey] Route: ${route.fullPath}`, {
879
- routeKey,
880
- renderKey,
881
- cacheKey,
882
- tabAlive: tab.alive,
883
- includeKeys: includeKeys.value,
884
- isIncluded: includeKeys.value.includes(cacheKey)
885
- })
886
- }
887
-
888
896
  return cacheKey
889
897
  }
890
898
 
@@ -1087,7 +1095,6 @@ export default defineComponent({
1087
1095
 
1088
1096
  instanceKeys.forEach(key => {
1089
1097
  if (!currentTabIds.has(key)) {
1090
- console.log(`[RouterTab] Cleaning up stale component instance: ${key}`)
1091
1098
  cleanupComponentWatching(key)
1092
1099
  }
1093
1100
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue3-router-tab",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",