vue3-router-tab 1.1.1 → 1.1.2

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,7 +1,7 @@
1
1
  import './vue3-router-tab.css';
2
- import { reactive as me, ref as Q, shallowRef as Ae, computed as K, watch as P, nextTick as ie, inject as oe, getCurrentInstance as ye, onMounted as Z, defineComponent as ge, provide as _e, onBeforeUnmount as Pe, resolveComponent as xe, createElementBlock as g, openBlock as m, createElementVNode as R, createCommentVNode as w, renderSlot as H, createVNode as E, TransitionGroup as $e, mergeProps as j, withCtx as z, Fragment as Y, renderList as ae, withModifiers as O, normalizeClass as le, createTextVNode as Ie, toDisplayString as se, normalizeProps as Ke, Transition as re, createBlock as q, KeepAlive as Se, resolveDynamicComponent as ce, normalizeStyle as Le } from "vue";
3
- import { RouterView as Me } from "vue-router";
4
- function Ee(e = {}) {
2
+ import { reactive as ye, ref as Z, shallowRef as _e, computed as I, watch as P, nextTick as oe, inject as ae, getCurrentInstance as ge, onMounted as ee, defineComponent as Te, provide as Pe, onBeforeUnmount as xe, resolveComponent as $e, createElementBlock as g, openBlock as m, createElementVNode as R, createCommentVNode as w, renderSlot as Y, createVNode as E, TransitionGroup as Ke, mergeProps as j, withCtx as z, Fragment as q, renderList as le, withModifiers as O, normalizeClass as se, createTextVNode as Ie, toDisplayString as re, normalizeProps as Se, Transition as ce, createBlock as W, KeepAlive as Le, resolveDynamicComponent as ue, normalizeStyle as Me } from "vue";
3
+ import { RouterView as Ee } from "vue-router";
4
+ function je(e = {}) {
5
5
  return {
6
6
  initialTabs: e.initialTabs ?? [],
7
7
  keepAlive: e.keepAlive ?? !0,
@@ -11,13 +11,13 @@ function Ee(e = {}) {
11
11
  defaultRoute: e.defaultRoute ?? "/"
12
12
  };
13
13
  }
14
- function A(e, n) {
15
- const o = e.resolve(n);
14
+ function A(e, i) {
15
+ const o = e.resolve(i);
16
16
  if (!o || !o.matched.length)
17
- throw new Error(`[RouterTabs] Unable to resolve route: ${String(n)}`);
17
+ throw new Error(`[RouterTabs] Unable to resolve route: ${String(i)}`);
18
18
  return o;
19
19
  }
20
- const je = {
20
+ const ze = {
21
21
  path: (e) => e.path,
22
22
  fullpath: (e) => e.fullPath,
23
23
  fullname: (e) => e.fullPath,
@@ -25,65 +25,65 @@ const je = {
25
25
  name: (e) => e.name ? String(e.name) : e.fullPath
26
26
  };
27
27
  function _(e) {
28
- const n = e.meta?.key;
29
- if (typeof n == "function") {
30
- const o = n(e);
28
+ const i = e.meta?.key;
29
+ if (typeof i == "function") {
30
+ const o = i(e);
31
31
  if (typeof o == "string" && o.length) return o;
32
- } else if (typeof n == "string" && n.length) {
33
- const o = je[n.toLowerCase()];
34
- return o ? o(e) : n;
32
+ } else if (typeof i == "string" && i.length) {
33
+ const o = ze[i.toLowerCase()];
34
+ return o ? o(e) : i;
35
35
  }
36
36
  return e.fullPath;
37
37
  }
38
- function ee(e, n) {
38
+ function te(e, i) {
39
39
  const o = e.meta?.keepAlive;
40
- return typeof o == "boolean" ? o : n;
40
+ return typeof o == "boolean" ? o : i;
41
41
  }
42
- function te(e, n) {
42
+ function ne(e, i) {
43
43
  const o = e.meta?.reuse;
44
- return typeof o == "boolean" ? o : n;
44
+ return typeof o == "boolean" ? o : i;
45
45
  }
46
- function Te(e) {
47
- const n = e.meta ?? {}, o = {};
48
- return "title" in n && (o.title = n.title), "tips" in n && (o.tips = n.tips), "icon" in n && (o.icon = n.icon), "closable" in n && (o.closable = n.closable), "tabClass" in n && (o.tabClass = n.tabClass), "target" in n && (o.target = n.target), "href" in n && (o.href = n.href), o;
46
+ function ke(e) {
47
+ const i = e.meta ?? {}, o = {};
48
+ return "title" in i && (o.title = i.title), "tips" in i && (o.tips = i.tips), "icon" in i && (o.icon = i.icon), "closable" in i && (o.closable = i.closable), "tabClass" in i && (o.tabClass = i.tabClass), "target" in i && (o.target = i.target), "href" in i && (o.href = i.href), o;
49
49
  }
50
- function V(e, n, o) {
51
- const t = Te(e);
50
+ function V(e, i, o) {
51
+ const t = ke(e);
52
52
  return {
53
53
  id: _(e),
54
54
  to: e.fullPath,
55
55
  fullPath: e.fullPath,
56
56
  matched: e,
57
- alive: ee(e, o),
58
- reusable: te(e, !1),
57
+ alive: te(e, o),
58
+ reusable: ne(e, !1),
59
59
  closable: t.closable ?? !0,
60
60
  ...t,
61
- ...n
61
+ ...i
62
62
  };
63
63
  }
64
- function W(e, n, o, t) {
65
- if (!e.find((d) => d.id === n.id)) {
64
+ function X(e, i, o, t) {
65
+ if (!e.find((d) => d.id === i.id)) {
66
66
  if (o === "next" && t) {
67
67
  const d = e.findIndex((b) => b.id === t);
68
68
  if (d > -1) {
69
- e.splice(d + 1, 0, n);
69
+ e.splice(d + 1, 0, i);
70
70
  return;
71
71
  }
72
72
  }
73
- e.push(n);
73
+ e.push(i);
74
74
  }
75
75
  }
76
- function ue(e, n, o) {
77
- if (!n || n <= 0) return;
76
+ function fe(e, i, o) {
77
+ if (!i || i <= 0) return;
78
78
  const t = e.filter((r) => r.alive);
79
- for (; t.length > n; ) {
79
+ for (; t.length > i; ) {
80
80
  const r = t.shift();
81
81
  if (!r || r.id === o) continue;
82
82
  const d = e.findIndex((b) => b.id === r.id);
83
83
  d > -1 && (e[d].alive = !1);
84
84
  }
85
85
  }
86
- function ze(e) {
86
+ function Oe(e) {
87
87
  return {
88
88
  to: e.to,
89
89
  title: e.title,
@@ -93,31 +93,31 @@ function ze(e) {
93
93
  closable: e.closable
94
94
  };
95
95
  }
96
- function Oe(e) {
97
- const n = {};
98
- return "title" in e && (n.title = e.title), "tips" in e && (n.tips = e.tips), "icon" in e && (n.icon = e.icon), "tabClass" in e && (n.tabClass = e.tabClass), "closable" in e && (n.closable = e.closable), n;
96
+ function Ve(e) {
97
+ const i = {};
98
+ return "title" in e && (i.title = e.title), "tips" in e && (i.tips = e.tips), "icon" in e && (i.icon = e.icon), "tabClass" in e && (i.tabClass = e.tabClass), "closable" in e && (i.closable = e.closable), i;
99
99
  }
100
- function Ve(e, n = {}) {
101
- const o = Ee(n), t = me([]), r = Q(null), d = Ae(), b = Q(null), l = K(() => t.filter((a) => a.alive).map((a) => a.id));
100
+ function De(e, i = {}) {
101
+ const o = je(i), t = ye([]), r = Z(null), d = _e(), b = Z(null), l = I(() => t.filter((a) => a.alive).map((a) => a.id));
102
102
  let u = !1;
103
103
  function T(a) {
104
104
  const s = typeof a.matched == "object" ? a : A(e, a);
105
105
  return {
106
106
  key: _(s),
107
107
  fullPath: s.fullPath,
108
- alive: ee(s, o.keepAlive),
109
- reusable: te(s, !1),
108
+ alive: te(s, o.keepAlive),
109
+ reusable: ne(s, !1),
110
110
  matched: s
111
111
  };
112
112
  }
113
113
  function C(a) {
114
114
  const s = _(a);
115
115
  let c = t.find((p) => p.id === s);
116
- return c ? (c.fullPath = a.fullPath, c.to = a.fullPath, c.matched = a, c.alive = ee(a, o.keepAlive), c.reusable = te(a, c.reusable), Object.assign(c, Te(a)), c) : (c = V(a, {}, o.keepAlive), W(t, c, o.appendPosition, r.value), ue(t, o.maxAlive, r.value), c);
116
+ return c ? (c.fullPath = a.fullPath, c.to = a.fullPath, c.matched = a, c.alive = te(a, o.keepAlive), c.reusable = ne(a, c.reusable), Object.assign(c, ke(a)), c) : (c = V(a, {}, o.keepAlive), X(t, c, o.appendPosition, r.value), fe(t, o.maxAlive, r.value), c);
117
117
  }
118
118
  async function S(a, s = !1, c = !0) {
119
- const p = A(e, a), k = _(p), i = r.value === k;
120
- c === "sameTab" && (c = i), c && await v(k, !0), await e[s ? "replace" : "push"](p), i && await $();
119
+ const p = A(e, a), k = _(p), n = r.value === k;
120
+ c === "sameTab" && (c = n), c && await v(k, !0), await e[s ? "replace" : "push"](p), n && await $();
121
121
  }
122
122
  function L(a) {
123
123
  const s = t.findIndex((p) => p.id === a), c = t[s] || t[s - 1] || t[0];
@@ -139,13 +139,13 @@ function Ve(e, n = {}) {
139
139
  c !== -1 && (t.splice(c, 1), b.value === a && (b.value = null), r.value === a && (r.value = null, d.value = void 0));
140
140
  }
141
141
  async function v(a = r.value ?? void 0, s = !1) {
142
- a && (b.value = a, await ie(), s || await ie(), b.value = null);
142
+ a && (b.value = a, await oe(), s || await oe(), b.value = null);
143
143
  }
144
- async function N(a = !1) {
144
+ async function U(a = !1) {
145
145
  for (const s of t)
146
146
  await v(s.id, a);
147
147
  }
148
- async function U(a = o.defaultRoute) {
148
+ async function B(a = o.defaultRoute) {
149
149
  t.splice(0, t.length), r.value = null, d.value = void 0;
150
150
  for (const s of o.initialTabs) {
151
151
  const c = A(e, s.to), p = V(c, s, o.keepAlive);
@@ -157,23 +157,23 @@ function Ve(e, n = {}) {
157
157
  const a = r.value;
158
158
  a && await v(a, !0);
159
159
  }
160
- function B(a) {
160
+ function F(a) {
161
161
  return typeof a.matched == "object" ? _(a) : _(A(e, a));
162
162
  }
163
- function F() {
163
+ function G() {
164
164
  const a = t.find((s) => s.id === r.value);
165
165
  return {
166
- tabs: t.map(ze),
166
+ tabs: t.map(Oe),
167
167
  active: a ? a.to : null
168
168
  };
169
169
  }
170
- async function I(a) {
170
+ async function K(a) {
171
171
  u = !0, t.splice(0, t.length), r.value = null, d.value = void 0;
172
172
  const s = a?.tabs ?? [];
173
173
  for (const p of s)
174
174
  try {
175
- const k = A(e, p.to), i = Oe(p), f = V(k, i, o.keepAlive);
176
- W(t, f, "last", null);
175
+ const k = A(e, p.to), n = Ve(p), f = V(k, n, o.keepAlive);
176
+ X(t, f, "last", null);
177
177
  } catch {
178
178
  }
179
179
  u = !1;
@@ -189,12 +189,12 @@ function Ve(e, n = {}) {
189
189
  (a) => {
190
190
  if (u) return;
191
191
  const s = C(a);
192
- r.value = s.id, d.value = s, ue(t, o.maxAlive, r.value);
192
+ r.value = s.id, d.value = s, fe(t, o.maxAlive, r.value);
193
193
  },
194
194
  { immediate: !0 }
195
195
  ), o.initialTabs.length && o.initialTabs.forEach((a) => {
196
196
  const s = A(e, a.to), c = V(s, a, o.keepAlive);
197
- W(t, c, "last", null);
197
+ X(t, c, "last", null);
198
198
  }), {
199
199
  options: o,
200
200
  tabs: t,
@@ -206,40 +206,40 @@ function Ve(e, n = {}) {
206
206
  closeTab: x,
207
207
  removeTab: M,
208
208
  refreshTab: v,
209
- refreshAll: N,
210
- reset: U,
209
+ refreshAll: U,
210
+ reset: B,
211
211
  reload: $,
212
- getRouteKey: B,
212
+ getRouteKey: F,
213
213
  matchRoute: T,
214
- snapshot: F,
215
- hydrate: I
214
+ snapshot: G,
215
+ hydrate: K
216
216
  };
217
217
  }
218
- function fe(e) {
218
+ function de(e) {
219
219
  return e ? typeof e == "string" ? { name: e } : e : {};
220
220
  }
221
- const D = Symbol("RouterTabsContext"), De = "router-tabs:snapshot";
222
- function de(e = {}) {
223
- const { optional: n = !1 } = e, o = oe(D, null);
221
+ const N = Symbol("RouterTabsContext"), D = "router-tabs:snapshot";
222
+ function be(e = {}) {
223
+ const { optional: i = !1 } = e, o = ae(N, null);
224
224
  if (o) return o;
225
- const t = oe("$tabs", null);
225
+ const t = ae("$tabs", null);
226
226
  if (t) return t;
227
- const d = ye()?.appContext.config.globalProperties.$tabs;
227
+ const d = ge()?.appContext.config.globalProperties.$tabs;
228
228
  if (d) return d;
229
- if (!n)
229
+ if (!i)
230
230
  throw new Error("[RouterTabs] useRouterTabs must be used within <router-tab>.");
231
231
  return null;
232
232
  }
233
233
  const Ne = 864e5;
234
234
  function Ue(e) {
235
235
  if (typeof document > "u") return null;
236
- const n = `${encodeURIComponent(e)}=`, o = document.cookie ? document.cookie.split("; ") : [];
236
+ const i = `${encodeURIComponent(e)}=`, o = document.cookie ? document.cookie.split("; ") : [];
237
237
  for (const t of o)
238
- if (t.startsWith(n))
239
- return decodeURIComponent(t.slice(n.length));
238
+ if (t.startsWith(i))
239
+ return decodeURIComponent(t.slice(i.length));
240
240
  return null;
241
241
  }
242
- function be(e, n, o) {
242
+ function pe(e, i, o) {
243
243
  if (typeof document > "u") return;
244
244
  const {
245
245
  expiresInDays: t = 7,
@@ -247,16 +247,16 @@ function be(e, n, o) {
247
247
  domain: d,
248
248
  secure: b,
249
249
  sameSite: l = "lax"
250
- } = o, u = [`${encodeURIComponent(e)}=${encodeURIComponent(n)}`];
250
+ } = o, u = [`${encodeURIComponent(e)}=${encodeURIComponent(i)}`];
251
251
  if (t !== 1 / 0) {
252
252
  const T = new Date(Date.now() + t * Ne).toUTCString();
253
253
  u.push(`Expires=${T}`);
254
254
  }
255
255
  r && u.push(`Path=${r}`), d && u.push(`Domain=${d}`), b && u.push("Secure"), l && u.push(`SameSite=${l.charAt(0).toUpperCase()}${l.slice(1)}`), document.cookie = u.join("; ");
256
256
  }
257
- function pe(e, n) {
257
+ function he(e, i) {
258
258
  if (typeof document > "u") return;
259
- const { path: o = "/", domain: t } = n, r = [`${encodeURIComponent(e)}=`];
259
+ const { path: o = "/", domain: t } = i, r = [`${encodeURIComponent(e)}=`];
260
260
  r.push("Expires=Thu, 01 Jan 1970 00:00:01 GMT"), o && r.push(`Path=${o}`), t && r.push(`Domain=${t}`), document.cookie = r.join("; ");
261
261
  }
262
262
  const Be = (e) => JSON.stringify(e ?? null), Fe = (e) => {
@@ -267,14 +267,14 @@ const Be = (e) => JSON.stringify(e ?? null), Fe = (e) => {
267
267
  return null;
268
268
  }
269
269
  };
270
- function ke(e = {}) {
270
+ function Ce(e = {}) {
271
271
  const {
272
- cookieKey: n = De,
272
+ cookieKey: i = D,
273
273
  serialize: o = Be,
274
274
  deserialize: t = Fe
275
- } = e, r = de({ optional: !0 }), d = Q(!1), b = (l) => {
276
- Z(async () => {
277
- const u = t(Ue(n));
275
+ } = e, r = be({ optional: !0 }), d = Z(!0), b = (l) => {
276
+ ee(async () => {
277
+ const u = t(Ue(i));
278
278
  if (u && u.tabs?.length)
279
279
  try {
280
280
  d.value = !0, await l.hydrate(u);
@@ -290,7 +290,7 @@ function ke(e = {}) {
290
290
  d.value = !1;
291
291
  }
292
292
  const T = l.snapshot();
293
- T.tabs.length ? be(n, o(T), e) : pe(n, e);
293
+ T.tabs.length ? pe(i, o(T), e) : he(i, e), d.value = !1;
294
294
  }), P(
295
295
  () => ({
296
296
  tabs: l.tabs.map((u) => ({
@@ -306,19 +306,19 @@ function ke(e = {}) {
306
306
  () => {
307
307
  if (d.value) return;
308
308
  const u = l.snapshot();
309
- u.tabs.length ? be(n, o(u), e) : pe(n, e);
309
+ u.tabs.length ? pe(i, o(u), e) : he(i, e);
310
310
  },
311
311
  { deep: !0 }
312
312
  );
313
313
  };
314
- r ? b(r) : Z(() => {
315
- const l = de({ optional: !0 });
314
+ r ? b(r) : ee(() => {
315
+ const l = be({ optional: !0 });
316
316
  l && b(l);
317
317
  });
318
318
  }
319
- const Ge = ge({
319
+ const Ge = Te({
320
320
  name: "RouterTab",
321
- components: { RouterView: Me },
321
+ components: { RouterView: Ee },
322
322
  props: {
323
323
  tabs: {
324
324
  type: Array,
@@ -358,7 +358,7 @@ const Ge = ge({
358
358
  },
359
359
  cookieKey: {
360
360
  type: String,
361
- default: null
361
+ default: D
362
362
  },
363
363
  persistence: {
364
364
  type: Object,
@@ -366,13 +366,13 @@ const Ge = ge({
366
366
  }
367
367
  },
368
368
  setup(e) {
369
- const n = ye();
370
- if (!n)
369
+ const i = ge();
370
+ if (!i)
371
371
  throw new Error("[RouterTab] component must be used within a Vue application context.");
372
- const o = n.appContext.app.config.globalProperties.$router;
372
+ const o = i.appContext.app.config.globalProperties.$router;
373
373
  if (!o)
374
374
  throw new Error("[RouterTab] Vue Router is required. Make sure to call app.use(router) before RouterTab.");
375
- const t = Ve(o, {
375
+ const t = De(o, {
376
376
  initialTabs: e.tabs,
377
377
  keepAlive: e.keepAlive,
378
378
  maxAlive: e.maxAlive,
@@ -380,15 +380,15 @@ const Ge = ge({
380
380
  appendPosition: e.append,
381
381
  defaultRoute: e.defaultPage
382
382
  });
383
- _e(D, t), n.appContext.config.globalProperties.$tabs = t;
384
- const r = K(() => !!n?.slots?.default);
385
- if (e.cookieKey || e.persistence) {
386
- const i = {
383
+ Pe(N, t), i.appContext.config.globalProperties.$tabs = t;
384
+ const r = I(() => !!i?.slots?.default);
385
+ if (e.cookieKey !== null || e.persistence) {
386
+ const n = {
387
387
  ...e.persistence ?? {}
388
388
  };
389
- e.cookieKey && (i.cookieKey = e.cookieKey), ke(i);
389
+ e.cookieKey !== null ? n.cookieKey = e.cookieKey || D : n.cookieKey || (n.cookieKey = D), Ce(n);
390
390
  }
391
- const d = K(() => fe(e.tabTransition)), b = K(() => fe(e.pageTransition)), l = me({
391
+ const d = I(() => de(e.tabTransition)), b = I(() => de(e.pageTransition)), l = ye({
392
392
  visible: !1,
393
393
  target: null,
394
394
  position: { x: 0, y: 0 }
@@ -400,22 +400,22 @@ const Ge = ge({
400
400
  "closeRights",
401
401
  "closeOthers"
402
402
  ];
403
- function T(i) {
404
- return t.tabs.findIndex((f) => f.id === i);
403
+ function T(n) {
404
+ return t.tabs.findIndex((f) => f.id === n);
405
405
  }
406
- function C(i) {
407
- const f = T(i.id);
406
+ function C(n) {
407
+ const f = T(n.id);
408
408
  return f > 0 ? t.tabs.slice(0, f) : [];
409
409
  }
410
- function S(i) {
411
- const f = T(i.id);
410
+ function S(n) {
411
+ const f = T(n.id);
412
412
  return f > -1 ? t.tabs.slice(f + 1) : [];
413
413
  }
414
- function L(i) {
415
- return t.tabs.filter((f) => f.id !== i.id);
414
+ function L(n) {
415
+ return t.tabs.filter((f) => f.id !== n.id);
416
416
  }
417
- async function x(i, f) {
418
- const h = i.filter((y) => y.closable !== !1);
417
+ async function x(n, f) {
418
+ const h = n.filter((y) => y.closable !== !1);
419
419
  if (h.length) {
420
420
  for (const y of h)
421
421
  t.activeId.value === y.id ? await t.closeTab(y.id, { redirect: f.to, force: !0 }) : await t.removeTab(y.id, { force: !0 });
@@ -425,8 +425,8 @@ const Ge = ge({
425
425
  const M = {
426
426
  refresh: {
427
427
  label: "Refresh",
428
- handler: async ({ target: i }) => {
429
- await t.refreshTab(i.id, !0);
428
+ handler: async ({ target: n }) => {
429
+ await t.refreshTab(n.id, !0);
430
430
  }
431
431
  },
432
432
  refreshAll: {
@@ -437,108 +437,108 @@ const Ge = ge({
437
437
  },
438
438
  close: {
439
439
  label: "Close",
440
- handler: async ({ target: i }) => {
441
- await t.closeTab(i.id);
440
+ handler: async ({ target: n }) => {
441
+ await t.closeTab(n.id);
442
442
  },
443
- enable: ({ target: i }) => I(i)
443
+ enable: ({ target: n }) => K(n)
444
444
  },
445
445
  closeLefts: {
446
446
  label: "Close to the Left",
447
- handler: async ({ target: i }) => {
448
- await x(C(i), i);
447
+ handler: async ({ target: n }) => {
448
+ await x(C(n), n);
449
449
  },
450
- enable: ({ target: i }) => C(i).some((f) => f.closable !== !1)
450
+ enable: ({ target: n }) => C(n).some((f) => f.closable !== !1)
451
451
  },
452
452
  closeRights: {
453
453
  label: "Close to the Right",
454
- handler: async ({ target: i }) => {
455
- await x(S(i), i);
454
+ handler: async ({ target: n }) => {
455
+ await x(S(n), n);
456
456
  },
457
- enable: ({ target: i }) => S(i).some((f) => f.closable !== !1)
457
+ enable: ({ target: n }) => S(n).some((f) => f.closable !== !1)
458
458
  },
459
459
  closeOthers: {
460
460
  label: "Close Others",
461
- handler: async ({ target: i }) => {
462
- await x(L(i), i);
461
+ handler: async ({ target: n }) => {
462
+ await x(L(n), n);
463
463
  },
464
- enable: ({ target: i }) => L(i).some((f) => f.closable !== !1)
464
+ enable: ({ target: n }) => L(n).some((f) => f.closable !== !1)
465
465
  }
466
466
  };
467
467
  function v() {
468
468
  l.visible = !1, l.target = null;
469
469
  }
470
- function N(i, f) {
471
- e.contextmenu && (l.visible = !0, l.target = i, l.position.x = f.clientX, l.position.y = f.clientY, document.addEventListener("click", v, { once: !0 }));
470
+ function U(n, f) {
471
+ e.contextmenu && (l.visible = !0, l.target = n, l.position.x = f.clientX, l.position.y = f.clientY, document.addEventListener("click", v, { once: !0 }));
472
472
  }
473
- function U(i, f) {
474
- const h = typeof i == "string" ? { id: i } : i, y = M[h.id], Ce = h.label ?? y?.label ?? String(h.id), G = h.visible ?? y?.visible ?? !0;
475
- if (!(typeof G == "function" ? G(f) : G !== !1)) return null;
476
- const J = h.enable ?? y?.enable ?? !0, Re = typeof J == "function" ? J(f) : J !== !1, ne = h.handler ?? y?.handler;
477
- if (!ne) return null;
478
- const we = async () => {
479
- await Promise.resolve(ne(f));
473
+ function B(n, f) {
474
+ const h = typeof n == "string" ? { id: n } : n, y = M[h.id], Re = h.label ?? y?.label ?? String(h.id), J = h.visible ?? y?.visible ?? !0;
475
+ if (!(typeof J == "function" ? J(f) : J !== !1)) return null;
476
+ const H = h.enable ?? y?.enable ?? !0, we = typeof H == "function" ? H(f) : H !== !1, ie = h.handler ?? y?.handler;
477
+ if (!ie) return null;
478
+ const Ae = async () => {
479
+ await Promise.resolve(ie(f));
480
480
  };
481
481
  return {
482
482
  id: String(h.id),
483
- label: Ce,
484
- disabled: !Re,
485
- action: we
483
+ label: Re,
484
+ disabled: !we,
485
+ action: Ae
486
486
  };
487
487
  }
488
- const $ = K(() => {
488
+ const $ = I(() => {
489
489
  if (!l.visible || !l.target || e.contextmenu === !1) return [];
490
- const i = Array.isArray(e.contextmenu) ? e.contextmenu : u, f = { target: l.target, controller: t };
491
- return i.map((h) => U(h, f)).filter((h) => !!h);
490
+ const n = Array.isArray(e.contextmenu) ? e.contextmenu : u, f = { target: l.target, controller: t };
491
+ return n.map((h) => B(h, f)).filter((h) => !!h);
492
492
  });
493
- async function B(i) {
494
- i.disabled || (v(), await i.action());
493
+ async function F(n) {
494
+ n.disabled || (v(), await n.action());
495
495
  }
496
- function F(i) {
497
- return typeof i.title == "string" ? i.title : Array.isArray(i.title) && i.title.length ? String(i.title[0]) : i.fullPath;
496
+ function G(n) {
497
+ return typeof n.title == "string" ? n.title : Array.isArray(n.title) && n.title.length ? String(n.title[0]) : n.fullPath;
498
498
  }
499
- function I(i) {
500
- return !(i.closable === !1 || t.options.keepLastTab && t.tabs.length <= 1);
499
+ function K(n) {
500
+ return !(n.closable === !1 || t.options.keepLastTab && t.tabs.length <= 1);
501
501
  }
502
- async function a(i) {
503
- await t.closeTab(i.id);
502
+ async function a(n) {
503
+ await t.closeTab(n.id);
504
504
  }
505
- function s(i) {
506
- t.activeId.value !== i.id && t.openTab(i.to, !1);
505
+ function s(n) {
506
+ t.activeId.value !== n.id && t.openTab(n.to, !1);
507
507
  }
508
- function c(i) {
508
+ function c(n) {
509
509
  return [
510
510
  "router-tab__item",
511
511
  {
512
- "is-active": t.activeId.value === i.id,
513
- "is-closable": I(i)
512
+ "is-active": t.activeId.value === n.id,
513
+ "is-closable": K(n)
514
514
  },
515
- i.tabClass
515
+ n.tabClass
516
516
  ];
517
517
  }
518
- function p(i) {
519
- return t.refreshingKey.value === t.getRouteKey(i);
518
+ function p(n) {
519
+ return t.refreshingKey.value === t.getRouteKey(n);
520
520
  }
521
- Z(() => {
521
+ ee(() => {
522
522
  document.addEventListener("keydown", v);
523
- }), Pe(() => {
524
- document.removeEventListener("keydown", v), n.appContext.config.globalProperties.$tabs = null;
523
+ }), xe(() => {
524
+ document.removeEventListener("keydown", v), i.appContext.config.globalProperties.$tabs = null;
525
525
  }), P(
526
526
  () => e.keepAlive,
527
- (i) => {
528
- t.options.keepAlive = i;
527
+ (n) => {
528
+ t.options.keepAlive = n;
529
529
  }
530
530
  ), P(
531
531
  () => t.activeId.value,
532
532
  () => v()
533
533
  ), P(
534
534
  () => e.contextmenu,
535
- (i) => {
536
- i || v();
535
+ (n) => {
536
+ n || v();
537
537
  }
538
538
  ), P(
539
539
  () => $.value.length,
540
- (i) => {
541
- l.visible && i === 0 && v();
540
+ (n) => {
541
+ l.visible && n === 0 && v();
542
542
  }
543
543
  );
544
544
  const k = t.includeKeys;
@@ -553,37 +553,37 @@ const Ge = ge({
553
553
  close: a,
554
554
  context: l,
555
555
  menuItems: $,
556
- handleMenuAction: B,
557
- showContextMenu: N,
556
+ handleMenuAction: F,
557
+ showContextMenu: U,
558
558
  hideContextMenu: v,
559
- tabTitle: F,
560
- isClosable: I,
559
+ tabTitle: G,
560
+ isClosable: K,
561
561
  isRefreshing: p,
562
562
  hasCustomSlot: r
563
563
  };
564
564
  }
565
- }), Je = (e, n) => {
565
+ }), Je = (e, i) => {
566
566
  const o = e.__vccOpts || e;
567
- for (const [t, r] of n)
567
+ for (const [t, r] of i)
568
568
  o[t] = r;
569
569
  return o;
570
570
  }, He = { class: "router-tab" }, Ye = { class: "router-tab__header" }, qe = { class: "router-tab__slot-start" }, We = { class: "router-tab__scroll" }, Xe = ["onClick", "onAuxclick", "onContextmenu"], Qe = ["title"], Ze = ["onClick"], et = { class: "router-tab__slot-end" }, tt = { class: "router-tab__container" }, nt = ["aria-disabled", "onClick"];
571
- function it(e, n, o, t, r, d) {
572
- const b = xe("RouterView");
571
+ function it(e, i, o, t, r, d) {
572
+ const b = $e("RouterView");
573
573
  return m(), g("div", He, [
574
574
  R("header", Ye, [
575
575
  R("div", qe, [
576
- H(e.$slots, "start")
576
+ Y(e.$slots, "start")
577
577
  ]),
578
578
  R("div", We, [
579
- E($e, j({
579
+ E(Ke, j({
580
580
  tag: "ul",
581
581
  class: "router-tab__nav"
582
582
  }, e.tabTransitionProps), {
583
583
  default: z(() => [
584
- (m(!0), g(Y, null, ae(e.tabs, (l) => (m(), g("li", {
584
+ (m(!0), g(q, null, le(e.tabs, (l) => (m(), g("li", {
585
585
  key: l.id,
586
- class: le(e.buildTabClass(l)),
586
+ class: se(e.buildTabClass(l)),
587
587
  onClick: (u) => e.activate(l),
588
588
  onAuxclick: O((u) => e.close(l), ["middle", "prevent"]),
589
589
  onContextmenu: O((u) => e.showContextMenu(l, u), ["prevent"])
@@ -594,9 +594,9 @@ function it(e, n, o, t, r, d) {
594
594
  }, [
595
595
  l.icon ? (m(), g("i", {
596
596
  key: 0,
597
- class: le(["router-tab__item-icon", l.icon])
597
+ class: se(["router-tab__item-icon", l.icon])
598
598
  }, null, 2)) : w("", !0),
599
- Ie(" " + se(e.tabTitle(l)), 1)
599
+ Ie(" " + re(e.tabTitle(l)), 1)
600
600
  ], 8, Qe),
601
601
  e.isClosable(l) ? (m(), g("a", {
602
602
  key: 0,
@@ -610,21 +610,21 @@ function it(e, n, o, t, r, d) {
610
610
  }, 16)
611
611
  ]),
612
612
  R("div", et, [
613
- H(e.$slots, "end")
613
+ Y(e.$slots, "end")
614
614
  ])
615
615
  ]),
616
616
  R("div", tt, [
617
617
  E(b, null, {
618
618
  default: z((l) => [
619
- e.hasCustomSlot ? H(e.$slots, "default", Ke(j({ key: 0 }, { ...l, controller: e.controller }))) : (m(), g(Y, { key: 1 }, [
620
- E(re, j(e.pageTransitionProps, { appear: "" }), {
619
+ e.hasCustomSlot ? Y(e.$slots, "default", Se(j({ key: 0 }, { ...l, controller: e.controller }))) : (m(), g(q, { key: 1 }, [
620
+ E(ce, j(e.pageTransitionProps, { appear: "" }), {
621
621
  default: z(() => [
622
- e.controller.options.keepAlive ? (m(), q(Se, {
622
+ e.controller.options.keepAlive ? (m(), W(Le, {
623
623
  key: 0,
624
624
  include: e.includeKeys,
625
625
  max: e.controller.options.maxAlive || void 0
626
626
  }, [
627
- e.isRefreshing(l.route) ? w("", !0) : (m(), q(ce(l.Component), {
627
+ e.isRefreshing(l.route) ? w("", !0) : (m(), W(ue(l.Component), {
628
628
  key: e.controller.getRouteKey(l.route),
629
629
  class: "router-tab-page"
630
630
  }))
@@ -632,9 +632,9 @@ function it(e, n, o, t, r, d) {
632
632
  ]),
633
633
  _: 2
634
634
  }, 1040),
635
- E(re, j(e.pageTransitionProps, { appear: "" }), {
635
+ E(ce, j(e.pageTransitionProps, { appear: "" }), {
636
636
  default: z(() => [
637
- !e.controller.options.keepAlive || e.isRefreshing(l.route) ? (m(), q(ce(l.Component), {
637
+ !e.controller.options.keepAlive || e.isRefreshing(l.route) ? (m(), W(ue(l.Component), {
638
638
  key: e.controller.getRouteKey(l.route) + (e.isRefreshing(l.route) ? "-refresh" : ""),
639
639
  class: "router-tab-page"
640
640
  })) : w("", !0)
@@ -649,21 +649,21 @@ function it(e, n, o, t, r, d) {
649
649
  e.context.visible && e.context.target ? (m(), g("div", {
650
650
  key: 0,
651
651
  class: "router-tab__contextmenu",
652
- style: Le({ left: e.context.position.x + "px", top: e.context.position.y + "px" })
652
+ style: Me({ left: e.context.position.x + "px", top: e.context.position.y + "px" })
653
653
  }, [
654
- (m(!0), g(Y, null, ae(e.menuItems, (l) => (m(), g("a", {
654
+ (m(!0), g(q, null, le(e.menuItems, (l) => (m(), g("a", {
655
655
  key: l.id,
656
656
  class: "router-tab__contextmenu-item",
657
657
  "aria-disabled": l.disabled,
658
658
  onClick: O((u) => e.handleMenuAction(l), ["prevent"])
659
- }, se(l.label), 9, nt))), 128))
659
+ }, re(l.label), 9, nt))), 128))
660
660
  ], 4)) : w("", !0)
661
661
  ]);
662
662
  }
663
- const he = /* @__PURE__ */ Je(Ge, [["render", it]]), ot = {
663
+ const ve = /* @__PURE__ */ Je(Ge, [["render", it]]), ot = {
664
664
  class: "router-tabs",
665
665
  "aria-hidden": "true"
666
- }, X = /* @__PURE__ */ ge({
666
+ }, Q = /* @__PURE__ */ Te({
667
667
  name: "RouterTabs",
668
668
  __name: "RouterTabs",
669
669
  props: {
@@ -678,30 +678,30 @@ const he = /* @__PURE__ */ Je(Ge, [["render", it]]), ot = {
678
678
  fallbackRoute: {}
679
679
  },
680
680
  setup(e) {
681
- return ke(e), (o, t) => (m(), g("span", ot));
681
+ return Ce(e), (o, t) => (m(), g("span", ot));
682
682
  }
683
- }), ve = {
683
+ }), me = {
684
684
  install(e) {
685
- if (ve._installed) return;
686
- ve._installed = !0;
687
- const n = he.name || "RouterTab", o = X.name || "RouterTabs";
688
- e.component(n, he), e.component(o, X), o !== "router-tabs" && e.component("router-tabs", X), Object.defineProperty(e.config.globalProperties, "$tabs", {
685
+ if (me._installed) return;
686
+ me._installed = !0;
687
+ const i = ve.name || "RouterTab", o = Q.name || "RouterTabs";
688
+ e.component(i, ve), e.component(o, Q), o !== "router-tabs" && e.component("router-tabs", Q), Object.defineProperty(e.config.globalProperties, "$tabs", {
689
689
  configurable: !0,
690
690
  enumerable: !1,
691
691
  get() {
692
- return e._context.provides[D];
692
+ return e._context.provides[N];
693
693
  },
694
694
  set(t) {
695
- t && e.provide(D, t);
695
+ t && e.provide(N, t);
696
696
  }
697
697
  });
698
698
  }
699
699
  };
700
700
  export {
701
- he as RouterTab,
702
- X as RouterTabs,
703
- ve as default,
704
- D as routerTabsKey,
705
- de as useRouterTabs,
706
- ke as useRouterTabsPersistence
701
+ ve as RouterTab,
702
+ Q as RouterTabs,
703
+ me as default,
704
+ N as routerTabsKey,
705
+ be as useRouterTabs,
706
+ Ce as useRouterTabsPersistence
707
707
  };
@@ -1 +1 @@
1
- (function(y,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue"),require("vue-router")):typeof define=="function"&&define.amd?define(["exports","vue","vue-router"],t):(y=typeof globalThis<"u"?globalThis:y||self,t(y["vue3-router-tab"]={},y.Vue,y.VueRouter))})(this,(function(y,t,Z){"use strict";function ee(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 w(e,o){const a=e.resolve(o);if(!a||!a.matched.length)throw new Error(`[RouterTabs] Unable to resolve route: ${String(o)}`);return a}const te={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 R(e){const o=e.meta?.key;if(typeof o=="function"){const a=o(e);if(typeof a=="string"&&a.length)return a}else if(typeof o=="string"&&o.length){const a=te[o.toLowerCase()];return a?a(e):o}return e.fullPath}function I(e,o){const a=e.meta?.keepAlive;return typeof a=="boolean"?a:o}function K(e,o){const a=e.meta?.reuse;return typeof a=="boolean"?a:o}function J(e){const o=e.meta??{},a={};return"title"in o&&(a.title=o.title),"tips"in o&&(a.tips=o.tips),"icon"in o&&(a.icon=o.icon),"closable"in o&&(a.closable=o.closable),"tabClass"in o&&(a.tabClass=o.tabClass),"target"in o&&(a.target=o.target),"href"in o&&(a.href=o.href),a}function B(e,o,a){const n=J(e);return{id:R(e),to:e.fullPath,fullPath:e.fullPath,matched:e,alive:I(e,a),reusable:K(e,!1),closable:n.closable??!0,...n,...o}}function N(e,o,a,n){if(!e.find(b=>b.id===o.id)){if(a==="next"&&n){const b=e.findIndex(p=>p.id===n);if(b>-1){e.splice(b+1,0,o);return}}e.push(o)}}function H(e,o,a){if(!o||o<=0)return;const n=e.filter(c=>c.alive);for(;n.length>o;){const c=n.shift();if(!c||c.id===a)continue;const b=e.findIndex(p=>p.id===c.id);b>-1&&(e[b].alive=!1)}}function ne(e){return{to:e.to,title:e.title,tips:e.tips,icon:e.icon,tabClass:e.tabClass,closable:e.closable}}function oe(e){const o={};return"title"in e&&(o.title=e.title),"tips"in e&&(o.tips=e.tips),"icon"in e&&(o.icon=e.icon),"tabClass"in e&&(o.tabClass=e.tabClass),"closable"in e&&(o.closable=e.closable),o}function ie(e,o={}){const a=ee(o),n=t.reactive([]),c=t.ref(null),b=t.shallowRef(),p=t.ref(null),s=t.computed(()=>n.filter(l=>l.alive).map(l=>l.id));let f=!1;function T(l){const r=typeof l.matched=="object"?l:w(e,l);return{key:R(r),fullPath:r.fullPath,alive:I(r,a.keepAlive),reusable:K(r,!1),matched:r}}function A(l){const r=R(l);let u=n.find(m=>m.id===r);return u?(u.fullPath=l.fullPath,u.to=l.fullPath,u.matched=l,u.alive=I(l,a.keepAlive),u.reusable=K(l,u.reusable),Object.assign(u,J(l)),u):(u=B(l,{},a.keepAlive),N(n,u,a.appendPosition,c.value),H(n,a.maxAlive,c.value),u)}async function E(l,r=!1,u=!0){const m=w(e,l),C=R(m),i=c.value===C;u==="sameTab"&&(u=i),u&&await g(C,!0),await e[r?"replace":"push"](m),i&&await v()}function S(l){const r=n.findIndex(m=>m.id===l),u=n[r]||n[r-1]||n[0];return u?u.to:a.defaultRoute}async function P(l=c.value,r={}){if(l){if(!r.force&&a.keepLastTab&&n.length===1)throw new Error("[RouterTabs] Unable to close the final tab when keepLastTab is true.");if(await V(l,{force:r.force}),r.redirect!==null)if(c.value===l){const u=r.redirect??S(l);u&&await e.replace(u)}else r.redirect&&await e.replace(r.redirect)}}async function V(l,r={}){const u=n.findIndex(m=>m.id===l);u!==-1&&(n.splice(u,1),p.value===l&&(p.value=null),c.value===l&&(c.value=null,b.value=void 0))}async function g(l=c.value??void 0,r=!1){l&&(p.value=l,await t.nextTick(),r||await t.nextTick(),p.value=null)}async function D(l=!1){for(const r of n)await g(r.id,l)}async function O(l=a.defaultRoute){n.splice(0,n.length),c.value=null,b.value=void 0;for(const r of a.initialTabs){const u=w(e,r.to),m=B(u,r,a.keepAlive);n.push(m)}await e.replace(l)}async function v(){const l=c.value;l&&await g(l,!0)}function U(l){return typeof l.matched=="object"?R(l):R(w(e,l))}function F(){const l=n.find(r=>r.id===c.value);return{tabs:n.map(ne),active:l?l.to:null}}async function x(l){f=!0,n.splice(0,n.length),c.value=null,b.value=void 0;const r=l?.tabs??[];for(const m of r)try{const C=w(e,m.to),i=oe(m),d=B(C,i,a.keepAlive);N(n,d,"last",null)}catch{}f=!1;const u=l?.active??r[r.length-1]?.to??a.defaultRoute;if(u)try{await e.replace(u)}catch{}}return t.watch(()=>e.currentRoute.value,l=>{if(f)return;const r=A(l);c.value=r.id,b.value=r,H(n,a.maxAlive,c.value)},{immediate:!0}),a.initialTabs.length&&a.initialTabs.forEach(l=>{const r=w(e,l.to),u=B(r,l,a.keepAlive);N(n,u,"last",null)}),{options:a,tabs:n,activeId:c,current:b,includeKeys:s,refreshingKey:p,openTab:E,closeTab:P,removeTab:V,refreshTab:g,refreshAll:D,reset:O,reload:v,getRouteKey:U,matchRoute:T,snapshot:F,hydrate:x}}function Y(e){return e?typeof e=="string"?{name:e}:e:{}}const _=Symbol("RouterTabsContext"),ae="router-tabs:snapshot";function M(e={}){const{optional:o=!1}=e,a=t.inject(_,null);if(a)return a;const n=t.inject("$tabs",null);if(n)return n;const b=t.getCurrentInstance()?.appContext.config.globalProperties.$tabs;if(b)return b;if(!o)throw new Error("[RouterTabs] useRouterTabs must be used within <router-tab>.");return null}const le=864e5;function se(e){if(typeof document>"u")return null;const o=`${encodeURIComponent(e)}=`,a=document.cookie?document.cookie.split("; "):[];for(const n of a)if(n.startsWith(o))return decodeURIComponent(n.slice(o.length));return null}function W(e,o,a){if(typeof document>"u")return;const{expiresInDays:n=7,path:c="/",domain:b,secure:p,sameSite:s="lax"}=a,f=[`${encodeURIComponent(e)}=${encodeURIComponent(o)}`];if(n!==1/0){const T=new Date(Date.now()+n*le).toUTCString();f.push(`Expires=${T}`)}c&&f.push(`Path=${c}`),b&&f.push(`Domain=${b}`),p&&f.push("Secure"),s&&f.push(`SameSite=${s.charAt(0).toUpperCase()}${s.slice(1)}`),document.cookie=f.join("; ")}function X(e,o){if(typeof document>"u")return;const{path:a="/",domain:n}=o,c=[`${encodeURIComponent(e)}=`];c.push("Expires=Thu, 01 Jan 1970 00:00:01 GMT"),a&&c.push(`Path=${a}`),n&&c.push(`Domain=${n}`),document.cookie=c.join("; ")}const re=e=>JSON.stringify(e??null),ce=e=>{if(!e)return null;try{return JSON.parse(e)}catch{return null}};function L(e={}){const{cookieKey:o=ae,serialize:a=re,deserialize:n=ce}=e,c=M({optional:!0}),b=t.ref(!1),p=s=>{t.onMounted(async()=>{const f=n(se(o));if(f&&f.tabs?.length)try{b.value=!0,await s.hydrate(f)}finally{b.value=!1}else try{b.value=!0;const A=e.fallbackRoute??s.options.defaultRoute;await s.reset(A)}finally{b.value=!1}const T=s.snapshot();T.tabs.length?W(o,a(T),e):X(o,e)}),t.watch(()=>({tabs:s.tabs.map(f=>({to:f.to,title:f.title,tips:f.tips,icon:f.icon,tabClass:f.tabClass,closable:f.closable})),active:s.activeId.value}),()=>{if(b.value)return;const f=s.snapshot();f.tabs.length?W(o,a(f),e):X(o,e)},{deep:!0})};c?p(c):t.onMounted(()=>{const s=M({optional:!0});s&&p(s)})}const ue=t.defineComponent({name:"RouterTab",components:{RouterView:Z.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:null},persistence:{type:Object,default:null}},setup(e){const o=t.getCurrentInstance();if(!o)throw new Error("[RouterTab] component must be used within a Vue application context.");const a=o.appContext.app.config.globalProperties.$router;if(!a)throw new Error("[RouterTab] Vue Router is required. Make sure to call app.use(router) before RouterTab.");const n=ie(a,{initialTabs:e.tabs,keepAlive:e.keepAlive,maxAlive:e.maxAlive,keepLastTab:e.keepLastTab,appendPosition:e.append,defaultRoute:e.defaultPage});t.provide(_,n),o.appContext.config.globalProperties.$tabs=n;const c=t.computed(()=>!!o?.slots?.default);if(e.cookieKey||e.persistence){const i={...e.persistence??{}};e.cookieKey&&(i.cookieKey=e.cookieKey),L(i)}const b=t.computed(()=>Y(e.tabTransition)),p=t.computed(()=>Y(e.pageTransition)),s=t.reactive({visible:!1,target:null,position:{x:0,y:0}}),f=["refresh","refreshAll","close","closeLefts","closeRights","closeOthers"];function T(i){return n.tabs.findIndex(d=>d.id===i)}function A(i){const d=T(i.id);return d>0?n.tabs.slice(0,d):[]}function E(i){const d=T(i.id);return d>-1?n.tabs.slice(d+1):[]}function S(i){return n.tabs.filter(d=>d.id!==i.id)}async function P(i,d){const h=i.filter(k=>k.closable!==!1);if(h.length){for(const k of h)n.activeId.value===k.id?await n.closeTab(k.id,{redirect:d.to,force:!0}):await n.removeTab(k.id,{force:!0});n.activeId.value!==d.id&&await n.openTab(d.to,!0,!1)}}const V={refresh:{label:"Refresh",handler:async({target:i})=>{await n.refreshTab(i.id,!0)}},refreshAll:{label:"Refresh All",handler:async()=>{await n.refreshAll(!0)}},close:{label:"Close",handler:async({target:i})=>{await n.closeTab(i.id)},enable:({target:i})=>x(i)},closeLefts:{label:"Close to the Left",handler:async({target:i})=>{await P(A(i),i)},enable:({target:i})=>A(i).some(d=>d.closable!==!1)},closeRights:{label:"Close to the Right",handler:async({target:i})=>{await P(E(i),i)},enable:({target:i})=>E(i).some(d=>d.closable!==!1)},closeOthers:{label:"Close Others",handler:async({target:i})=>{await P(S(i),i)},enable:({target:i})=>S(i).some(d=>d.closable!==!1)}};function g(){s.visible=!1,s.target=null}function D(i,d){e.contextmenu&&(s.visible=!0,s.target=i,s.position.x=d.clientX,s.position.y=d.clientY,document.addEventListener("click",g,{once:!0}))}function O(i,d){const h=typeof i=="string"?{id:i}:i,k=V[h.id],Ae=h.label??k?.label??String(h.id),q=h.visible??k?.visible??!0;if(!(typeof q=="function"?q(d):q!==!1))return null;const G=h.enable??k?.enable??!0,_e=typeof G=="function"?G(d):G!==!1,Q=h.handler??k?.handler;if(!Q)return null;const Pe=async()=>{await Promise.resolve(Q(d))};return{id:String(h.id),label:Ae,disabled:!_e,action:Pe}}const v=t.computed(()=>{if(!s.visible||!s.target||e.contextmenu===!1)return[];const i=Array.isArray(e.contextmenu)?e.contextmenu:f,d={target:s.target,controller:n};return i.map(h=>O(h,d)).filter(h=>!!h)});async function U(i){i.disabled||(g(),await i.action())}function F(i){return typeof i.title=="string"?i.title:Array.isArray(i.title)&&i.title.length?String(i.title[0]):i.fullPath}function x(i){return!(i.closable===!1||n.options.keepLastTab&&n.tabs.length<=1)}async function l(i){await n.closeTab(i.id)}function r(i){n.activeId.value!==i.id&&n.openTab(i.to,!1)}function u(i){return["router-tab__item",{"is-active":n.activeId.value===i.id,"is-closable":x(i)},i.tabClass]}function m(i){return n.refreshingKey.value===n.getRouteKey(i)}t.onMounted(()=>{document.addEventListener("keydown",g)}),t.onBeforeUnmount(()=>{document.removeEventListener("keydown",g),o.appContext.config.globalProperties.$tabs=null}),t.watch(()=>e.keepAlive,i=>{n.options.keepAlive=i}),t.watch(()=>n.activeId.value,()=>g()),t.watch(()=>e.contextmenu,i=>{i||g()}),t.watch(()=>v.value.length,i=>{s.visible&&i===0&&g()});const C=n.includeKeys;return{controller:n,tabs:n.tabs,includeKeys:C,tabTransitionProps:b,pageTransitionProps:p,buildTabClass:u,activate:r,close:l,context:s,menuItems:v,handleMenuAction:U,showContextMenu:D,hideContextMenu:g,tabTitle:F,isClosable:x,isRefreshing:m,hasCustomSlot:c}}}),fe=(e,o)=>{const a=e.__vccOpts||e;for(const[n,c]of o)a[n]=c;return a},de={class:"router-tab"},be={class:"router-tab__header"},pe={class:"router-tab__slot-start"},me={class:"router-tab__scroll"},he=["onClick","onAuxclick","onContextmenu"],ye=["title"],ge=["onClick"],ke={class:"router-tab__slot-end"},Te={class:"router-tab__container"},Ce=["aria-disabled","onClick"];function we(e,o,a,n,c,b){const p=t.resolveComponent("RouterView");return t.openBlock(),t.createElementBlock("div",de,[t.createElementVNode("header",be,[t.createElementVNode("div",pe,[t.renderSlot(e.$slots,"start")]),t.createElementVNode("div",me,[t.createVNode(t.TransitionGroup,t.mergeProps({tag:"ul",class:"router-tab__nav"},e.tabTransitionProps),{default:t.withCtx(()=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(e.tabs,s=>(t.openBlock(),t.createElementBlock("li",{key:s.id,class:t.normalizeClass(e.buildTabClass(s)),onClick:f=>e.activate(s),onAuxclick:t.withModifiers(f=>e.close(s),["middle","prevent"]),onContextmenu:t.withModifiers(f=>e.showContextMenu(s,f),["prevent"])},[t.createElementVNode("span",{class:"router-tab__item-title",title:e.tabTitle(s)},[s.icon?(t.openBlock(),t.createElementBlock("i",{key:0,class:t.normalizeClass(["router-tab__item-icon",s.icon])},null,2)):t.createCommentVNode("",!0),t.createTextVNode(" "+t.toDisplayString(e.tabTitle(s)),1)],8,ye),e.isClosable(s)?(t.openBlock(),t.createElementBlock("a",{key:0,class:"router-tab__item-close",type:"button",onClick:t.withModifiers(f=>e.close(s),["stop"])},null,8,ge)):t.createCommentVNode("",!0)],42,he))),128))]),_:1},16)]),t.createElementVNode("div",ke,[t.renderSlot(e.$slots,"end")])]),t.createElementVNode("div",Te,[t.createVNode(p,null,{default:t.withCtx(s=>[e.hasCustomSlot?t.renderSlot(e.$slots,"default",t.normalizeProps(t.mergeProps({key:0},{...s,controller:e.controller}))):(t.openBlock(),t.createElementBlock(t.Fragment,{key:1},[t.createVNode(t.Transition,t.mergeProps(e.pageTransitionProps,{appear:""}),{default:t.withCtx(()=>[e.controller.options.keepAlive?(t.openBlock(),t.createBlock(t.KeepAlive,{key:0,include:e.includeKeys,max:e.controller.options.maxAlive||void 0},[e.isRefreshing(s.route)?t.createCommentVNode("",!0):(t.openBlock(),t.createBlock(t.resolveDynamicComponent(s.Component),{key:e.controller.getRouteKey(s.route),class:"router-tab-page"}))],1032,["include","max"])):t.createCommentVNode("",!0)]),_:2},1040),t.createVNode(t.Transition,t.mergeProps(e.pageTransitionProps,{appear:""}),{default:t.withCtx(()=>[!e.controller.options.keepAlive||e.isRefreshing(s.route)?(t.openBlock(),t.createBlock(t.resolveDynamicComponent(s.Component),{key:e.controller.getRouteKey(s.route)+(e.isRefreshing(s.route)?"-refresh":""),class:"router-tab-page"})):t.createCommentVNode("",!0)]),_:2},1040)],64))]),_:3})]),e.context.visible&&e.context.target?(t.openBlock(),t.createElementBlock("div",{key:0,class:"router-tab__contextmenu",style:t.normalizeStyle({left:e.context.position.x+"px",top:e.context.position.y+"px"})},[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(e.menuItems,s=>(t.openBlock(),t.createElementBlock("a",{key:s.id,class:"router-tab__contextmenu-item","aria-disabled":s.disabled,onClick:t.withModifiers(f=>e.handleMenuAction(s),["prevent"])},t.toDisplayString(s.label),9,Ce))),128))],4)):t.createCommentVNode("",!0)])}const j=fe(ue,[["render",we]]),Re={class:"router-tabs","aria-hidden":"true"},$=t.defineComponent({name:"RouterTabs",__name:"RouterTabs",props:{cookieKey:{},expiresInDays:{},path:{},domain:{},secure:{type:Boolean},sameSite:{},serialize:{type:Function},deserialize:{type:Function},fallbackRoute:{}},setup(e){return L(e),(a,n)=>(t.openBlock(),t.createElementBlock("span",Re))}}),z={install(e){if(z._installed)return;z._installed=!0;const o=j.name||"RouterTab",a=$.name||"RouterTabs";e.component(o,j),e.component(a,$),a!=="router-tabs"&&e.component("router-tabs",$),Object.defineProperty(e.config.globalProperties,"$tabs",{configurable:!0,enumerable:!1,get(){return e._context.provides[_]},set(n){n&&e.provide(_,n)}})}};y.RouterTab=j,y.RouterTabs=$,y.default=z,y.routerTabsKey=_,y.useRouterTabs=M,y.useRouterTabsPersistence=L,Object.defineProperties(y,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
1
+ (function(y,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue"),require("vue-router")):typeof define=="function"&&define.amd?define(["exports","vue","vue-router"],t):(y=typeof globalThis<"u"?globalThis:y||self,t(y["vue3-router-tab"]={},y.Vue,y.VueRouter))})(this,(function(y,t,ee){"use strict";function te(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 w(e,i){const a=e.resolve(i);if(!a||!a.matched.length)throw new Error(`[RouterTabs] Unable to resolve route: ${String(i)}`);return a}const ne={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 R(e){const i=e.meta?.key;if(typeof i=="function"){const a=i(e);if(typeof a=="string"&&a.length)return a}else if(typeof i=="string"&&i.length){const a=ne[i.toLowerCase()];return a?a(e):i}return e.fullPath}function I(e,i){const a=e.meta?.keepAlive;return typeof a=="boolean"?a:i}function N(e,i){const a=e.meta?.reuse;return typeof a=="boolean"?a:i}function H(e){const i=e.meta??{},a={};return"title"in i&&(a.title=i.title),"tips"in i&&(a.tips=i.tips),"icon"in i&&(a.icon=i.icon),"closable"in i&&(a.closable=i.closable),"tabClass"in i&&(a.tabClass=i.tabClass),"target"in i&&(a.target=i.target),"href"in i&&(a.href=i.href),a}function B(e,i,a){const n=H(e);return{id:R(e),to:e.fullPath,fullPath:e.fullPath,matched:e,alive:I(e,a),reusable:N(e,!1),closable:n.closable??!0,...n,...i}}function M(e,i,a,n){if(!e.find(b=>b.id===i.id)){if(a==="next"&&n){const b=e.findIndex(p=>p.id===n);if(b>-1){e.splice(b+1,0,i);return}}e.push(i)}}function Y(e,i,a){if(!i||i<=0)return;const n=e.filter(c=>c.alive);for(;n.length>i;){const c=n.shift();if(!c||c.id===a)continue;const b=e.findIndex(p=>p.id===c.id);b>-1&&(e[b].alive=!1)}}function oe(e){return{to:e.to,title:e.title,tips:e.tips,icon:e.icon,tabClass:e.tabClass,closable:e.closable}}function ie(e){const i={};return"title"in e&&(i.title=e.title),"tips"in e&&(i.tips=e.tips),"icon"in e&&(i.icon=e.icon),"tabClass"in e&&(i.tabClass=e.tabClass),"closable"in e&&(i.closable=e.closable),i}function ae(e,i={}){const a=te(i),n=t.reactive([]),c=t.ref(null),b=t.shallowRef(),p=t.ref(null),s=t.computed(()=>n.filter(l=>l.alive).map(l=>l.id));let f=!1;function T(l){const r=typeof l.matched=="object"?l:w(e,l);return{key:R(r),fullPath:r.fullPath,alive:I(r,a.keepAlive),reusable:N(r,!1),matched:r}}function A(l){const r=R(l);let u=n.find(m=>m.id===r);return u?(u.fullPath=l.fullPath,u.to=l.fullPath,u.matched=l,u.alive=I(l,a.keepAlive),u.reusable=N(l,u.reusable),Object.assign(u,H(l)),u):(u=B(l,{},a.keepAlive),M(n,u,a.appendPosition,c.value),Y(n,a.maxAlive,c.value),u)}async function K(l,r=!1,u=!0){const m=w(e,l),C=R(m),o=c.value===C;u==="sameTab"&&(u=o),u&&await k(C,!0),await e[r?"replace":"push"](m),o&&await P()}function S(l){const r=n.findIndex(m=>m.id===l),u=n[r]||n[r-1]||n[0];return u?u.to:a.defaultRoute}async function v(l=c.value,r={}){if(l){if(!r.force&&a.keepLastTab&&n.length===1)throw new Error("[RouterTabs] Unable to close the final tab when keepLastTab is true.");if(await V(l,{force:r.force}),r.redirect!==null)if(c.value===l){const u=r.redirect??S(l);u&&await e.replace(u)}else r.redirect&&await e.replace(r.redirect)}}async function V(l,r={}){const u=n.findIndex(m=>m.id===l);u!==-1&&(n.splice(u,1),p.value===l&&(p.value=null),c.value===l&&(c.value=null,b.value=void 0))}async function k(l=c.value??void 0,r=!1){l&&(p.value=l,await t.nextTick(),r||await t.nextTick(),p.value=null)}async function O(l=!1){for(const r of n)await k(r.id,l)}async function U(l=a.defaultRoute){n.splice(0,n.length),c.value=null,b.value=void 0;for(const r of a.initialTabs){const u=w(e,r.to),m=B(u,r,a.keepAlive);n.push(m)}await e.replace(l)}async function P(){const l=c.value;l&&await k(l,!0)}function F(l){return typeof l.matched=="object"?R(l):R(w(e,l))}function q(){const l=n.find(r=>r.id===c.value);return{tabs:n.map(oe),active:l?l.to:null}}async function x(l){f=!0,n.splice(0,n.length),c.value=null,b.value=void 0;const r=l?.tabs??[];for(const m of r)try{const C=w(e,m.to),o=ie(m),d=B(C,o,a.keepAlive);M(n,d,"last",null)}catch{}f=!1;const u=l?.active??r[r.length-1]?.to??a.defaultRoute;if(u)try{await e.replace(u)}catch{}}return t.watch(()=>e.currentRoute.value,l=>{if(f)return;const r=A(l);c.value=r.id,b.value=r,Y(n,a.maxAlive,c.value)},{immediate:!0}),a.initialTabs.length&&a.initialTabs.forEach(l=>{const r=w(e,l.to),u=B(r,l,a.keepAlive);M(n,u,"last",null)}),{options:a,tabs:n,activeId:c,current:b,includeKeys:s,refreshingKey:p,openTab:K,closeTab:v,removeTab:V,refreshTab:k,refreshAll:O,reset:U,reload:P,getRouteKey:F,matchRoute:T,snapshot:q,hydrate:x}}function W(e){return e?typeof e=="string"?{name:e}:e:{}}const _=Symbol("RouterTabsContext"),$="router-tabs:snapshot";function L(e={}){const{optional:i=!1}=e,a=t.inject(_,null);if(a)return a;const n=t.inject("$tabs",null);if(n)return n;const b=t.getCurrentInstance()?.appContext.config.globalProperties.$tabs;if(b)return b;if(!i)throw new Error("[RouterTabs] useRouterTabs must be used within <router-tab>.");return null}const le=864e5;function se(e){if(typeof document>"u")return null;const i=`${encodeURIComponent(e)}=`,a=document.cookie?document.cookie.split("; "):[];for(const n of a)if(n.startsWith(i))return decodeURIComponent(n.slice(i.length));return null}function X(e,i,a){if(typeof document>"u")return;const{expiresInDays:n=7,path:c="/",domain:b,secure:p,sameSite:s="lax"}=a,f=[`${encodeURIComponent(e)}=${encodeURIComponent(i)}`];if(n!==1/0){const T=new Date(Date.now()+n*le).toUTCString();f.push(`Expires=${T}`)}c&&f.push(`Path=${c}`),b&&f.push(`Domain=${b}`),p&&f.push("Secure"),s&&f.push(`SameSite=${s.charAt(0).toUpperCase()}${s.slice(1)}`),document.cookie=f.join("; ")}function Q(e,i){if(typeof document>"u")return;const{path:a="/",domain:n}=i,c=[`${encodeURIComponent(e)}=`];c.push("Expires=Thu, 01 Jan 1970 00:00:01 GMT"),a&&c.push(`Path=${a}`),n&&c.push(`Domain=${n}`),document.cookie=c.join("; ")}const re=e=>JSON.stringify(e??null),ce=e=>{if(!e)return null;try{return JSON.parse(e)}catch{return null}};function j(e={}){const{cookieKey:i=$,serialize:a=re,deserialize:n=ce}=e,c=L({optional:!0}),b=t.ref(!0),p=s=>{t.onMounted(async()=>{const f=n(se(i));if(f&&f.tabs?.length)try{b.value=!0,await s.hydrate(f)}finally{b.value=!1}else try{b.value=!0;const A=e.fallbackRoute??s.options.defaultRoute;await s.reset(A)}finally{b.value=!1}const T=s.snapshot();T.tabs.length?X(i,a(T),e):Q(i,e),b.value=!1}),t.watch(()=>({tabs:s.tabs.map(f=>({to:f.to,title:f.title,tips:f.tips,icon:f.icon,tabClass:f.tabClass,closable:f.closable})),active:s.activeId.value}),()=>{if(b.value)return;const f=s.snapshot();f.tabs.length?X(i,a(f),e):Q(i,e)},{deep:!0})};c?p(c):t.onMounted(()=>{const s=L({optional:!0});s&&p(s)})}const ue=t.defineComponent({name:"RouterTab",components:{RouterView:ee.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:$},persistence:{type:Object,default:null}},setup(e){const i=t.getCurrentInstance();if(!i)throw new Error("[RouterTab] component must be used within a Vue application context.");const a=i.appContext.app.config.globalProperties.$router;if(!a)throw new Error("[RouterTab] Vue Router is required. Make sure to call app.use(router) before RouterTab.");const n=ae(a,{initialTabs:e.tabs,keepAlive:e.keepAlive,maxAlive:e.maxAlive,keepLastTab:e.keepLastTab,appendPosition:e.append,defaultRoute:e.defaultPage});t.provide(_,n),i.appContext.config.globalProperties.$tabs=n;const c=t.computed(()=>!!i?.slots?.default);if(e.cookieKey!==null||e.persistence){const o={...e.persistence??{}};e.cookieKey!==null?o.cookieKey=e.cookieKey||$:o.cookieKey||(o.cookieKey=$),j(o)}const b=t.computed(()=>W(e.tabTransition)),p=t.computed(()=>W(e.pageTransition)),s=t.reactive({visible:!1,target:null,position:{x:0,y:0}}),f=["refresh","refreshAll","close","closeLefts","closeRights","closeOthers"];function T(o){return n.tabs.findIndex(d=>d.id===o)}function A(o){const d=T(o.id);return d>0?n.tabs.slice(0,d):[]}function K(o){const d=T(o.id);return d>-1?n.tabs.slice(d+1):[]}function S(o){return n.tabs.filter(d=>d.id!==o.id)}async function v(o,d){const h=o.filter(g=>g.closable!==!1);if(h.length){for(const g of h)n.activeId.value===g.id?await n.closeTab(g.id,{redirect:d.to,force:!0}):await n.removeTab(g.id,{force:!0});n.activeId.value!==d.id&&await n.openTab(d.to,!0,!1)}}const V={refresh:{label:"Refresh",handler:async({target:o})=>{await n.refreshTab(o.id,!0)}},refreshAll:{label:"Refresh All",handler:async()=>{await n.refreshAll(!0)}},close:{label:"Close",handler:async({target:o})=>{await n.closeTab(o.id)},enable:({target:o})=>x(o)},closeLefts:{label:"Close to the Left",handler:async({target:o})=>{await v(A(o),o)},enable:({target:o})=>A(o).some(d=>d.closable!==!1)},closeRights:{label:"Close to the Right",handler:async({target:o})=>{await v(K(o),o)},enable:({target:o})=>K(o).some(d=>d.closable!==!1)},closeOthers:{label:"Close Others",handler:async({target:o})=>{await v(S(o),o)},enable:({target:o})=>S(o).some(d=>d.closable!==!1)}};function k(){s.visible=!1,s.target=null}function O(o,d){e.contextmenu&&(s.visible=!0,s.target=o,s.position.x=d.clientX,s.position.y=d.clientY,document.addEventListener("click",k,{once:!0}))}function U(o,d){const h=typeof o=="string"?{id:o}:o,g=V[h.id],Ae=h.label??g?.label??String(h.id),G=h.visible??g?.visible??!0;if(!(typeof G=="function"?G(d):G!==!1))return null;const J=h.enable??g?.enable??!0,_e=typeof J=="function"?J(d):J!==!1,Z=h.handler??g?.handler;if(!Z)return null;const ve=async()=>{await Promise.resolve(Z(d))};return{id:String(h.id),label:Ae,disabled:!_e,action:ve}}const P=t.computed(()=>{if(!s.visible||!s.target||e.contextmenu===!1)return[];const o=Array.isArray(e.contextmenu)?e.contextmenu:f,d={target:s.target,controller:n};return o.map(h=>U(h,d)).filter(h=>!!h)});async function F(o){o.disabled||(k(),await o.action())}function q(o){return typeof o.title=="string"?o.title:Array.isArray(o.title)&&o.title.length?String(o.title[0]):o.fullPath}function x(o){return!(o.closable===!1||n.options.keepLastTab&&n.tabs.length<=1)}async function l(o){await n.closeTab(o.id)}function r(o){n.activeId.value!==o.id&&n.openTab(o.to,!1)}function u(o){return["router-tab__item",{"is-active":n.activeId.value===o.id,"is-closable":x(o)},o.tabClass]}function m(o){return n.refreshingKey.value===n.getRouteKey(o)}t.onMounted(()=>{document.addEventListener("keydown",k)}),t.onBeforeUnmount(()=>{document.removeEventListener("keydown",k),i.appContext.config.globalProperties.$tabs=null}),t.watch(()=>e.keepAlive,o=>{n.options.keepAlive=o}),t.watch(()=>n.activeId.value,()=>k()),t.watch(()=>e.contextmenu,o=>{o||k()}),t.watch(()=>P.value.length,o=>{s.visible&&o===0&&k()});const C=n.includeKeys;return{controller:n,tabs:n.tabs,includeKeys:C,tabTransitionProps:b,pageTransitionProps:p,buildTabClass:u,activate:r,close:l,context:s,menuItems:P,handleMenuAction:F,showContextMenu:O,hideContextMenu:k,tabTitle:q,isClosable:x,isRefreshing:m,hasCustomSlot:c}}}),fe=(e,i)=>{const a=e.__vccOpts||e;for(const[n,c]of i)a[n]=c;return a},de={class:"router-tab"},be={class:"router-tab__header"},pe={class:"router-tab__slot-start"},me={class:"router-tab__scroll"},he=["onClick","onAuxclick","onContextmenu"],ye=["title"],ke=["onClick"],ge={class:"router-tab__slot-end"},Te={class:"router-tab__container"},Ce=["aria-disabled","onClick"];function we(e,i,a,n,c,b){const p=t.resolveComponent("RouterView");return t.openBlock(),t.createElementBlock("div",de,[t.createElementVNode("header",be,[t.createElementVNode("div",pe,[t.renderSlot(e.$slots,"start")]),t.createElementVNode("div",me,[t.createVNode(t.TransitionGroup,t.mergeProps({tag:"ul",class:"router-tab__nav"},e.tabTransitionProps),{default:t.withCtx(()=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(e.tabs,s=>(t.openBlock(),t.createElementBlock("li",{key:s.id,class:t.normalizeClass(e.buildTabClass(s)),onClick:f=>e.activate(s),onAuxclick:t.withModifiers(f=>e.close(s),["middle","prevent"]),onContextmenu:t.withModifiers(f=>e.showContextMenu(s,f),["prevent"])},[t.createElementVNode("span",{class:"router-tab__item-title",title:e.tabTitle(s)},[s.icon?(t.openBlock(),t.createElementBlock("i",{key:0,class:t.normalizeClass(["router-tab__item-icon",s.icon])},null,2)):t.createCommentVNode("",!0),t.createTextVNode(" "+t.toDisplayString(e.tabTitle(s)),1)],8,ye),e.isClosable(s)?(t.openBlock(),t.createElementBlock("a",{key:0,class:"router-tab__item-close",type:"button",onClick:t.withModifiers(f=>e.close(s),["stop"])},null,8,ke)):t.createCommentVNode("",!0)],42,he))),128))]),_:1},16)]),t.createElementVNode("div",ge,[t.renderSlot(e.$slots,"end")])]),t.createElementVNode("div",Te,[t.createVNode(p,null,{default:t.withCtx(s=>[e.hasCustomSlot?t.renderSlot(e.$slots,"default",t.normalizeProps(t.mergeProps({key:0},{...s,controller:e.controller}))):(t.openBlock(),t.createElementBlock(t.Fragment,{key:1},[t.createVNode(t.Transition,t.mergeProps(e.pageTransitionProps,{appear:""}),{default:t.withCtx(()=>[e.controller.options.keepAlive?(t.openBlock(),t.createBlock(t.KeepAlive,{key:0,include:e.includeKeys,max:e.controller.options.maxAlive||void 0},[e.isRefreshing(s.route)?t.createCommentVNode("",!0):(t.openBlock(),t.createBlock(t.resolveDynamicComponent(s.Component),{key:e.controller.getRouteKey(s.route),class:"router-tab-page"}))],1032,["include","max"])):t.createCommentVNode("",!0)]),_:2},1040),t.createVNode(t.Transition,t.mergeProps(e.pageTransitionProps,{appear:""}),{default:t.withCtx(()=>[!e.controller.options.keepAlive||e.isRefreshing(s.route)?(t.openBlock(),t.createBlock(t.resolveDynamicComponent(s.Component),{key:e.controller.getRouteKey(s.route)+(e.isRefreshing(s.route)?"-refresh":""),class:"router-tab-page"})):t.createCommentVNode("",!0)]),_:2},1040)],64))]),_:3})]),e.context.visible&&e.context.target?(t.openBlock(),t.createElementBlock("div",{key:0,class:"router-tab__contextmenu",style:t.normalizeStyle({left:e.context.position.x+"px",top:e.context.position.y+"px"})},[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(e.menuItems,s=>(t.openBlock(),t.createElementBlock("a",{key:s.id,class:"router-tab__contextmenu-item","aria-disabled":s.disabled,onClick:t.withModifiers(f=>e.handleMenuAction(s),["prevent"])},t.toDisplayString(s.label),9,Ce))),128))],4)):t.createCommentVNode("",!0)])}const z=fe(ue,[["render",we]]),Re={class:"router-tabs","aria-hidden":"true"},E=t.defineComponent({name:"RouterTabs",__name:"RouterTabs",props:{cookieKey:{},expiresInDays:{},path:{},domain:{},secure:{type:Boolean},sameSite:{},serialize:{type:Function},deserialize:{type:Function},fallbackRoute:{}},setup(e){return j(e),(a,n)=>(t.openBlock(),t.createElementBlock("span",Re))}}),D={install(e){if(D._installed)return;D._installed=!0;const i=z.name||"RouterTab",a=E.name||"RouterTabs";e.component(i,z),e.component(a,E),a!=="router-tabs"&&e.component("router-tabs",E),Object.defineProperty(e.config.globalProperties,"$tabs",{configurable:!0,enumerable:!1,get(){return e._context.provides[_]},set(n){n&&e.provide(_,n)}})}};y.RouterTab=z,y.RouterTabs=E,y.default=D,y.routerTabsKey=_,y.useRouterTabs=L,y.useRouterTabsPersistence=j,Object.defineProperties(y,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
package/index.d.ts ADDED
@@ -0,0 +1,96 @@
1
+ import type { App, Plugin, DefineComponent, PropType } from 'vue'
2
+ import type { RouteLocationRaw } from 'vue-router'
3
+ import type {
4
+ TabRecord,
5
+ TabInput,
6
+ RouterTabsOptions,
7
+ CloseTabOptions,
8
+ RouterTabsContext,
9
+ RouterTabsMenuConfig,
10
+ RouterTabsMenuItem,
11
+ RouterTabsMenuPreset,
12
+ RouterTabsSnapshot,
13
+ RouterTabsSnapshotTab,
14
+ RouterTabsPersistenceOptions
15
+ } from './lib/core/types'
16
+
17
+ export type {
18
+ TabRecord,
19
+ TabInput,
20
+ RouterTabsOptions,
21
+ CloseTabOptions,
22
+ RouterTabsContext,
23
+ RouterTabsMenuConfig,
24
+ RouterTabsMenuItem,
25
+ RouterTabsMenuPreset,
26
+ RouterTabsSnapshot,
27
+ RouterTabsSnapshotTab,
28
+ RouterTabsPersistenceOptions
29
+ }
30
+
31
+ export declare const routerTabsKey: import('vue').InjectionKey<RouterTabsContext>
32
+
33
+ export declare function useRouterTabs(options?: { optional?: boolean }): RouterTabsContext | null
34
+
35
+ export declare function useRouterTabsPersistence(options?: RouterTabsPersistenceOptions): void
36
+
37
+ export declare const RouterTabs: DefineComponent<RouterTabsPersistenceOptions, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, Readonly<RouterTabsPersistenceOptions>, {}>
38
+
39
+ export declare const RouterTab: DefineComponent<{
40
+ tabs: {
41
+ type: PropType<TabInput[]>
42
+ default: () => TabInput[]
43
+ }
44
+ keepAlive: BooleanConstructor
45
+ maxAlive: NumberConstructor
46
+ keepLastTab: BooleanConstructor
47
+ append: PropType<'last' | 'next'>
48
+ defaultPage: PropType<RouteLocationRaw>
49
+ tabTransition: PropType<import('./lib/core/types').TransitionLike>
50
+ pageTransition: PropType<import('./lib/core/types').TransitionLike>
51
+ contextmenu: PropType<boolean | RouterTabsMenuConfig[]>
52
+ cookieKey: StringConstructor
53
+ persistence: PropType<RouterTabsPersistenceOptions | null>
54
+ }, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, Record<string, any>, string, import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, Readonly<{
55
+ tabs?: TabInput[] | undefined
56
+ keepAlive?: boolean | undefined
57
+ maxAlive?: number | undefined
58
+ keepLastTab?: boolean | undefined
59
+ append?: 'last' | 'next' | undefined
60
+ defaultPage?: RouteLocationRaw | undefined
61
+ tabTransition?: import('./lib/core/types').TransitionLike | undefined
62
+ pageTransition?: import('./lib/core/types').TransitionLike | undefined
63
+ contextmenu?: boolean | RouterTabsMenuConfig[] | undefined
64
+ cookieKey?: string | undefined
65
+ persistence?: RouterTabsPersistenceOptions | null | undefined
66
+ }> & {
67
+ tabs?: TabInput[] | undefined
68
+ keepAlive?: boolean | undefined
69
+ maxAlive?: number | undefined
70
+ keepLastTab?: boolean | undefined
71
+ append?: 'last' | 'next' | undefined
72
+ defaultPage?: RouteLocationRaw | undefined
73
+ tabTransition?: import('./lib/core/types').TransitionLike | undefined
74
+ pageTransition?: import('./lib/core/types').TransitionLike | undefined
75
+ contextmenu?: boolean | RouterTabsMenuConfig[] | undefined
76
+ cookieKey?: string | undefined
77
+ persistence?: RouterTabsPersistenceOptions | null | undefined
78
+ }, {
79
+ tabs: TabInput[]
80
+ keepAlive: boolean
81
+ maxAlive: number
82
+ keepLastTab: boolean
83
+ append: 'last' | 'next'
84
+ defaultPage: RouteLocationRaw
85
+ tabTransition: import('./lib/core/types').TransitionLike
86
+ pageTransition: import('./lib/core/types').TransitionLike
87
+ contextmenu: boolean | RouterTabsMenuConfig[]
88
+ cookieKey: string
89
+ persistence: RouterTabsPersistenceOptions | null
90
+ }>
91
+
92
+ export interface RouterTabPlugin extends Plugin {}
93
+
94
+ declare const plugin: RouterTabPlugin
95
+
96
+ export default plugin
@@ -121,7 +121,7 @@ import type {
121
121
  TransitionLike
122
122
  } from '../core/types'
123
123
  import { getTransOpt } from '../util/index'
124
- import { routerTabsKey } from '../constants'
124
+ import { routerTabsKey, routerTabsCookie } from '../constants'
125
125
  import { useRouterTabsPersistence } from '../persistence'
126
126
 
127
127
 
@@ -174,7 +174,7 @@ export default defineComponent({
174
174
  },
175
175
  cookieKey: {
176
176
  type: String,
177
- default: null
177
+ default: routerTabsCookie
178
178
  },
179
179
  persistence: {
180
180
  type: Object as PropType<RouterTabsPersistenceOptions | null>,
@@ -206,11 +206,15 @@ export default defineComponent({
206
206
 
207
207
  const hasCustomSlot = computed(() => Boolean(instance?.slots?.default))
208
208
 
209
- if (props.cookieKey || props.persistence) {
209
+ if (props.cookieKey !== null || props.persistence) {
210
210
  const options: RouterTabsPersistenceOptions = {
211
211
  ...(props.persistence ?? {})
212
212
  }
213
- if (props.cookieKey) options.cookieKey = props.cookieKey
213
+ if (props.cookieKey !== null) {
214
+ options.cookieKey = props.cookieKey || routerTabsCookie
215
+ } else if (!options.cookieKey) {
216
+ options.cookieKey = routerTabsCookie
217
+ }
214
218
  useRouterTabsPersistence(options)
215
219
  }
216
220
 
@@ -98,7 +98,7 @@ export function useRouterTabsPersistence(options: RouterTabsPersistenceOptions =
98
98
  } = options
99
99
 
100
100
  const controller = useRouterTabs({ optional: true })
101
- const hydrating = ref(false)
101
+ const hydrating = ref(true)
102
102
 
103
103
  const setup = (ctrl: NonNullable<typeof controller>) => {
104
104
  onMounted(async () => {
@@ -127,6 +127,8 @@ export function useRouterTabsPersistence(options: RouterTabsPersistenceOptions =
127
127
  } else {
128
128
  writeCookie(cookieKey, serialize(snapshot), options)
129
129
  }
130
+
131
+ hydrating.value = false
130
132
  })
131
133
 
132
134
  watch(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue3-router-tab",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",