vue3-router-tab 1.0.3 → 1.0.5
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,36 +1,36 @@
|
|
|
1
1
|
import './vue3-router-tab.css';
|
|
2
|
-
import { defineComponent as
|
|
3
|
-
import { defineStore as
|
|
2
|
+
import { defineComponent as ae, inject as z, computed as S, unref as Ve, provide as U, ref as J, watch as x, h as Ie, getCurrentInstance as se, reactive as _e, shallowRef as Ke, nextTick as re, onMounted as Ae, onBeforeUnmount as Ne, resolveComponent as $e, createElementBlock as A, openBlock as T, createElementVNode as I, createCommentVNode as K, renderSlot as le, createVNode as j, TransitionGroup as Le, mergeProps as Q, withCtx as M, Fragment as ce, renderList as ue, withModifiers as B, normalizeClass as fe, createTextVNode as De, toDisplayString as de, Transition as pe, createBlock as W, KeepAlive as je, resolveDynamicComponent as be, normalizeStyle as Me } from "vue";
|
|
3
|
+
import { defineStore as Be } from "pinia";
|
|
4
4
|
/*!
|
|
5
5
|
* vue-router v4.5.1
|
|
6
6
|
* (c) 2025 Eduardo San Martin Morote
|
|
7
7
|
* @license MIT
|
|
8
8
|
*/
|
|
9
|
-
const
|
|
10
|
-
function
|
|
9
|
+
const Ge = typeof document < "u", Ue = Object.assign, ze = Array.isArray;
|
|
10
|
+
function Je(e) {
|
|
11
11
|
const n = Array.from(arguments).slice(1);
|
|
12
12
|
console.warn.apply(console, ["[Vue Router warn]: " + e].concat(n));
|
|
13
13
|
}
|
|
14
|
-
function
|
|
14
|
+
function He(e, n) {
|
|
15
15
|
return (e.aliasOf || e) === (n.aliasOf || n);
|
|
16
16
|
}
|
|
17
|
-
var
|
|
17
|
+
var ve;
|
|
18
18
|
(function(e) {
|
|
19
19
|
e.pop = "pop", e.push = "push";
|
|
20
|
-
})(
|
|
21
|
-
var
|
|
20
|
+
})(ve || (ve = {}));
|
|
21
|
+
var he;
|
|
22
22
|
(function(e) {
|
|
23
23
|
e.back = "back", e.forward = "forward", e.unknown = "";
|
|
24
|
-
})(
|
|
24
|
+
})(he || (he = {}));
|
|
25
25
|
Symbol(process.env.NODE_ENV !== "production" ? "navigation failure" : "");
|
|
26
|
-
var
|
|
26
|
+
var me;
|
|
27
27
|
(function(e) {
|
|
28
28
|
e[e.aborted = 4] = "aborted", e[e.cancelled = 8] = "cancelled", e[e.duplicated = 16] = "duplicated";
|
|
29
|
-
})(
|
|
30
|
-
const
|
|
29
|
+
})(me || (me = {}));
|
|
30
|
+
const qe = Symbol(process.env.NODE_ENV !== "production" ? "router view location matched" : ""), ye = Symbol(process.env.NODE_ENV !== "production" ? "router view depth" : "");
|
|
31
31
|
Symbol(process.env.NODE_ENV !== "production" ? "router" : "");
|
|
32
32
|
Symbol(process.env.NODE_ENV !== "production" ? "route location" : "");
|
|
33
|
-
const
|
|
33
|
+
const ge = Symbol(process.env.NODE_ENV !== "production" ? "router view location" : ""), Xe = /* @__PURE__ */ ae({
|
|
34
34
|
name: "RouterView",
|
|
35
35
|
// #674 we manually inherit them
|
|
36
36
|
inheritAttrs: !1,
|
|
@@ -45,62 +45,62 @@ const ye = Symbol(process.env.NODE_ENV !== "production" ? "router view location"
|
|
|
45
45
|
// https://github.com/vuejs/router/issues/1315
|
|
46
46
|
compatConfig: { MODE: 3 },
|
|
47
47
|
setup(e, { attrs: n, slots: a }) {
|
|
48
|
-
process.env.NODE_ENV !== "production" &&
|
|
49
|
-
const t = z(
|
|
50
|
-
let h =
|
|
51
|
-
const { matched: b } =
|
|
48
|
+
process.env.NODE_ENV !== "production" && Fe();
|
|
49
|
+
const t = z(ge), i = S(() => e.route || t.value), u = z(ye, 0), d = S(() => {
|
|
50
|
+
let h = Ve(u);
|
|
51
|
+
const { matched: b } = i.value;
|
|
52
52
|
let m;
|
|
53
53
|
for (; (m = b[h]) && !m.components; )
|
|
54
54
|
h++;
|
|
55
55
|
return h;
|
|
56
|
-
}), f = S(() =>
|
|
57
|
-
U(
|
|
56
|
+
}), f = S(() => i.value.matched[d.value]);
|
|
57
|
+
U(ye, S(() => d.value + 1)), U(qe, f), U(ge, i);
|
|
58
58
|
const p = J();
|
|
59
59
|
return x(() => [p.value, f.value, e.name], ([h, b, m], [k, y, C]) => {
|
|
60
60
|
b && (b.instances[m] = h, y && y !== b && h && h === k && (b.leaveGuards.size || (b.leaveGuards = y.leaveGuards), b.updateGuards.size || (b.updateGuards = y.updateGuards))), h && b && // if there is no instance but to and from are the same this might be
|
|
61
61
|
// the first visit
|
|
62
|
-
(!y || !
|
|
62
|
+
(!y || !He(b, y) || !k) && (b.enterCallbacks[m] || []).forEach((_) => _(h));
|
|
63
63
|
}, { flush: "post" }), () => {
|
|
64
|
-
const h =
|
|
64
|
+
const h = i.value, b = e.name, m = f.value, k = m && m.components[b];
|
|
65
65
|
if (!k)
|
|
66
|
-
return
|
|
67
|
-
const y = m.props[b], C = y ? y === !0 ? h.params : typeof y == "function" ? y(h) : y : null, g =
|
|
66
|
+
return we(a.default, { Component: k, route: h });
|
|
67
|
+
const y = m.props[b], C = y ? y === !0 ? h.params : typeof y == "function" ? y(h) : y : null, g = Ie(k, Ue({}, C, n, {
|
|
68
68
|
onVnodeUnmounted: (E) => {
|
|
69
69
|
E.component.isUnmounted && (m.instances[b] = null);
|
|
70
70
|
},
|
|
71
71
|
ref: p
|
|
72
72
|
}));
|
|
73
|
-
if (process.env.NODE_ENV !== "production" &&
|
|
73
|
+
if (process.env.NODE_ENV !== "production" && Ge && g.ref) {
|
|
74
74
|
const E = {
|
|
75
75
|
depth: d.value,
|
|
76
76
|
name: m.name,
|
|
77
77
|
path: m.path,
|
|
78
78
|
meta: m.meta
|
|
79
79
|
};
|
|
80
|
-
(
|
|
80
|
+
(ze(g.ref) ? g.ref.map((P) => P.i) : [g.ref.i]).forEach((P) => {
|
|
81
81
|
P.__vrv_devtools = E;
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
84
|
return (
|
|
85
85
|
// pass the vnode to the slot as a prop.
|
|
86
86
|
// h and <component :is="..."> both accept vnodes
|
|
87
|
-
|
|
87
|
+
we(a.default, { Component: g, route: h }) || g
|
|
88
88
|
);
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
});
|
|
92
|
-
function
|
|
92
|
+
function we(e, n) {
|
|
93
93
|
if (!e)
|
|
94
94
|
return null;
|
|
95
95
|
const a = e(n);
|
|
96
96
|
return a.length === 1 ? a[0] : a;
|
|
97
97
|
}
|
|
98
|
-
const
|
|
99
|
-
function
|
|
100
|
-
const e =
|
|
98
|
+
const Ye = Xe;
|
|
99
|
+
function Fe() {
|
|
100
|
+
const e = se(), n = e.parent && e.parent.type.name, a = e.parent && e.parent.subTree && e.parent.subTree.type;
|
|
101
101
|
if (n && (n === "KeepAlive" || n.includes("Transition")) && typeof a == "object" && a.name === "RouterView") {
|
|
102
102
|
const t = n === "KeepAlive" ? "keep-alive" : "transition";
|
|
103
|
-
|
|
103
|
+
Je(`<router-view> can no longer be used directly inside <transition> or <keep-alive>.
|
|
104
104
|
Use slot props instead:
|
|
105
105
|
|
|
106
106
|
<router-view v-slot="{ Component }">
|
|
@@ -110,7 +110,7 @@ Use slot props instead:
|
|
|
110
110
|
</router-view>`);
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
|
-
function
|
|
113
|
+
function Qe(e = {}) {
|
|
114
114
|
return {
|
|
115
115
|
initialTabs: e.initialTabs ?? [],
|
|
116
116
|
keepAlive: e.keepAlive ?? !0,
|
|
@@ -126,7 +126,7 @@ function N(e, n) {
|
|
|
126
126
|
throw new Error(`[RouterTabs] Unable to resolve route: ${String(n)}`);
|
|
127
127
|
return a;
|
|
128
128
|
}
|
|
129
|
-
const
|
|
129
|
+
const We = {
|
|
130
130
|
path: (e) => e.path,
|
|
131
131
|
fullpath: (e) => e.fullPath,
|
|
132
132
|
fullname: (e) => e.fullPath,
|
|
@@ -139,32 +139,32 @@ function $(e) {
|
|
|
139
139
|
const a = n(e);
|
|
140
140
|
if (typeof a == "string" && a.length) return a;
|
|
141
141
|
} else if (typeof n == "string" && n.length) {
|
|
142
|
-
const a =
|
|
142
|
+
const a = We[n.toLowerCase()];
|
|
143
143
|
return a ? a(e) : n;
|
|
144
144
|
}
|
|
145
145
|
return e.fullPath;
|
|
146
146
|
}
|
|
147
|
-
function
|
|
147
|
+
function ne(e, n) {
|
|
148
148
|
const a = e.meta?.keepAlive;
|
|
149
149
|
return typeof a == "boolean" ? a : n;
|
|
150
150
|
}
|
|
151
|
-
function
|
|
151
|
+
function oe(e, n) {
|
|
152
152
|
const a = e.meta?.reuse;
|
|
153
153
|
return typeof a == "boolean" ? a : n;
|
|
154
154
|
}
|
|
155
|
-
function
|
|
155
|
+
function Se(e) {
|
|
156
156
|
const n = e.meta ?? {}, a = {};
|
|
157
157
|
return "title" in n && (a.title = n.title), "tips" in n && (a.tips = n.tips), "icon" in n && (a.icon = n.icon), "closable" in n && (a.closable = n.closable), "tabClass" in n && (a.tabClass = n.tabClass), "target" in n && (a.target = n.target), "href" in n && (a.href = n.href), a;
|
|
158
158
|
}
|
|
159
159
|
function G(e, n, a) {
|
|
160
|
-
const t =
|
|
160
|
+
const t = Se(e);
|
|
161
161
|
return {
|
|
162
162
|
id: $(e),
|
|
163
163
|
to: e.fullPath,
|
|
164
164
|
fullPath: e.fullPath,
|
|
165
165
|
matched: e,
|
|
166
|
-
alive:
|
|
167
|
-
reusable:
|
|
166
|
+
alive: ne(e, a),
|
|
167
|
+
reusable: oe(e, !1),
|
|
168
168
|
closable: t.closable ?? !0,
|
|
169
169
|
...t,
|
|
170
170
|
...n
|
|
@@ -182,17 +182,17 @@ function Z(e, n, a, t) {
|
|
|
182
182
|
e.push(n);
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
function
|
|
185
|
+
function Te(e, n, a) {
|
|
186
186
|
if (!n || n <= 0) return;
|
|
187
|
-
const t = e.filter((
|
|
187
|
+
const t = e.filter((i) => i.alive);
|
|
188
188
|
for (; t.length > n; ) {
|
|
189
|
-
const
|
|
190
|
-
if (!
|
|
191
|
-
const u = e.findIndex((d) => d.id ===
|
|
189
|
+
const i = t.shift();
|
|
190
|
+
if (!i || i.id === a) continue;
|
|
191
|
+
const u = e.findIndex((d) => d.id === i.id);
|
|
192
192
|
u > -1 && (e[u].alive = !1);
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
|
-
function
|
|
195
|
+
function Ze(e) {
|
|
196
196
|
return {
|
|
197
197
|
to: e.to,
|
|
198
198
|
title: e.title,
|
|
@@ -202,91 +202,91 @@ function We(e) {
|
|
|
202
202
|
closable: e.closable
|
|
203
203
|
};
|
|
204
204
|
}
|
|
205
|
-
function
|
|
205
|
+
function et(e) {
|
|
206
206
|
const n = {};
|
|
207
207
|
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;
|
|
208
208
|
}
|
|
209
|
-
function
|
|
210
|
-
const a =
|
|
209
|
+
function tt(e, n = {}) {
|
|
210
|
+
const a = Qe(n), t = _e([]), i = J(null), u = Ke(), d = J(null), f = S(() => t.filter((s) => s.alive).map((s) => s.id));
|
|
211
211
|
let p = !1;
|
|
212
|
-
function h(
|
|
213
|
-
const
|
|
212
|
+
function h(s) {
|
|
213
|
+
const r = typeof s.matched == "object" ? s : N(e, s);
|
|
214
214
|
return {
|
|
215
|
-
key: $(
|
|
216
|
-
fullPath:
|
|
217
|
-
alive:
|
|
218
|
-
reusable:
|
|
219
|
-
matched:
|
|
215
|
+
key: $(r),
|
|
216
|
+
fullPath: r.fullPath,
|
|
217
|
+
alive: ne(r, a.keepAlive),
|
|
218
|
+
reusable: oe(r, !1),
|
|
219
|
+
matched: r
|
|
220
220
|
};
|
|
221
221
|
}
|
|
222
|
-
function b(
|
|
223
|
-
const
|
|
224
|
-
let l = t.find((w) => w.id ===
|
|
225
|
-
return l ? (l.fullPath =
|
|
222
|
+
function b(s) {
|
|
223
|
+
const r = $(s);
|
|
224
|
+
let l = t.find((w) => w.id === r);
|
|
225
|
+
return l ? (l.fullPath = s.fullPath, l.to = s.fullPath, l.matched = s, l.alive = ne(s, a.keepAlive), l.reusable = oe(s, l.reusable), Object.assign(l, Se(s)), l) : (l = G(s, {}, a.keepAlive), Z(t, l, a.appendPosition, i.value), Te(t, a.maxAlive, i.value), l);
|
|
226
226
|
}
|
|
227
|
-
async function m(
|
|
228
|
-
const w = N(e,
|
|
229
|
-
l === "sameTab" && (l = V), l && await _(O, !0), await e[
|
|
227
|
+
async function m(s, r = !1, l = !0) {
|
|
228
|
+
const w = N(e, s), O = $(w), V = i.value === O;
|
|
229
|
+
l === "sameTab" && (l = V), l && await _(O, !0), await e[r ? "replace" : "push"](w), V && await L();
|
|
230
230
|
}
|
|
231
|
-
function k(
|
|
232
|
-
const
|
|
231
|
+
function k(s) {
|
|
232
|
+
const r = t.findIndex((w) => w.id === s), l = t[r] || t[r - 1] || t[0];
|
|
233
233
|
return l ? l.to : a.defaultRoute;
|
|
234
234
|
}
|
|
235
|
-
async function y(
|
|
236
|
-
if (
|
|
237
|
-
if (!
|
|
235
|
+
async function y(s = i.value, r = {}) {
|
|
236
|
+
if (s) {
|
|
237
|
+
if (!r.force && a.keepLastTab && t.length === 1)
|
|
238
238
|
throw new Error("[RouterTabs] Unable to close the final tab when keepLastTab is true.");
|
|
239
|
-
if (await C(
|
|
240
|
-
if (
|
|
241
|
-
const l =
|
|
239
|
+
if (await C(s, { force: r.force }), r.redirect !== null)
|
|
240
|
+
if (i.value === s) {
|
|
241
|
+
const l = r.redirect ?? k(s);
|
|
242
242
|
l && await e.replace(l);
|
|
243
|
-
} else
|
|
243
|
+
} else r.redirect && await e.replace(r.redirect);
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
|
-
async function C(
|
|
247
|
-
const l = t.findIndex((w) => w.id ===
|
|
248
|
-
l !== -1 && (t.splice(l, 1), d.value ===
|
|
246
|
+
async function C(s, r = {}) {
|
|
247
|
+
const l = t.findIndex((w) => w.id === s);
|
|
248
|
+
l !== -1 && (t.splice(l, 1), d.value === s && (d.value = null), i.value === s && (i.value = null, u.value = void 0));
|
|
249
249
|
}
|
|
250
|
-
async function _(
|
|
251
|
-
|
|
250
|
+
async function _(s = i.value ?? void 0, r = !1) {
|
|
251
|
+
s && (d.value = s, await re(), r || await re(), d.value = null);
|
|
252
252
|
}
|
|
253
|
-
async function g(
|
|
254
|
-
for (const
|
|
255
|
-
await _(
|
|
253
|
+
async function g(s = !1) {
|
|
254
|
+
for (const r of t)
|
|
255
|
+
await _(r.id, s);
|
|
256
256
|
}
|
|
257
|
-
async function E(
|
|
258
|
-
t.splice(0, t.length),
|
|
259
|
-
for (const
|
|
260
|
-
const l = N(e,
|
|
257
|
+
async function E(s = a.defaultRoute) {
|
|
258
|
+
t.splice(0, t.length), i.value = null, u.value = void 0;
|
|
259
|
+
for (const r of a.initialTabs) {
|
|
260
|
+
const l = N(e, r.to), w = G(l, r, a.keepAlive);
|
|
261
261
|
t.push(w);
|
|
262
262
|
}
|
|
263
|
-
await e.replace(
|
|
263
|
+
await e.replace(s);
|
|
264
264
|
}
|
|
265
265
|
async function L() {
|
|
266
|
-
const
|
|
267
|
-
|
|
266
|
+
const s = i.value;
|
|
267
|
+
s && await _(s, !0);
|
|
268
268
|
}
|
|
269
|
-
function P(
|
|
270
|
-
return typeof
|
|
269
|
+
function P(s) {
|
|
270
|
+
return typeof s.matched == "object" ? $(s) : $(N(e, s));
|
|
271
271
|
}
|
|
272
272
|
function q() {
|
|
273
|
-
const
|
|
273
|
+
const s = t.find((r) => r.id === i.value);
|
|
274
274
|
return {
|
|
275
|
-
tabs: t.map(
|
|
276
|
-
active:
|
|
275
|
+
tabs: t.map(Ze),
|
|
276
|
+
active: s ? s.to : null
|
|
277
277
|
};
|
|
278
278
|
}
|
|
279
|
-
async function X(
|
|
280
|
-
p = !0, t.splice(0, t.length),
|
|
281
|
-
const
|
|
282
|
-
for (const w of
|
|
279
|
+
async function X(s) {
|
|
280
|
+
p = !0, t.splice(0, t.length), i.value = null, u.value = void 0;
|
|
281
|
+
const r = s?.tabs ?? [];
|
|
282
|
+
for (const w of r)
|
|
283
283
|
try {
|
|
284
|
-
const O = N(e, w.to), V =
|
|
284
|
+
const O = N(e, w.to), V = et(w), D = G(O, V, a.keepAlive);
|
|
285
285
|
Z(t, D, "last", null);
|
|
286
286
|
} catch {
|
|
287
287
|
}
|
|
288
288
|
p = !1;
|
|
289
|
-
const l =
|
|
289
|
+
const l = s?.active ?? r[r.length - 1]?.to ?? a.defaultRoute;
|
|
290
290
|
if (l)
|
|
291
291
|
try {
|
|
292
292
|
await e.replace(l);
|
|
@@ -295,19 +295,19 @@ function et(e, n = {}) {
|
|
|
295
295
|
}
|
|
296
296
|
return x(
|
|
297
297
|
() => e.currentRoute.value,
|
|
298
|
-
(
|
|
298
|
+
(s) => {
|
|
299
299
|
if (p) return;
|
|
300
|
-
const
|
|
301
|
-
|
|
300
|
+
const r = b(s);
|
|
301
|
+
i.value = r.id, u.value = r, Te(t, a.maxAlive, i.value);
|
|
302
302
|
},
|
|
303
303
|
{ immediate: !0 }
|
|
304
|
-
), a.initialTabs.length && a.initialTabs.forEach((
|
|
305
|
-
const
|
|
304
|
+
), a.initialTabs.length && a.initialTabs.forEach((s) => {
|
|
305
|
+
const r = N(e, s.to), l = G(r, s, a.keepAlive);
|
|
306
306
|
Z(t, l, "last", null);
|
|
307
307
|
}), {
|
|
308
308
|
options: a,
|
|
309
309
|
tabs: t,
|
|
310
|
-
activeId:
|
|
310
|
+
activeId: i,
|
|
311
311
|
current: u,
|
|
312
312
|
includeKeys: f,
|
|
313
313
|
refreshingKey: d,
|
|
@@ -324,12 +324,12 @@ function et(e, n = {}) {
|
|
|
324
324
|
hydrate: X
|
|
325
325
|
};
|
|
326
326
|
}
|
|
327
|
-
function
|
|
327
|
+
function ke(e) {
|
|
328
328
|
return e ? typeof e == "string" ? { name: e } : e : {};
|
|
329
329
|
}
|
|
330
|
-
const H = Symbol("RouterTabsContext"), ee = typeof window < "u" && "sessionStorage" in window,
|
|
330
|
+
const H = Symbol("RouterTabsContext"), ee = typeof window < "u" && "sessionStorage" in window, nt = ae({
|
|
331
331
|
name: "RouterTab",
|
|
332
|
-
components: { RouterView:
|
|
332
|
+
components: { RouterView: Ye },
|
|
333
333
|
props: {
|
|
334
334
|
tabs: {
|
|
335
335
|
type: Array,
|
|
@@ -373,13 +373,13 @@ const H = Symbol("RouterTabsContext"), ee = typeof window < "u" && "sessionStora
|
|
|
373
373
|
}
|
|
374
374
|
},
|
|
375
375
|
setup(e) {
|
|
376
|
-
const n =
|
|
376
|
+
const n = se();
|
|
377
377
|
if (!n)
|
|
378
378
|
throw new Error("[RouterTab] component must be used within a Vue application context.");
|
|
379
379
|
const a = n.appContext.app.config.globalProperties.$router;
|
|
380
380
|
if (!a)
|
|
381
381
|
throw new Error("[RouterTab] Vue Router is required. Make sure to call app.use(router) before RouterTab.");
|
|
382
|
-
const t =
|
|
382
|
+
const t = tt(a, {
|
|
383
383
|
initialTabs: e.tabs,
|
|
384
384
|
keepAlive: e.keepAlive,
|
|
385
385
|
maxAlive: e.maxAlive,
|
|
@@ -388,7 +388,7 @@ const H = Symbol("RouterTabsContext"), ee = typeof window < "u" && "sessionStora
|
|
|
388
388
|
defaultRoute: e.defaultPage
|
|
389
389
|
});
|
|
390
390
|
U(H, t), n.appContext.config.globalProperties.$tabs = t;
|
|
391
|
-
const
|
|
391
|
+
const i = S(() => ke(e.tabTransition)), u = S(() => ke(e.pageTransition)), d = _e({
|
|
392
392
|
visible: !1,
|
|
393
393
|
target: null,
|
|
394
394
|
position: { x: 0, y: 0 }
|
|
@@ -442,7 +442,7 @@ const H = Symbol("RouterTabsContext"), ee = typeof window < "u" && "sessionStora
|
|
|
442
442
|
handler: async ({ target: o }) => {
|
|
443
443
|
await t.closeTab(o.id);
|
|
444
444
|
},
|
|
445
|
-
enable: ({ target: o }) =>
|
|
445
|
+
enable: ({ target: o }) => s(o)
|
|
446
446
|
},
|
|
447
447
|
closeLefts: {
|
|
448
448
|
label: "Close to the Left",
|
|
@@ -473,18 +473,18 @@ const H = Symbol("RouterTabsContext"), ee = typeof window < "u" && "sessionStora
|
|
|
473
473
|
e.contextmenu && (d.visible = !0, d.target = o, d.position.x = c.clientX, d.position.y = c.clientY, document.addEventListener("click", g, { once: !0 }));
|
|
474
474
|
}
|
|
475
475
|
function L(o, c) {
|
|
476
|
-
const v = typeof o == "string" ? { id: o } : o, R = _[v.id],
|
|
476
|
+
const v = typeof o == "string" ? { id: o } : o, R = _[v.id], xe = v.label ?? R?.label ?? String(v.id), Y = v.visible ?? R?.visible ?? !0;
|
|
477
477
|
if (!(typeof Y == "function" ? Y(c) : Y !== !1)) return null;
|
|
478
|
-
const F = v.enable ?? R?.enable ?? !0,
|
|
478
|
+
const F = v.enable ?? R?.enable ?? !0, Ee = typeof F == "function" ? F(c) : F !== !1, ie = v.handler ?? R?.handler;
|
|
479
479
|
if (!ie) return null;
|
|
480
|
-
const
|
|
480
|
+
const Oe = async () => {
|
|
481
481
|
await Promise.resolve(ie(c));
|
|
482
482
|
};
|
|
483
483
|
return {
|
|
484
484
|
id: String(v.id),
|
|
485
|
-
label:
|
|
486
|
-
disabled: !
|
|
487
|
-
action:
|
|
485
|
+
label: xe,
|
|
486
|
+
disabled: !Ee,
|
|
487
|
+
action: Oe
|
|
488
488
|
};
|
|
489
489
|
}
|
|
490
490
|
const P = S(() => {
|
|
@@ -498,10 +498,10 @@ const H = Symbol("RouterTabsContext"), ee = typeof window < "u" && "sessionStora
|
|
|
498
498
|
function X(o) {
|
|
499
499
|
return typeof o.title == "string" ? o.title : Array.isArray(o.title) && o.title.length ? String(o.title[0]) : o.fullPath;
|
|
500
500
|
}
|
|
501
|
-
function
|
|
501
|
+
function s(o) {
|
|
502
502
|
return !(o.closable === !1 || t.options.keepLastTab && t.tabs.length <= 1);
|
|
503
503
|
}
|
|
504
|
-
async function
|
|
504
|
+
async function r(o) {
|
|
505
505
|
await t.closeTab(o.id);
|
|
506
506
|
}
|
|
507
507
|
function l(o) {
|
|
@@ -512,7 +512,7 @@ const H = Symbol("RouterTabsContext"), ee = typeof window < "u" && "sessionStora
|
|
|
512
512
|
"router-tab__item",
|
|
513
513
|
{
|
|
514
514
|
"is-active": t.activeId.value === o.id,
|
|
515
|
-
"is-closable":
|
|
515
|
+
"is-closable": s(o)
|
|
516
516
|
},
|
|
517
517
|
o.tabClass
|
|
518
518
|
];
|
|
@@ -543,9 +543,9 @@ const H = Symbol("RouterTabsContext"), ee = typeof window < "u" && "sessionStora
|
|
|
543
543
|
} catch {
|
|
544
544
|
}
|
|
545
545
|
}
|
|
546
|
-
|
|
546
|
+
Ae(() => {
|
|
547
547
|
document.addEventListener("keydown", g), V();
|
|
548
|
-
}),
|
|
548
|
+
}), Ne(() => {
|
|
549
549
|
document.removeEventListener("keydown", g), n.appContext.config.globalProperties.$tabs = null, D();
|
|
550
550
|
}), x(
|
|
551
551
|
() => e.keepAlive,
|
|
@@ -583,48 +583,48 @@ const H = Symbol("RouterTabsContext"), ee = typeof window < "u" && "sessionStora
|
|
|
583
583
|
},
|
|
584
584
|
{ deep: !0 }
|
|
585
585
|
);
|
|
586
|
-
const
|
|
586
|
+
const Pe = t.includeKeys;
|
|
587
587
|
return {
|
|
588
588
|
controller: t,
|
|
589
589
|
tabs: t.tabs,
|
|
590
|
-
includeKeys:
|
|
591
|
-
tabTransitionProps:
|
|
590
|
+
includeKeys: Pe,
|
|
591
|
+
tabTransitionProps: i,
|
|
592
592
|
pageTransitionProps: u,
|
|
593
593
|
buildTabClass: w,
|
|
594
594
|
activate: l,
|
|
595
|
-
close:
|
|
595
|
+
close: r,
|
|
596
596
|
context: d,
|
|
597
597
|
menuItems: P,
|
|
598
598
|
handleMenuAction: q,
|
|
599
599
|
showContextMenu: E,
|
|
600
600
|
hideContextMenu: g,
|
|
601
601
|
tabTitle: X,
|
|
602
|
-
isClosable:
|
|
602
|
+
isClosable: s,
|
|
603
603
|
isRefreshing: O
|
|
604
604
|
};
|
|
605
605
|
}
|
|
606
|
-
}),
|
|
606
|
+
}), ot = (e, n) => {
|
|
607
607
|
const a = e.__vccOpts || e;
|
|
608
|
-
for (const [t,
|
|
609
|
-
a[t] =
|
|
608
|
+
for (const [t, i] of n)
|
|
609
|
+
a[t] = i;
|
|
610
610
|
return a;
|
|
611
|
-
},
|
|
612
|
-
function
|
|
613
|
-
const d =
|
|
614
|
-
return T(), A("div",
|
|
615
|
-
I("header",
|
|
611
|
+
}, at = { class: "router-tab" }, st = { class: "router-tab__header" }, it = { class: "router-tab__slot-start" }, rt = { class: "router-tab__scroll" }, lt = ["onClick", "onAuxclick", "onContextmenu"], ct = ["title"], ut = ["onClick"], ft = { class: "router-tab__slot-end" }, dt = { class: "router-tab__container" }, pt = ["aria-disabled", "onClick"];
|
|
612
|
+
function bt(e, n, a, t, i, u) {
|
|
613
|
+
const d = $e("RouterView");
|
|
614
|
+
return T(), A("div", at, [
|
|
615
|
+
I("header", st, [
|
|
616
616
|
I("div", it, [
|
|
617
|
-
|
|
617
|
+
le(e.$slots, "start")
|
|
618
618
|
]),
|
|
619
|
-
I("div",
|
|
620
|
-
j(
|
|
619
|
+
I("div", rt, [
|
|
620
|
+
j(Le, Q({
|
|
621
621
|
tag: "ul",
|
|
622
622
|
class: "router-tab__nav"
|
|
623
623
|
}, e.tabTransitionProps), {
|
|
624
624
|
default: M(() => [
|
|
625
|
-
(T(!0), A(
|
|
625
|
+
(T(!0), A(ce, null, ue(e.tabs, (f) => (T(), A("li", {
|
|
626
626
|
key: f.id,
|
|
627
|
-
class:
|
|
627
|
+
class: fe(e.buildTabClass(f)),
|
|
628
628
|
onClick: (p) => e.activate(f),
|
|
629
629
|
onAuxclick: B((p) => e.close(f), ["middle", "prevent"]),
|
|
630
630
|
onContextmenu: B((p) => e.showContextMenu(f, p), ["prevent"])
|
|
@@ -635,35 +635,35 @@ function pt(e, n, a, t, r, u) {
|
|
|
635
635
|
}, [
|
|
636
636
|
f.icon ? (T(), A("i", {
|
|
637
637
|
key: 0,
|
|
638
|
-
class:
|
|
638
|
+
class: fe(["router-tab__item-icon", f.icon])
|
|
639
639
|
}, null, 2)) : K("", !0),
|
|
640
|
-
|
|
641
|
-
], 8,
|
|
640
|
+
De(" " + de(e.tabTitle(f)), 1)
|
|
641
|
+
], 8, ct),
|
|
642
642
|
e.isClosable(f) ? (T(), A("a", {
|
|
643
643
|
key: 0,
|
|
644
644
|
class: "router-tab__item-close",
|
|
645
645
|
onClick: B((p) => e.close(f), ["stop"])
|
|
646
|
-
}, null, 8,
|
|
647
|
-
], 42,
|
|
646
|
+
}, null, 8, ut)) : K("", !0)
|
|
647
|
+
], 42, lt))), 128))
|
|
648
648
|
]),
|
|
649
649
|
_: 1
|
|
650
650
|
}, 16)
|
|
651
651
|
]),
|
|
652
|
-
I("div",
|
|
653
|
-
|
|
652
|
+
I("div", ft, [
|
|
653
|
+
le(e.$slots, "end")
|
|
654
654
|
])
|
|
655
655
|
]),
|
|
656
|
-
I("div",
|
|
656
|
+
I("div", dt, [
|
|
657
657
|
j(d, null, {
|
|
658
658
|
default: M(({ Component: f, route: p }) => [
|
|
659
|
-
j(
|
|
659
|
+
j(pe, Q(e.pageTransitionProps, { appear: "" }), {
|
|
660
660
|
default: M(() => [
|
|
661
|
-
e.controller.options.keepAlive ? (T(), W(
|
|
661
|
+
e.controller.options.keepAlive ? (T(), W(je, {
|
|
662
662
|
key: 0,
|
|
663
663
|
include: e.includeKeys,
|
|
664
664
|
max: e.controller.options.maxAlive || void 0
|
|
665
665
|
}, [
|
|
666
|
-
e.isRefreshing(p) ? K("", !0) : (T(), W(
|
|
666
|
+
e.isRefreshing(p) ? K("", !0) : (T(), W(be(f), {
|
|
667
667
|
key: e.controller.getRouteKey(p),
|
|
668
668
|
class: "router-tab-page"
|
|
669
669
|
}))
|
|
@@ -671,9 +671,9 @@ function pt(e, n, a, t, r, u) {
|
|
|
671
671
|
]),
|
|
672
672
|
_: 2
|
|
673
673
|
}, 1040),
|
|
674
|
-
j(
|
|
674
|
+
j(pe, Q(e.pageTransitionProps, { appear: "" }), {
|
|
675
675
|
default: M(() => [
|
|
676
|
-
!e.controller.options.keepAlive || e.isRefreshing(p) ? (T(), W(
|
|
676
|
+
!e.controller.options.keepAlive || e.isRefreshing(p) ? (T(), W(be(f), {
|
|
677
677
|
key: e.controller.getRouteKey(p) + (e.isRefreshing(p) ? "-refresh" : ""),
|
|
678
678
|
class: "router-tab-page"
|
|
679
679
|
})) : K("", !0)
|
|
@@ -687,36 +687,36 @@ function pt(e, n, a, t, r, u) {
|
|
|
687
687
|
e.context.visible && e.context.target ? (T(), A("div", {
|
|
688
688
|
key: 0,
|
|
689
689
|
class: "router-tab__contextmenu",
|
|
690
|
-
style:
|
|
690
|
+
style: Me({ left: e.context.position.x + "px", top: e.context.position.y + "px" })
|
|
691
691
|
}, [
|
|
692
|
-
(T(!0), A(
|
|
692
|
+
(T(!0), A(ce, null, ue(e.menuItems, (f) => (T(), A("a", {
|
|
693
693
|
key: f.id,
|
|
694
694
|
class: "router-tab__contextmenu-item",
|
|
695
695
|
"aria-disabled": f.disabled,
|
|
696
696
|
onClick: B((p) => e.handleMenuAction(f), ["prevent"])
|
|
697
|
-
},
|
|
697
|
+
}, de(f.label), 9, pt))), 128))
|
|
698
698
|
], 4)) : K("", !0)
|
|
699
699
|
]);
|
|
700
700
|
}
|
|
701
|
-
const
|
|
702
|
-
function
|
|
701
|
+
const Re = /* @__PURE__ */ ot(nt, [["render", bt]]);
|
|
702
|
+
function vt(e = {}) {
|
|
703
703
|
const { optional: n = !1 } = e, a = z(H, null);
|
|
704
704
|
if (a) return a;
|
|
705
705
|
const t = z("$tabs", null);
|
|
706
706
|
if (t) return t;
|
|
707
|
-
const u =
|
|
707
|
+
const u = se()?.appContext.config.globalProperties.$tabs;
|
|
708
708
|
if (u) return u;
|
|
709
709
|
if (!n)
|
|
710
710
|
throw new Error("[RouterTabs] useRouterTabs must be used within <router-tab>.");
|
|
711
711
|
return null;
|
|
712
712
|
}
|
|
713
|
-
const
|
|
714
|
-
function
|
|
713
|
+
const ht = "router-tabs:persistent";
|
|
714
|
+
function mt(e) {
|
|
715
715
|
return typeof window > "u" ? null : e === void 0 ? window.localStorage ?? null : e;
|
|
716
716
|
}
|
|
717
|
-
function
|
|
718
|
-
const n =
|
|
719
|
-
return
|
|
717
|
+
function yt(e) {
|
|
718
|
+
const n = mt(e.storage), a = e.storageKey ?? ht;
|
|
719
|
+
return Be(e.storeId ?? "routerTabs", {
|
|
720
720
|
state: () => ({
|
|
721
721
|
snapshot: null
|
|
722
722
|
}),
|
|
@@ -742,17 +742,29 @@ function mt(e) {
|
|
|
742
742
|
}
|
|
743
743
|
});
|
|
744
744
|
}
|
|
745
|
-
function
|
|
746
|
-
const n =
|
|
747
|
-
|
|
745
|
+
function gt(e = {}) {
|
|
746
|
+
const n = vt({ optional: !0 });
|
|
747
|
+
if (!n)
|
|
748
|
+
throw new Error("[RouterTabs] Pinia helper must be used inside <router-tab>.");
|
|
749
|
+
const t = (e.store ?? yt(e))(), i = J(!1);
|
|
750
|
+
return Ae(async () => {
|
|
748
751
|
t.load();
|
|
749
752
|
const u = t.snapshot;
|
|
750
|
-
if (u)
|
|
753
|
+
if (u && u.tabs?.length)
|
|
751
754
|
try {
|
|
752
|
-
|
|
755
|
+
i.value = !0, await n.hydrate(u);
|
|
753
756
|
} finally {
|
|
754
|
-
|
|
757
|
+
i.value = !1;
|
|
755
758
|
}
|
|
759
|
+
else
|
|
760
|
+
try {
|
|
761
|
+
i.value = !0;
|
|
762
|
+
const d = e.fallbackRoute ?? n.options.defaultRoute;
|
|
763
|
+
await n.reset(d);
|
|
764
|
+
} finally {
|
|
765
|
+
i.value = !1;
|
|
766
|
+
}
|
|
767
|
+
t.setSnapshot(n.snapshot());
|
|
756
768
|
}), x(
|
|
757
769
|
() => ({
|
|
758
770
|
tabs: n.tabs.map((u) => ({
|
|
@@ -766,44 +778,50 @@ function yt(e = {}) {
|
|
|
766
778
|
active: n.activeId.value
|
|
767
779
|
}),
|
|
768
780
|
() => {
|
|
769
|
-
|
|
781
|
+
i.value || t.setSnapshot(n.snapshot());
|
|
770
782
|
},
|
|
771
783
|
{ deep: !0 }
|
|
772
784
|
), t;
|
|
773
785
|
}
|
|
774
|
-
const
|
|
775
|
-
class: "router-tabs
|
|
786
|
+
const wt = {
|
|
787
|
+
class: "router-tabs",
|
|
776
788
|
"aria-hidden": "true"
|
|
777
|
-
},
|
|
789
|
+
}, te = /* @__PURE__ */ ae({
|
|
790
|
+
name: "RouterTabs",
|
|
778
791
|
__name: "RouterTabsPinia",
|
|
779
792
|
props: {
|
|
780
793
|
storeId: {},
|
|
781
794
|
storageKey: {},
|
|
782
795
|
storage: {},
|
|
796
|
+
fallbackRoute: {},
|
|
783
797
|
store: { type: [Function, Object] }
|
|
784
798
|
},
|
|
785
799
|
setup(e) {
|
|
786
|
-
return
|
|
800
|
+
return gt(e), (a, t) => (T(), A("span", wt));
|
|
787
801
|
}
|
|
788
|
-
}),
|
|
802
|
+
}), Ce = {
|
|
789
803
|
install(e) {
|
|
790
|
-
|
|
804
|
+
if (Ce._installed) return;
|
|
805
|
+
Ce._installed = !0;
|
|
806
|
+
const n = Re.name || "RouterTab", a = te.name || "RouterTabs";
|
|
807
|
+
e.component(n, Re), e.component(a, te), a !== "router-tabs" && e.component("router-tabs", te), Object.defineProperty(e.config.globalProperties, "$tabs", {
|
|
791
808
|
configurable: !0,
|
|
792
809
|
enumerable: !1,
|
|
793
810
|
get() {
|
|
794
811
|
return e._context.provides[H];
|
|
795
812
|
},
|
|
796
|
-
set(
|
|
797
|
-
|
|
813
|
+
set(t) {
|
|
814
|
+
t && e.provide(H, t);
|
|
798
815
|
}
|
|
799
|
-
})
|
|
816
|
+
});
|
|
800
817
|
}
|
|
801
818
|
};
|
|
802
819
|
export {
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
820
|
+
Re as RouterTab,
|
|
821
|
+
te as RouterTabs,
|
|
822
|
+
te as RouterTabsPinia,
|
|
823
|
+
Ce as default,
|
|
806
824
|
H as routerTabsKey,
|
|
807
|
-
|
|
808
|
-
|
|
825
|
+
vt as useRouterTabs,
|
|
826
|
+
gt as useRouterTabsPiniaPersistence
|
|
809
827
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
(function(v,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue"),require("pinia")):typeof define=="function"&&define.amd?define(["exports","vue","pinia"],t):(v=typeof globalThis<"u"?globalThis:v||self,t(v["vue3-router-tab"]={},v.Vue,v.pinia))})(this,(function(v,t,re){"use strict";/*!
|
|
2
|
+
* vue-router v4.5.1
|
|
3
|
+
* (c) 2025 Eduardo San Martin Morote
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/const se=typeof document<"u",le=Object.assign,ce=Array.isArray;function ue(e){const o=Array.from(arguments).slice(1);console.warn.apply(console,["[Vue Router warn]: "+e].concat(o))}function fe(e,o){return(e.aliasOf||e)===(o.aliasOf||o)}var F;(function(e){e.pop="pop",e.push="push"})(F||(F={}));var X;(function(e){e.back="back",e.forward="forward",e.unknown=""})(X||(X={})),Symbol(process.env.NODE_ENV!=="production"?"navigation failure":"");var Y;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})(Y||(Y={}));const de=Symbol(process.env.NODE_ENV!=="production"?"router view location matched":""),Q=Symbol(process.env.NODE_ENV!=="production"?"router view depth":"");Symbol(process.env.NODE_ENV!=="production"?"router":""),Symbol(process.env.NODE_ENV!=="production"?"route location":"");const W=Symbol(process.env.NODE_ENV!=="production"?"router view location":""),pe=t.defineComponent({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:o,slots:i}){process.env.NODE_ENV!=="production"&&me();const n=t.inject(W),s=t.computed(()=>e.route||n.value),f=t.inject(Q,0),p=t.computed(()=>{let y=t.unref(f);const{matched:m}=s.value;let g;for(;(g=m[y])&&!g.components;)y++;return y}),d=t.computed(()=>s.value.matched[p.value]);t.provide(Q,t.computed(()=>p.value+1)),t.provide(de,d),t.provide(W,s);const b=t.ref();return t.watch(()=>[b.value,d.value,e.name],([y,m,g],[R,w,S])=>{m&&(m.instances[g]=y,w&&w!==m&&y&&y===R&&(m.leaveGuards.size||(m.leaveGuards=w.leaveGuards),m.updateGuards.size||(m.updateGuards=w.updateGuards))),y&&m&&(!w||!fe(m,w)||!R)&&(m.enterCallbacks[g]||[]).forEach(C=>C(y))},{flush:"post"}),()=>{const y=s.value,m=e.name,g=d.value,R=g&&g.components[m];if(!R)return Z(i.default,{Component:R,route:y});const w=g.props[m],S=w?w===!0?y.params:typeof w=="function"?w(y):w:null,C=E=>{E.component.isUnmounted&&(g.instances[m]=null)},T=t.h(R,le({},S,o,{onVnodeUnmounted:C,ref:b}));if(process.env.NODE_ENV!=="production"&&se&&T.ref){const E={depth:p.value,name:g.name,path:g.path,meta:g.meta};(ce(T.ref)?T.ref.map(A=>A.i):[T.ref.i]).forEach(A=>{A.__vrv_devtools=E})}return Z(i.default,{Component:T,route:y})||T}}});function Z(e,o){if(!e)return null;const i=e(o);return i.length===1?i[0]:i}const be=pe;function me(){const e=t.getCurrentInstance(),o=e.parent&&e.parent.type.name,i=e.parent&&e.parent.subTree&&e.parent.subTree.type;if(o&&(o==="KeepAlive"||o.includes("Transition"))&&typeof i=="object"&&i.name==="RouterView"){const n=o==="KeepAlive"?"keep-alive":"transition";ue(`<router-view> can no longer be used directly inside <transition> or <keep-alive>.
|
|
6
|
+
Use slot props instead:
|
|
7
|
+
|
|
8
|
+
<router-view v-slot="{ Component }">
|
|
9
|
+
<${n}>
|
|
10
|
+
<component :is="Component" />
|
|
11
|
+
</${n}>
|
|
12
|
+
</router-view>`)}}function he(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 V(e,o){const i=e.resolve(o);if(!i||!i.matched.length)throw new Error(`[RouterTabs] Unable to resolve route: ${String(o)}`);return i}const ye={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 o=e.meta?.key;if(typeof o=="function"){const i=o(e);if(typeof i=="string"&&i.length)return i}else if(typeof o=="string"&&o.length){const i=ye[o.toLowerCase()];return i?i(e):o}return e.fullPath}function j(e,o){const i=e.meta?.keepAlive;return typeof i=="boolean"?i:o}function M(e,o){const i=e.meta?.reuse;return typeof i=="boolean"?i:o}function ee(e){const o=e.meta??{},i={};return"title"in o&&(i.title=o.title),"tips"in o&&(i.tips=o.tips),"icon"in o&&(i.icon=o.icon),"closable"in o&&(i.closable=o.closable),"tabClass"in o&&(i.tabClass=o.tabClass),"target"in o&&(i.target=o.target),"href"in o&&(i.href=o.href),i}function $(e,o,i){const n=ee(e);return{id:N(e),to:e.fullPath,fullPath:e.fullPath,matched:e,alive:j(e,i),reusable:M(e,!1),closable:n.closable??!0,...n,...o}}function L(e,o,i,n){if(!e.find(f=>f.id===o.id)){if(i==="next"&&n){const f=e.findIndex(p=>p.id===n);if(f>-1){e.splice(f+1,0,o);return}}e.push(o)}}function te(e,o,i){if(!o||o<=0)return;const n=e.filter(s=>s.alive);for(;n.length>o;){const s=n.shift();if(!s||s.id===i)continue;const f=e.findIndex(p=>p.id===s.id);f>-1&&(e[f].alive=!1)}}function ge(e){return{to:e.to,title:e.title,tips:e.tips,icon:e.icon,tabClass:e.tabClass,closable:e.closable}}function we(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 Te(e,o={}){const i=he(o),n=t.reactive([]),s=t.ref(null),f=t.shallowRef(),p=t.ref(null),d=t.computed(()=>n.filter(r=>r.alive).map(r=>r.id));let b=!1;function y(r){const l=typeof r.matched=="object"?r:V(e,r);return{key:N(l),fullPath:l.fullPath,alive:j(l,i.keepAlive),reusable:M(l,!1),matched:l}}function m(r){const l=N(r);let c=n.find(k=>k.id===l);return c?(c.fullPath=r.fullPath,c.to=r.fullPath,c.matched=r,c.alive=j(r,i.keepAlive),c.reusable=M(r,c.reusable),Object.assign(c,ee(r)),c):(c=$(r,{},i.keepAlive),L(n,c,i.appendPosition,s.value),te(n,i.maxAlive,s.value),c)}async function g(r,l=!1,c=!0){const k=V(e,r),P=N(k),x=s.value===P;c==="sameTab"&&(c=x),c&&await C(P,!0),await e[l?"replace":"push"](k),x&&await O()}function R(r){const l=n.findIndex(k=>k.id===r),c=n[l]||n[l-1]||n[0];return c?c.to:i.defaultRoute}async function w(r=s.value,l={}){if(r){if(!l.force&&i.keepLastTab&&n.length===1)throw new Error("[RouterTabs] Unable to close the final tab when keepLastTab is true.");if(await S(r,{force:l.force}),l.redirect!==null)if(s.value===r){const c=l.redirect??R(r);c&&await e.replace(c)}else l.redirect&&await e.replace(l.redirect)}}async function S(r,l={}){const c=n.findIndex(k=>k.id===r);c!==-1&&(n.splice(c,1),p.value===r&&(p.value=null),s.value===r&&(s.value=null,f.value=void 0))}async function C(r=s.value??void 0,l=!1){r&&(p.value=r,await t.nextTick(),l||await t.nextTick(),p.value=null)}async function T(r=!1){for(const l of n)await C(l.id,r)}async function E(r=i.defaultRoute){n.splice(0,n.length),s.value=null,f.value=void 0;for(const l of i.initialTabs){const c=V(e,l.to),k=$(c,l,i.keepAlive);n.push(k)}await e.replace(r)}async function O(){const r=s.value;r&&await C(r,!0)}function A(r){return typeof r.matched=="object"?N(r):N(V(e,r))}function U(){const r=n.find(l=>l.id===s.value);return{tabs:n.map(ge),active:r?r.to:null}}async function J(r){b=!0,n.splice(0,n.length),s.value=null,f.value=void 0;const l=r?.tabs??[];for(const k of l)try{const P=V(e,k.to),x=we(k),K=$(P,x,i.keepAlive);L(n,K,"last",null)}catch{}b=!1;const c=r?.active??l[l.length-1]?.to??i.defaultRoute;if(c)try{await e.replace(c)}catch{}}return t.watch(()=>e.currentRoute.value,r=>{if(b)return;const l=m(r);s.value=l.id,f.value=l,te(n,i.maxAlive,s.value)},{immediate:!0}),i.initialTabs.length&&i.initialTabs.forEach(r=>{const l=V(e,r.to),c=$(l,r,i.keepAlive);L(n,c,"last",null)}),{options:i,tabs:n,activeId:s,current:f,includeKeys:d,refreshingKey:p,openTab:g,closeTab:w,removeTab:S,refreshTab:C,refreshAll:T,reset:E,reload:O,getRouteKey:A,matchRoute:y,snapshot:U,hydrate:J}}function ne(e){return e?typeof e=="string"?{name:e}:e:{}}const B=Symbol("RouterTabsContext"),D=typeof window<"u"&&"sessionStorage"in window,ke=t.defineComponent({name:"RouterTab",components:{RouterView:be},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},storage:{type:[Boolean,String],default:!1}},setup(e){const o=t.getCurrentInstance();if(!o)throw new Error("[RouterTab] component must be used within a Vue application context.");const i=o.appContext.app.config.globalProperties.$router;if(!i)throw new Error("[RouterTab] Vue Router is required. Make sure to call app.use(router) before RouterTab.");const n=Te(i,{initialTabs:e.tabs,keepAlive:e.keepAlive,maxAlive:e.maxAlive,keepLastTab:e.keepLastTab,appendPosition:e.append,defaultRoute:e.defaultPage});t.provide(B,n),o.appContext.config.globalProperties.$tabs=n;const s=t.computed(()=>ne(e.tabTransition)),f=t.computed(()=>ne(e.pageTransition)),p=t.reactive({visible:!1,target:null,position:{x:0,y:0}}),d=t.computed(()=>!e.storage||!D?null:typeof e.storage=="string"?e.storage:`router-tabs:${(i.options?.history?.base??"")||"default"}`);let b=!!d.value;const y=["refresh","refreshAll","close","closeLefts","closeRights","closeOthers"];function m(a){return n.tabs.findIndex(u=>u.id===a)}function g(a){const u=m(a.id);return u>0?n.tabs.slice(0,u):[]}function R(a){const u=m(a.id);return u>-1?n.tabs.slice(u+1):[]}function w(a){return n.tabs.filter(u=>u.id!==a.id)}async function S(a,u){const h=a.filter(_=>_.closable!==!1);if(h.length){for(const _ of h)n.activeId.value===_.id?await n.closeTab(_.id,{redirect:u.to,force:!0}):await n.removeTab(_.id,{force:!0});n.activeId.value!==u.id&&await n.openTab(u.to,!0,!1)}}const C={refresh:{label:"Refresh",handler:async({target:a})=>{await n.refreshTab(a.id,!0)}},refreshAll:{label:"Refresh All",handler:async()=>{await n.refreshAll(!0)}},close:{label:"Close",handler:async({target:a})=>{await n.closeTab(a.id)},enable:({target:a})=>r(a)},closeLefts:{label:"Close to the Left",handler:async({target:a})=>{await S(g(a),a)},enable:({target:a})=>g(a).some(u=>u.closable!==!1)},closeRights:{label:"Close to the Right",handler:async({target:a})=>{await S(R(a),a)},enable:({target:a})=>R(a).some(u=>u.closable!==!1)},closeOthers:{label:"Close Others",handler:async({target:a})=>{await S(w(a),a)},enable:({target:a})=>w(a).some(u=>u.closable!==!1)}};function T(){p.visible=!1,p.target=null}function E(a,u){e.contextmenu&&(p.visible=!0,p.target=a,p.position.x=u.clientX,p.position.y=u.clientY,document.addEventListener("click",T,{once:!0}))}function O(a,u){const h=typeof a=="string"?{id:a}:a,_=C[h.id],Me=h.label??_?.label??String(h.id),q=h.visible??_?.visible??!0;if(!(typeof q=="function"?q(u):q!==!1))return null;const H=h.enable??_?.enable??!0,Le=typeof H=="function"?H(u):H!==!1,ie=h.handler??_?.handler;if(!ie)return null;const De=async()=>{await Promise.resolve(ie(u))};return{id:String(h.id),label:Me,disabled:!Le,action:De}}const A=t.computed(()=>{if(!p.visible||!p.target||e.contextmenu===!1)return[];const a=Array.isArray(e.contextmenu)?e.contextmenu:y,u={target:p.target,controller:n};return a.map(h=>O(h,u)).filter(h=>!!h)});async function U(a){a.disabled||(T(),await a.action())}function J(a){return typeof a.title=="string"?a.title:Array.isArray(a.title)&&a.title.length?String(a.title[0]):a.fullPath}function r(a){return!(a.closable===!1||n.options.keepLastTab&&n.tabs.length<=1)}async function l(a){await n.closeTab(a.id)}function c(a){n.activeId.value!==a.id&&n.openTab(a.to,!1)}function k(a){return["router-tab__item",{"is-active":n.activeId.value===a.id,"is-closable":r(a)},a.tabClass]}function P(a){return n.refreshingKey.value===n.getRouteKey(a)}async function x(){const a=d.value;if(!a||!D)return;const u=window.sessionStorage.getItem(a);if(u)try{const h=JSON.parse(u);if(!h||!Array.isArray(h.tabs))return;b=!0,await n.hydrate(h)}catch{}finally{b=!1,K()}}function K(){const a=d.value;if(!(!a||!D||b))try{const u=n.snapshot();window.sessionStorage.setItem(a,JSON.stringify(u))}catch{}}t.onMounted(()=>{document.addEventListener("keydown",T),x()}),t.onBeforeUnmount(()=>{document.removeEventListener("keydown",T),o.appContext.config.globalProperties.$tabs=null,K()}),t.watch(()=>e.keepAlive,a=>{n.options.keepAlive=a}),t.watch(()=>n.activeId.value,()=>T()),t.watch(()=>e.contextmenu,a=>{a||T()}),t.watch(()=>A.value.length,a=>{p.visible&&a===0&&T()}),t.watch(()=>({key:d.value,tabs:n.tabs.map(a=>({to:a.to,title:a.title,tips:a.tips,icon:a.icon,tabClass:a.tabClass,closable:a.closable})),active:n.activeId.value}),()=>{K()},{deep:!0});const je=n.includeKeys;return{controller:n,tabs:n.tabs,includeKeys:je,tabTransitionProps:s,pageTransitionProps:f,buildTabClass:k,activate:c,close:l,context:p,menuItems:A,handleMenuAction:U,showContextMenu:E,hideContextMenu:T,tabTitle:J,isClosable:r,isRefreshing:P}}}),ve=(e,o)=>{const i=e.__vccOpts||e;for(const[n,s]of o)i[n]=s;return i},Re={class:"router-tab"},Ce={class:"router-tab__header"},_e={class:"router-tab__slot-start"},Se={class:"router-tab__scroll"},Ae=["onClick","onAuxclick","onContextmenu"],Ee=["title"],Pe=["onClick"],Ve={class:"router-tab__slot-end"},Ne={class:"router-tab__container"},xe=["aria-disabled","onClick"];function Be(e,o,i,n,s,f){const p=t.resolveComponent("RouterView");return t.openBlock(),t.createElementBlock("div",Re,[t.createElementVNode("header",Ce,[t.createElementVNode("div",_e,[t.renderSlot(e.$slots,"start")]),t.createElementVNode("div",Se,[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,d=>(t.openBlock(),t.createElementBlock("li",{key:d.id,class:t.normalizeClass(e.buildTabClass(d)),onClick:b=>e.activate(d),onAuxclick:t.withModifiers(b=>e.close(d),["middle","prevent"]),onContextmenu:t.withModifiers(b=>e.showContextMenu(d,b),["prevent"])},[t.createElementVNode("span",{class:"router-tab__item-title",title:e.tabTitle(d)},[d.icon?(t.openBlock(),t.createElementBlock("i",{key:0,class:t.normalizeClass(["router-tab__item-icon",d.icon])},null,2)):t.createCommentVNode("",!0),t.createTextVNode(" "+t.toDisplayString(e.tabTitle(d)),1)],8,Ee),e.isClosable(d)?(t.openBlock(),t.createElementBlock("a",{key:0,class:"router-tab__item-close",onClick:t.withModifiers(b=>e.close(d),["stop"])},null,8,Pe)):t.createCommentVNode("",!0)],42,Ae))),128))]),_:1},16)]),t.createElementVNode("div",Ve,[t.renderSlot(e.$slots,"end")])]),t.createElementVNode("div",Ne,[t.createVNode(p,null,{default:t.withCtx(({Component:d,route:b})=>[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(b)?t.createCommentVNode("",!0):(t.openBlock(),t.createBlock(t.resolveDynamicComponent(d),{key:e.controller.getRouteKey(b),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(b)?(t.openBlock(),t.createBlock(t.resolveDynamicComponent(d),{key:e.controller.getRouteKey(b)+(e.isRefreshing(b)?"-refresh":""),class:"router-tab-page"})):t.createCommentVNode("",!0)]),_:2},1040)]),_:1})]),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,d=>(t.openBlock(),t.createElementBlock("a",{key:d.id,class:"router-tab__contextmenu-item","aria-disabled":d.disabled,onClick:t.withModifiers(b=>e.handleMenuAction(d),["prevent"])},t.toDisplayString(d.label),9,xe))),128))],4)):t.createCommentVNode("",!0)])}const z=ve(ke,[["render",Be]]);function oe(e={}){const{optional:o=!1}=e,i=t.inject(B,null);if(i)return i;const n=t.inject("$tabs",null);if(n)return n;const f=t.getCurrentInstance()?.appContext.config.globalProperties.$tabs;if(f)return f;if(!o)throw new Error("[RouterTabs] useRouterTabs must be used within <router-tab>.");return null}const Ie="router-tabs:persistent";function Oe(e){return typeof window>"u"?null:e===void 0?window.localStorage??null:e}function Ke(e){const o=Oe(e.storage),i=e.storageKey??Ie;return re.defineStore(e.storeId??"routerTabs",{state:()=>({snapshot:null}),actions:{load(){if(!(!o||this.snapshot))try{const n=o.getItem(i);n&&(this.snapshot=JSON.parse(n))}catch{}},setSnapshot(n){if(this.snapshot=n,!!o)try{n&&n.tabs.length?o.setItem(i,JSON.stringify(n)):o.removeItem(i)}catch{}},clear(){this.setSnapshot(null)}}})}function ae(e={}){const o=oe({optional:!0});if(!o)throw new Error("[RouterTabs] Pinia helper must be used inside <router-tab>.");const n=(e.store??Ke(e))(),s=t.ref(!1);return t.onMounted(async()=>{n.load();const f=n.snapshot;if(f&&f.tabs?.length)try{s.value=!0,await o.hydrate(f)}finally{s.value=!1}else try{s.value=!0;const p=e.fallbackRoute??o.options.defaultRoute;await o.reset(p)}finally{s.value=!1}n.setSnapshot(o.snapshot())}),t.watch(()=>({tabs:o.tabs.map(f=>({to:f.to,title:f.title,tips:f.tips,icon:f.icon,tabClass:f.tabClass,closable:f.closable})),active:o.activeId.value}),()=>{s.value||n.setSnapshot(o.snapshot())},{deep:!0}),n}const $e={class:"router-tabs","aria-hidden":"true"},I=t.defineComponent({name:"RouterTabs",__name:"RouterTabsPinia",props:{storeId:{},storageKey:{},storage:{},fallbackRoute:{},store:{type:[Function,Object]}},setup(e){return ae(e),(i,n)=>(t.openBlock(),t.createElementBlock("span",$e))}}),G={install(e){if(G._installed)return;G._installed=!0;const o=z.name||"RouterTab",i=I.name||"RouterTabs";e.component(o,z),e.component(i,I),i!=="router-tabs"&&e.component("router-tabs",I),Object.defineProperty(e.config.globalProperties,"$tabs",{configurable:!0,enumerable:!1,get(){return e._context.provides[B]},set(n){n&&e.provide(B,n)}})}};v.RouterTab=z,v.RouterTabs=I,v.RouterTabsPinia=I,v.default=G,v.routerTabsKey=B,v.useRouterTabs=oe,v.useRouterTabsPiniaPersistence=ae,Object.defineProperties(v,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vue3-router-tab",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -12,21 +12,23 @@
|
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
14
|
"types": "./index.d.ts",
|
|
15
|
+
"default": "./dist/vue3-router-tab.es.js",
|
|
15
16
|
"import": "./dist/vue3-router-tab.es.js",
|
|
16
17
|
"require": "./dist/vue3-router-tab.cjs.js"
|
|
17
18
|
},
|
|
18
|
-
"./style": "./dist/vue3-router-tab.css"
|
|
19
|
+
"./style": "./dist/vue3-router-tab.css",
|
|
20
|
+
"./package.json": "./package.json"
|
|
19
21
|
},
|
|
20
22
|
"scripts": {
|
|
21
23
|
"build": "vite build"
|
|
22
24
|
},
|
|
23
25
|
"dependencies": {
|
|
26
|
+
"pinia": "^3.0.3",
|
|
24
27
|
"vue": "^3.5.22",
|
|
25
28
|
"vue-router": "^4.5.1"
|
|
26
29
|
},
|
|
27
30
|
"devDependencies": {
|
|
28
31
|
"@vitejs/plugin-vue": "^6.0.1",
|
|
29
|
-
"pinia": "^3.0.3",
|
|
30
32
|
"sass": "^1.93.2",
|
|
31
33
|
"sass-loader": "^16.0.5",
|
|
32
34
|
"typescript": "^5.9.2",
|
|
@@ -40,9 +42,6 @@
|
|
|
40
42
|
"router",
|
|
41
43
|
"tabs",
|
|
42
44
|
"tab",
|
|
43
|
-
"pinia",
|
|
44
|
-
"persistence",
|
|
45
|
-
"tab persistence",
|
|
46
45
|
"router-tab"
|
|
47
46
|
],
|
|
48
47
|
"license": "MIT",
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("vue"),le=require("pinia");/*!
|
|
2
|
-
* vue-router v4.5.1
|
|
3
|
-
* (c) 2025 Eduardo San Martin Morote
|
|
4
|
-
* @license MIT
|
|
5
|
-
*/const ce=typeof document<"u",ue=Object.assign,fe=Array.isArray;function de(e){const o=Array.from(arguments).slice(1);console.warn.apply(console,["[Vue Router warn]: "+e].concat(o))}function pe(e,o){return(e.aliasOf||e)===(o.aliasOf||o)}var H;(function(e){e.pop="pop",e.push="push"})(H||(H={}));var F;(function(e){e.back="back",e.forward="forward",e.unknown=""})(F||(F={}));Symbol(process.env.NODE_ENV!=="production"?"navigation failure":"");var X;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})(X||(X={}));const be=Symbol(process.env.NODE_ENV!=="production"?"router view location matched":""),Y=Symbol(process.env.NODE_ENV!=="production"?"router view depth":"");Symbol(process.env.NODE_ENV!=="production"?"router":"");Symbol(process.env.NODE_ENV!=="production"?"route location":"");const Q=Symbol(process.env.NODE_ENV!=="production"?"router view location":""),ve=t.defineComponent({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:o,slots:r}){process.env.NODE_ENV!=="production"&&he();const n=t.inject(Q),l=t.computed(()=>e.route||n.value),f=t.inject(Y,0),p=t.computed(()=>{let h=t.unref(f);const{matched:v}=l.value;let y;for(;(y=v[h])&&!y.components;)h++;return h}),d=t.computed(()=>l.value.matched[p.value]);t.provide(Y,t.computed(()=>p.value+1)),t.provide(be,d),t.provide(Q,l);const b=t.ref();return t.watch(()=>[b.value,d.value,e.name],([h,v,y],[T,g,_])=>{v&&(v.instances[y]=h,g&&g!==v&&h&&h===T&&(v.leaveGuards.size||(v.leaveGuards=g.leaveGuards),v.updateGuards.size||(v.updateGuards=g.updateGuards))),h&&v&&(!g||!pe(v,g)||!T)&&(v.enterCallbacks[y]||[]).forEach(C=>C(h))},{flush:"post"}),()=>{const h=l.value,v=e.name,y=d.value,T=y&&y.components[v];if(!T)return W(r.default,{Component:T,route:h});const g=y.props[v],_=g?g===!0?h.params:typeof g=="function"?g(h):g:null,C=A=>{A.component.isUnmounted&&(y.instances[v]=null)},w=t.h(T,ue({},_,o,{onVnodeUnmounted:C,ref:b}));if(process.env.NODE_ENV!=="production"&&ce&&w.ref){const A={depth:p.value,name:y.name,path:y.path,meta:y.meta};(fe(w.ref)?w.ref.map(S=>S.i):[w.ref.i]).forEach(S=>{S.__vrv_devtools=A})}return W(r.default,{Component:w,route:h})||w}}});function W(e,o){if(!e)return null;const r=e(o);return r.length===1?r[0]:r}const me=ve;function he(){const e=t.getCurrentInstance(),o=e.parent&&e.parent.type.name,r=e.parent&&e.parent.subTree&&e.parent.subTree.type;if(o&&(o==="KeepAlive"||o.includes("Transition"))&&typeof r=="object"&&r.name==="RouterView"){const n=o==="KeepAlive"?"keep-alive":"transition";de(`<router-view> can no longer be used directly inside <transition> or <keep-alive>.
|
|
6
|
-
Use slot props instead:
|
|
7
|
-
|
|
8
|
-
<router-view v-slot="{ Component }">
|
|
9
|
-
<${n}>
|
|
10
|
-
<component :is="Component" />
|
|
11
|
-
</${n}>
|
|
12
|
-
</router-view>`)}}function ye(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 V(e,o){const r=e.resolve(o);if(!r||!r.matched.length)throw new Error(`[RouterTabs] Unable to resolve route: ${String(o)}`);return r}const ge={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 x(e){const o=e.meta?.key;if(typeof o=="function"){const r=o(e);if(typeof r=="string"&&r.length)return r}else if(typeof o=="string"&&o.length){const r=ge[o.toLowerCase()];return r?r(e):o}return e.fullPath}function z(e,o){const r=e.meta?.keepAlive;return typeof r=="boolean"?r:o}function G(e,o){const r=e.meta?.reuse;return typeof r=="boolean"?r:o}function te(e){const o=e.meta??{},r={};return"title"in o&&(r.title=o.title),"tips"in o&&(r.tips=o.tips),"icon"in o&&(r.icon=o.icon),"closable"in o&&(r.closable=o.closable),"tabClass"in o&&(r.tabClass=o.tabClass),"target"in o&&(r.target=o.target),"href"in o&&(r.href=o.href),r}function O(e,o,r){const n=te(e);return{id:x(e),to:e.fullPath,fullPath:e.fullPath,matched:e,alive:z(e,r),reusable:G(e,!1),closable:n.closable??!0,...n,...o}}function L(e,o,r,n){if(!e.find(f=>f.id===o.id)){if(r==="next"&&n){const f=e.findIndex(p=>p.id===n);if(f>-1){e.splice(f+1,0,o);return}}e.push(o)}}function Z(e,o,r){if(!o||o<=0)return;const n=e.filter(l=>l.alive);for(;n.length>o;){const l=n.shift();if(!l||l.id===r)continue;const f=e.findIndex(p=>p.id===l.id);f>-1&&(e[f].alive=!1)}}function we(e){return{to:e.to,title:e.title,tips:e.tips,icon:e.icon,tabClass:e.tabClass,closable:e.closable}}function ke(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 Te(e,o={}){const r=ye(o),n=t.reactive([]),l=t.ref(null),f=t.shallowRef(),p=t.ref(null),d=t.computed(()=>n.filter(i=>i.alive).map(i=>i.id));let b=!1;function h(i){const s=typeof i.matched=="object"?i:V(e,i);return{key:x(s),fullPath:s.fullPath,alive:z(s,r.keepAlive),reusable:G(s,!1),matched:s}}function v(i){const s=x(i);let c=n.find(k=>k.id===s);return c?(c.fullPath=i.fullPath,c.to=i.fullPath,c.matched=i,c.alive=z(i,r.keepAlive),c.reusable=G(i,c.reusable),Object.assign(c,te(i)),c):(c=O(i,{},r.keepAlive),L(n,c,r.appendPosition,l.value),Z(n,r.maxAlive,l.value),c)}async function y(i,s=!1,c=!0){const k=V(e,i),E=x(k),P=l.value===E;c==="sameTab"&&(c=P),c&&await C(E,!0),await e[s?"replace":"push"](k),P&&await N()}function T(i){const s=n.findIndex(k=>k.id===i),c=n[s]||n[s-1]||n[0];return c?c.to:r.defaultRoute}async function g(i=l.value,s={}){if(i){if(!s.force&&r.keepLastTab&&n.length===1)throw new Error("[RouterTabs] Unable to close the final tab when keepLastTab is true.");if(await _(i,{force:s.force}),s.redirect!==null)if(l.value===i){const c=s.redirect??T(i);c&&await e.replace(c)}else s.redirect&&await e.replace(s.redirect)}}async function _(i,s={}){const c=n.findIndex(k=>k.id===i);c!==-1&&(n.splice(c,1),p.value===i&&(p.value=null),l.value===i&&(l.value=null,f.value=void 0))}async function C(i=l.value??void 0,s=!1){i&&(p.value=i,await t.nextTick(),s||await t.nextTick(),p.value=null)}async function w(i=!1){for(const s of n)await C(s.id,i)}async function A(i=r.defaultRoute){n.splice(0,n.length),l.value=null,f.value=void 0;for(const s of r.initialTabs){const c=V(e,s.to),k=O(c,s,r.keepAlive);n.push(k)}await e.replace(i)}async function N(){const i=l.value;i&&await C(i,!0)}function S(i){return typeof i.matched=="object"?x(i):x(V(e,i))}function K(){const i=n.find(s=>s.id===l.value);return{tabs:n.map(we),active:i?i.to:null}}async function $(i){b=!0,n.splice(0,n.length),l.value=null,f.value=void 0;const s=i?.tabs??[];for(const k of s)try{const E=V(e,k.to),P=ke(k),B=O(E,P,r.keepAlive);L(n,B,"last",null)}catch{}b=!1;const c=i?.active??s[s.length-1]?.to??r.defaultRoute;if(c)try{await e.replace(c)}catch{}}return t.watch(()=>e.currentRoute.value,i=>{if(b)return;const s=v(i);l.value=s.id,f.value=s,Z(n,r.maxAlive,l.value)},{immediate:!0}),r.initialTabs.length&&r.initialTabs.forEach(i=>{const s=V(e,i.to),c=O(s,i,r.keepAlive);L(n,c,"last",null)}),{options:r,tabs:n,activeId:l,current:f,includeKeys:d,refreshingKey:p,openTab:y,closeTab:g,removeTab:_,refreshTab:C,refreshAll:w,reset:A,reload:N,getRouteKey:S,matchRoute:h,snapshot:K,hydrate:$}}function ee(e){return e?typeof e=="string"?{name:e}:e:{}}const I=Symbol("RouterTabsContext"),D=typeof window<"u"&&"sessionStorage"in window,Ce=t.defineComponent({name:"RouterTab",components:{RouterView:me},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},storage:{type:[Boolean,String],default:!1}},setup(e){const o=t.getCurrentInstance();if(!o)throw new Error("[RouterTab] component must be used within a Vue application context.");const r=o.appContext.app.config.globalProperties.$router;if(!r)throw new Error("[RouterTab] Vue Router is required. Make sure to call app.use(router) before RouterTab.");const n=Te(r,{initialTabs:e.tabs,keepAlive:e.keepAlive,maxAlive:e.maxAlive,keepLastTab:e.keepLastTab,appendPosition:e.append,defaultRoute:e.defaultPage});t.provide(I,n),o.appContext.config.globalProperties.$tabs=n;const l=t.computed(()=>ee(e.tabTransition)),f=t.computed(()=>ee(e.pageTransition)),p=t.reactive({visible:!1,target:null,position:{x:0,y:0}}),d=t.computed(()=>!e.storage||!D?null:typeof e.storage=="string"?e.storage:`router-tabs:${(r.options?.history?.base??"")||"default"}`);let b=!!d.value;const h=["refresh","refreshAll","close","closeLefts","closeRights","closeOthers"];function v(a){return n.tabs.findIndex(u=>u.id===a)}function y(a){const u=v(a.id);return u>0?n.tabs.slice(0,u):[]}function T(a){const u=v(a.id);return u>-1?n.tabs.slice(u+1):[]}function g(a){return n.tabs.filter(u=>u.id!==a.id)}async function _(a,u){const m=a.filter(R=>R.closable!==!1);if(m.length){for(const R of m)n.activeId.value===R.id?await n.closeTab(R.id,{redirect:u.to,force:!0}):await n.removeTab(R.id,{force:!0});n.activeId.value!==u.id&&await n.openTab(u.to,!0,!1)}}const C={refresh:{label:"Refresh",handler:async({target:a})=>{await n.refreshTab(a.id,!0)}},refreshAll:{label:"Refresh All",handler:async()=>{await n.refreshAll(!0)}},close:{label:"Close",handler:async({target:a})=>{await n.closeTab(a.id)},enable:({target:a})=>i(a)},closeLefts:{label:"Close to the Left",handler:async({target:a})=>{await _(y(a),a)},enable:({target:a})=>y(a).some(u=>u.closable!==!1)},closeRights:{label:"Close to the Right",handler:async({target:a})=>{await _(T(a),a)},enable:({target:a})=>T(a).some(u=>u.closable!==!1)},closeOthers:{label:"Close Others",handler:async({target:a})=>{await _(g(a),a)},enable:({target:a})=>g(a).some(u=>u.closable!==!1)}};function w(){p.visible=!1,p.target=null}function A(a,u){e.contextmenu&&(p.visible=!0,p.target=a,p.position.x=u.clientX,p.position.y=u.clientY,document.addEventListener("click",w,{once:!0}))}function N(a,u){const m=typeof a=="string"?{id:a}:a,R=C[m.id],re=m.label??R?.label??String(m.id),M=m.visible??R?.visible??!0;if(!(typeof M=="function"?M(u):M!==!1))return null;const j=m.enable??R?.enable??!0,ie=typeof j=="function"?j(u):j!==!1,q=m.handler??R?.handler;if(!q)return null;const se=async()=>{await Promise.resolve(q(u))};return{id:String(m.id),label:re,disabled:!ie,action:se}}const S=t.computed(()=>{if(!p.visible||!p.target||e.contextmenu===!1)return[];const a=Array.isArray(e.contextmenu)?e.contextmenu:h,u={target:p.target,controller:n};return a.map(m=>N(m,u)).filter(m=>!!m)});async function K(a){a.disabled||(w(),await a.action())}function $(a){return typeof a.title=="string"?a.title:Array.isArray(a.title)&&a.title.length?String(a.title[0]):a.fullPath}function i(a){return!(a.closable===!1||n.options.keepLastTab&&n.tabs.length<=1)}async function s(a){await n.closeTab(a.id)}function c(a){n.activeId.value!==a.id&&n.openTab(a.to,!1)}function k(a){return["router-tab__item",{"is-active":n.activeId.value===a.id,"is-closable":i(a)},a.tabClass]}function E(a){return n.refreshingKey.value===n.getRouteKey(a)}async function P(){const a=d.value;if(!a||!D)return;const u=window.sessionStorage.getItem(a);if(u)try{const m=JSON.parse(u);if(!m||!Array.isArray(m.tabs))return;b=!0,await n.hydrate(m)}catch{}finally{b=!1,B()}}function B(){const a=d.value;if(!(!a||!D||b))try{const u=n.snapshot();window.sessionStorage.setItem(a,JSON.stringify(u))}catch{}}t.onMounted(()=>{document.addEventListener("keydown",w),P()}),t.onBeforeUnmount(()=>{document.removeEventListener("keydown",w),o.appContext.config.globalProperties.$tabs=null,B()}),t.watch(()=>e.keepAlive,a=>{n.options.keepAlive=a}),t.watch(()=>n.activeId.value,()=>w()),t.watch(()=>e.contextmenu,a=>{a||w()}),t.watch(()=>S.value.length,a=>{p.visible&&a===0&&w()}),t.watch(()=>({key:d.value,tabs:n.tabs.map(a=>({to:a.to,title:a.title,tips:a.tips,icon:a.icon,tabClass:a.tabClass,closable:a.closable})),active:n.activeId.value}),()=>{B()},{deep:!0});const ae=n.includeKeys;return{controller:n,tabs:n.tabs,includeKeys:ae,tabTransitionProps:l,pageTransitionProps:f,buildTabClass:k,activate:c,close:s,context:p,menuItems:S,handleMenuAction:K,showContextMenu:A,hideContextMenu:w,tabTitle:$,isClosable:i,isRefreshing:E}}}),Re=(e,o)=>{const r=e.__vccOpts||e;for(const[n,l]of o)r[n]=l;return r},_e={class:"router-tab"},Se={class:"router-tab__header"},Ae={class:"router-tab__slot-start"},Ee={class:"router-tab__scroll"},Pe=["onClick","onAuxclick","onContextmenu"],Ve=["title"],xe=["onClick"],Ne={class:"router-tab__slot-end"},Be={class:"router-tab__container"},Ie=["aria-disabled","onClick"];function Oe(e,o,r,n,l,f){const p=t.resolveComponent("RouterView");return t.openBlock(),t.createElementBlock("div",_e,[t.createElementVNode("header",Se,[t.createElementVNode("div",Ae,[t.renderSlot(e.$slots,"start")]),t.createElementVNode("div",Ee,[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,d=>(t.openBlock(),t.createElementBlock("li",{key:d.id,class:t.normalizeClass(e.buildTabClass(d)),onClick:b=>e.activate(d),onAuxclick:t.withModifiers(b=>e.close(d),["middle","prevent"]),onContextmenu:t.withModifiers(b=>e.showContextMenu(d,b),["prevent"])},[t.createElementVNode("span",{class:"router-tab__item-title",title:e.tabTitle(d)},[d.icon?(t.openBlock(),t.createElementBlock("i",{key:0,class:t.normalizeClass(["router-tab__item-icon",d.icon])},null,2)):t.createCommentVNode("",!0),t.createTextVNode(" "+t.toDisplayString(e.tabTitle(d)),1)],8,Ve),e.isClosable(d)?(t.openBlock(),t.createElementBlock("a",{key:0,class:"router-tab__item-close",onClick:t.withModifiers(b=>e.close(d),["stop"])},null,8,xe)):t.createCommentVNode("",!0)],42,Pe))),128))]),_:1},16)]),t.createElementVNode("div",Ne,[t.renderSlot(e.$slots,"end")])]),t.createElementVNode("div",Be,[t.createVNode(p,null,{default:t.withCtx(({Component:d,route:b})=>[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(b)?t.createCommentVNode("",!0):(t.openBlock(),t.createBlock(t.resolveDynamicComponent(d),{key:e.controller.getRouteKey(b),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(b)?(t.openBlock(),t.createBlock(t.resolveDynamicComponent(d),{key:e.controller.getRouteKey(b)+(e.isRefreshing(b)?"-refresh":""),class:"router-tab-page"})):t.createCommentVNode("",!0)]),_:2},1040)]),_:1})]),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,d=>(t.openBlock(),t.createElementBlock("a",{key:d.id,class:"router-tab__contextmenu-item","aria-disabled":d.disabled,onClick:t.withModifiers(b=>e.handleMenuAction(d),["prevent"])},t.toDisplayString(d.label),9,Ie))),128))],4)):t.createCommentVNode("",!0)])}const U=Re(Ce,[["render",Oe]]);function ne(e={}){const{optional:o=!1}=e,r=t.inject(I,null);if(r)return r;const n=t.inject("$tabs",null);if(n)return n;const f=t.getCurrentInstance()?.appContext.config.globalProperties.$tabs;if(f)return f;if(!o)throw new Error("[RouterTabs] useRouterTabs must be used within <router-tab>.");return null}const Ke="router-tabs:persistent";function $e(e){return typeof window>"u"?null:e===void 0?window.localStorage??null:e}function Me(e){const o=$e(e.storage),r=e.storageKey??Ke;return le.defineStore(e.storeId??"routerTabs",{state:()=>({snapshot:null}),actions:{load(){if(!(!o||this.snapshot))try{const n=o.getItem(r);n&&(this.snapshot=JSON.parse(n))}catch{}},setSnapshot(n){if(this.snapshot=n,!!o)try{n&&n.tabs.length?o.setItem(r,JSON.stringify(n)):o.removeItem(r)}catch{}},clear(){this.setSnapshot(null)}}})}function oe(e={}){const o=ne(),n=(e.store??Me(e))(),l=t.ref(!1);return t.onMounted(async()=>{n.load();const f=n.snapshot;if(f)try{l.value=!0,await o.hydrate(f)}finally{l.value=!1,n.setSnapshot(o.snapshot())}}),t.watch(()=>({tabs:o.tabs.map(f=>({to:f.to,title:f.title,tips:f.tips,icon:f.icon,tabClass:f.tabClass,closable:f.closable})),active:o.activeId.value}),()=>{l.value||n.setSnapshot(o.snapshot())},{deep:!0}),n}const je={class:"router-tabs-pinia","aria-hidden":"true"},Le=t.defineComponent({__name:"RouterTabsPinia",props:{storeId:{},storageKey:{},storage:{},store:{type:[Function,Object]}},setup(e){return oe(e),(r,n)=>(t.openBlock(),t.createElementBlock("span",je))}}),J={install(e){J._installed||(J._installed=!0,e.component(U.name,U),Object.defineProperty(e.config.globalProperties,"$tabs",{configurable:!0,enumerable:!1,get(){return e._context.provides[I]},set(o){o&&e.provide(I,o)}}))}};exports.RouterTab=U;exports.RouterTabsPinia=Le;exports.default=J;exports.routerTabsKey=I;exports.useRouterTabs=ne;exports.useRouterTabsPiniaPersistence=oe;
|