@robot-admin/layout 3.1.0 → 3.2.1

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.
@@ -0,0 +1,739 @@
1
+ import { computed as e, defineComponent as t, getCurrentScope as n, h as r, inject as i, nextTick as a, onMounted as o, onScopeDispose as s, onUnmounted as c, provide as l, ref as u, toValue as d, watch as f } from "vue";
2
+ import { useRoute as p, useRouter as m } from "vue-router";
3
+ import { defineStore as h } from "pinia";
4
+ //#region src/composables/useLayoutContext.ts
5
+ var g = Symbol("layout-context"), _ = Symbol("layout-settings"), v = Symbol("menu-collapse"), y = Symbol("drawer-handlers");
6
+ function b() {
7
+ let e = i(g);
8
+ if (!e) throw Error("[Layout] LayoutContext not provided. 请在上层组件中使用 provide(LAYOUT_CONTEXT_KEY, ...) 注入布局数据。");
9
+ return e;
10
+ }
11
+ function x(e) {
12
+ return l(g, e), e;
13
+ }
14
+ var S = {
15
+ name: "Admin",
16
+ subtitle: "",
17
+ logoSrc: "",
18
+ logoType: "image",
19
+ logoSize: 36,
20
+ homePath: "/home",
21
+ copyright: ""
22
+ };
23
+ //#endregion
24
+ //#region src/composables/useLayoutCache.ts
25
+ function C(e) {
26
+ return typeof e.name == "string" && e.meta.keepAlive === !0;
27
+ }
28
+ function w(e = {}) {
29
+ let { maxCacheCount: t = 20, enableDevLog: n = !1, exposeToWindow: r = !1 } = e, i = p(), a = Number.isFinite(t) && t > 0 ? Math.floor(t) : 20, o = u([]), s = u(a), l = (e) => {
30
+ e && !o.value.includes(e) && (o.value.push(e), o.value.length > s.value && o.value.shift(), n && console.debug(`[KeepAlive] ✅ 缓存: ${e} (${o.value.length}/${s.value})`));
31
+ }, d = (e) => {
32
+ let t = o.value.indexOf(e);
33
+ t > -1 && (o.value.splice(t, 1), n && console.debug(`[KeepAlive] ❌ 移除: ${e}`));
34
+ }, m = () => {
35
+ o.value = [], n && console.debug("[KeepAlive] 🗑️ 清空所有缓存");
36
+ }, h = () => o.value;
37
+ if (r && typeof window < "u") {
38
+ let e = window;
39
+ e.__clearCache__ = m, e.__removeCache__ = d, e.__getCachedViews__ = h, c(() => {
40
+ e.__clearCache__ === m && delete e.__clearCache__, e.__removeCache__ === d && delete e.__removeCache__, e.__getCachedViews__ === h && delete e.__getCachedViews__;
41
+ });
42
+ }
43
+ return f(() => [i.name, i.meta.keepAlive], () => {
44
+ C(i) && l(i.name);
45
+ }, { immediate: !0 }), {
46
+ cachedViews: o,
47
+ maxCacheCount: s,
48
+ addCache: l,
49
+ removeCache: d,
50
+ clearAllCache: m
51
+ };
52
+ }
53
+ //#endregion
54
+ //#region src/composables/useResponsiveMenu.ts
55
+ function T(e) {
56
+ let t = e.meta?.title || e.label || e.name || "", n = 0;
57
+ for (let e of t) {
58
+ let t = e.charCodeAt(0);
59
+ n += t >= 19968 && t <= 40959 || t >= 13312 && t <= 19903 || t >= 12288 && t <= 12351 || t >= 65280 && t <= 65519 || t >= 12352 && t <= 12447 || t >= 12448 && t <= 12543 ? 15 : 8;
60
+ }
61
+ let r = e.meta?.icon || e.icon ? 26 : 0;
62
+ return n + r + 36 + 8 + 8;
63
+ }
64
+ function E(e, t, n = 95) {
65
+ if (e.length === 0 || t <= 0) return 0;
66
+ if (e.reduce((e, t) => e + T(t), 0) + 15 <= t) return e.length;
67
+ let r = Math.max(0, t - n), i = 0, a = 0;
68
+ for (let t of e) {
69
+ let e = T(t);
70
+ if (i + e > r) break;
71
+ i += e, a += 1;
72
+ }
73
+ return Math.max(a, 1);
74
+ }
75
+ function D(t) {
76
+ let n = Number.isFinite(t.debounceMs) && (t.debounceMs ?? 0) >= 0 ? Math.floor(t.debounceMs ?? 100) : 100, r = Number.isFinite(t.overflowReserve) && (t.overflowReserve ?? 0) >= 0 ? t.overflowReserve ?? 95 : 95, i = u(), s = e(() => [...d(t.data)]), l = u([]), p = u([]), m = () => {
77
+ let e = i.value?.offsetWidth ?? 0;
78
+ if (e <= 0 || s.value.length === 0) {
79
+ l.value = [], p.value = [];
80
+ return;
81
+ }
82
+ let t = E(s.value, e, r);
83
+ l.value = s.value.slice(0, t), p.value = s.value.slice(t);
84
+ }, h, g = () => {
85
+ h !== void 0 && clearTimeout(h), h = setTimeout(m, n);
86
+ }, _;
87
+ return o(() => {
88
+ a(m), i.value && typeof ResizeObserver < "u" ? (_ = new ResizeObserver(g), _.observe(i.value)) : typeof window < "u" && window.addEventListener("resize", g, { passive: !0 });
89
+ }), c(() => {
90
+ _?.disconnect(), typeof window < "u" && window.removeEventListener("resize", g), h !== void 0 && clearTimeout(h);
91
+ }), f(() => d(t.data), () => void a(m), { deep: !0 }), {
92
+ containerRef: i,
93
+ hiddenItems: p,
94
+ refresh: m,
95
+ visibleItems: l
96
+ };
97
+ }
98
+ //#endregion
99
+ //#region src/composables/useMenuSplit.ts
100
+ function O(e, t) {
101
+ if (!e) return !1;
102
+ let n = e.split("/").filter(Boolean), r = t.split("/").filter(Boolean);
103
+ return n.length === 0 ? r.length === 0 : n.every((e, t) => r[t] === e);
104
+ }
105
+ function k(t) {
106
+ let { menus: n, floatingSecondMenu: r = !1 } = t, i = p(), a = m(), o = u(""), s = u(null), c = u(!1), l = e(() => s.value || _.value || null), h = (e) => O(e, i.path), g = (e) => {
107
+ for (let t of e) if (h(t.path) || t.children?.length && g(t.children)) return t;
108
+ return null;
109
+ }, _ = e(() => d(n).find((e) => e.path === o.value)), v = e(() => _.value?.children || []), y = (e) => {
110
+ e.disabled || (d(r) ? e.children && e.children.length > 0 ? c.value && o.value === e.path ? c.value = !1 : (o.value = e.path || "", c.value = !0) : (o.value = e.path || "", c.value = !1, e.path && a.push(e.path)) : (!e.children || e.children.length === 0) && e.path && a.push(e.path));
111
+ }, b = (e) => {
112
+ !e.disabled && e.path && a.push(e.path);
113
+ }, x = () => {
114
+ let e = d(n), t = g(e);
115
+ t ? (o.value = t.path || "", d(r) && t.children?.length && (c.value = !0)) : e.length > 0 && !o.value && (o.value = e[0].path || "");
116
+ };
117
+ return f([() => i.path, () => d(n)], () => x(), { immediate: !0 }), {
118
+ activeFirstMenu: o,
119
+ activeFirstMenuItem: _,
120
+ currentSecondMenus: v,
121
+ hoveredMenuItem: s,
122
+ displayMenuItem: l,
123
+ showSecondMenu: c,
124
+ handleFirstMenuClick: y,
125
+ handleSecondMenuClick: b,
126
+ isMenuItemActive: h
127
+ };
128
+ }
129
+ //#endregion
130
+ //#region src/composables/useLayoutIcon.ts
131
+ var A = t({
132
+ name: "FallbackLayoutIcon",
133
+ props: {
134
+ name: String,
135
+ size: {
136
+ type: Number,
137
+ default: 18
138
+ }
139
+ },
140
+ setup(e) {
141
+ return () => r("i", {
142
+ class: e.name,
143
+ style: {
144
+ alignItems: "center",
145
+ display: "inline-flex",
146
+ fontSize: `${e.size}px`,
147
+ justifyContent: "center"
148
+ }
149
+ });
150
+ }
151
+ });
152
+ function j() {
153
+ return b().iconComponent ?? A;
154
+ }
155
+ //#endregion
156
+ //#region src/core/settings.ts
157
+ var M = {
158
+ themeMode: new Set([
159
+ "light",
160
+ "dark",
161
+ "system"
162
+ ]),
163
+ borderRadius: new Set([
164
+ "small",
165
+ "medium",
166
+ "large"
167
+ ]),
168
+ transitionType: new Set([
169
+ "fade",
170
+ "slide",
171
+ "zoom",
172
+ "none"
173
+ ]),
174
+ layoutMode: new Set([
175
+ "side",
176
+ "top",
177
+ "mix",
178
+ "mix-top",
179
+ "reverse-horizontal-mix",
180
+ "card-layout"
181
+ ]),
182
+ menuExpandMode: new Set(["inline", "panel"]),
183
+ tagsViewStyle: new Set([
184
+ "default",
185
+ "card",
186
+ "smart"
187
+ ])
188
+ }, N = new Set([
189
+ "enableTransition",
190
+ "collapsed",
191
+ "fixedHeader",
192
+ "showBreadcrumb",
193
+ "showBreadcrumbIcon",
194
+ "showTagsView",
195
+ "showFooter",
196
+ "enableHotkeys"
197
+ ]), P = {
198
+ tagsViewHeight: [24, 100],
199
+ sidebarWidth: [120, 480],
200
+ sidebarCollapsedWidth: [32, 160],
201
+ headerHeight: [32, 160]
202
+ }, F = 1;
203
+ function I(e) {
204
+ if (e.sidebarCollapsedWidth > e.sidebarWidth) throw RangeError("sidebarCollapsedWidth 不能大于 sidebarWidth");
205
+ }
206
+ function L(e) {
207
+ if (!e || typeof e != "object" || Array.isArray(e)) throw TypeError("settings 必须是对象");
208
+ let t = e, n = {}, r = (e, t) => {
209
+ n[e] = t;
210
+ };
211
+ for (let [e, n] of Object.entries(M)) {
212
+ let i = t[e];
213
+ if (i !== void 0) {
214
+ if (typeof i != "string" || !n.has(i)) throw RangeError(`无效的设置项 ${e}: ${String(i)}`);
215
+ r(e, i);
216
+ }
217
+ }
218
+ for (let e of N) {
219
+ let n = t[e];
220
+ if (n !== void 0) {
221
+ if (typeof n != "boolean") throw TypeError(`设置项 ${e} 必须是布尔值`);
222
+ r(e, n);
223
+ }
224
+ }
225
+ for (let [e, n] of Object.entries(P)) {
226
+ let i = t[e];
227
+ if (i !== void 0) {
228
+ if (typeof i != "number" || !Number.isFinite(i) || i < n[0] || i > n[1]) throw RangeError(`设置项 ${e} 超出允许范围`);
229
+ r(e, i);
230
+ }
231
+ }
232
+ if (t.primaryColor !== void 0) {
233
+ if (typeof t.primaryColor != "string" || !/^#[0-9a-fA-F]{6}$/.test(t.primaryColor)) throw RangeError("primaryColor 必须是 #rrggbb 格式");
234
+ n.primaryColor = t.primaryColor;
235
+ }
236
+ if (t.version !== void 0) {
237
+ if (typeof t.version != "string" || t.version.length > 50) throw TypeError("version 必须是长度不超过 50 的字符串");
238
+ n.version = t.version;
239
+ }
240
+ return n;
241
+ }
242
+ function R(e) {
243
+ if (!e || typeof e != "object" || Array.isArray(e)) throw TypeError("配置文件根节点必须是对象");
244
+ let t = e, n = {};
245
+ if (t.schemaVersion !== void 0) {
246
+ if (typeof t.schemaVersion != "number" || !Number.isInteger(t.schemaVersion) || t.schemaVersion < 1 || t.schemaVersion > 1) throw RangeError("不支持的配置格式版本");
247
+ n.schemaVersion = t.schemaVersion;
248
+ }
249
+ t.settings !== void 0 && (n.settings = L(t.settings));
250
+ for (let e of ["gray", "colorWeak"]) {
251
+ let r = t[e];
252
+ if (r !== void 0) {
253
+ if (typeof r != "boolean") throw TypeError(`${e} 必须是布尔值`);
254
+ n[e] = r;
255
+ }
256
+ }
257
+ if (t.watermark !== void 0) {
258
+ if (!t.watermark || typeof t.watermark != "object" || Array.isArray(t.watermark)) throw TypeError("watermark 必须是对象");
259
+ let e = t.watermark;
260
+ if (typeof e.enabled != "boolean" || typeof e.text != "string" || e.text.length > 200) throw TypeError("watermark 配置无效");
261
+ n.watermark = {
262
+ enabled: e.enabled,
263
+ text: e.text
264
+ };
265
+ }
266
+ return n;
267
+ }
268
+ function z(e, t) {
269
+ if (typeof e != "string") return "#000000";
270
+ if (!Number.isFinite(t)) return e;
271
+ let n = Math.round(t), r = e.trim(), i = r.startsWith("#") ? r.slice(1) : r;
272
+ if (i.length === 3 && (i = i.split("").map((e) => e + e).join("")), !/^[0-9a-fA-F]{6}$/.test(i)) return e;
273
+ let a = parseInt(i, 16), o = Math.min(255, Math.max(0, (a >> 16) + n)), s = Math.min(255, Math.max(0, (a >> 8 & 255) + n)), c = Math.min(255, Math.max(0, (a & 255) + n));
274
+ return `#${(o << 16 | s << 8 | c).toString(16).padStart(6, "0")}`;
275
+ }
276
+ //#endregion
277
+ //#region src/constants/index.ts
278
+ var B = [
279
+ {
280
+ name: "拂晓蓝",
281
+ value: "#409eff"
282
+ },
283
+ {
284
+ name: "薄暮红",
285
+ value: "#f5222d"
286
+ },
287
+ {
288
+ name: "火山橙",
289
+ value: "#fa541c"
290
+ },
291
+ {
292
+ name: "日暮黄",
293
+ value: "#faad14"
294
+ },
295
+ {
296
+ name: "极光绿",
297
+ value: "#52c41a"
298
+ },
299
+ {
300
+ name: "明青",
301
+ value: "#13c2c2"
302
+ },
303
+ {
304
+ name: "极客蓝",
305
+ value: "#2f54eb"
306
+ },
307
+ {
308
+ name: "酱紫",
309
+ value: "#722ed1"
310
+ }
311
+ ], V = [
312
+ {
313
+ name: "科技蓝",
314
+ icon: "💙",
315
+ primaryColor: "#409eff"
316
+ },
317
+ {
318
+ name: "清新绿",
319
+ icon: "💚",
320
+ primaryColor: "#52c41a"
321
+ },
322
+ {
323
+ name: "商务灰",
324
+ icon: "🖤",
325
+ primaryColor: "#595959"
326
+ },
327
+ {
328
+ name: "活力橙",
329
+ icon: "🧡",
330
+ primaryColor: "#fa8c16"
331
+ },
332
+ {
333
+ name: "优雅紫",
334
+ icon: "💜",
335
+ primaryColor: "#722ed1"
336
+ },
337
+ {
338
+ name: "经典红",
339
+ icon: "❤️",
340
+ primaryColor: "#f5222d"
341
+ }
342
+ ], H = [
343
+ {
344
+ mode: "side",
345
+ label: "左侧菜单",
346
+ description: "经典的左侧导航布局",
347
+ icon: "i-mdi:page-layout-sidebar-left"
348
+ },
349
+ {
350
+ mode: "top",
351
+ label: "顶部菜单",
352
+ description: "顶部水平导航布局",
353
+ icon: "i-mdi:page-layout-header"
354
+ },
355
+ {
356
+ mode: "mix",
357
+ label: "混合菜单",
358
+ description: "顶部 + 侧边混合布局",
359
+ icon: "i-mdi:view-dashboard-outline"
360
+ },
361
+ {
362
+ mode: "mix-top",
363
+ label: "顶部混合",
364
+ description: "侧边优先的混合布局",
365
+ icon: "i-mdi:view-dashboard-variant-outline"
366
+ },
367
+ {
368
+ mode: "reverse-horizontal-mix",
369
+ label: "反转混合",
370
+ description: "反转的水平混合布局",
371
+ icon: "i-mdi:page-layout-header-footer"
372
+ },
373
+ {
374
+ mode: "card-layout",
375
+ label: "卡片布局",
376
+ description: "卡片式布局风格",
377
+ icon: "i-mdi:card-outline"
378
+ }
379
+ ], U = {
380
+ small: "4px",
381
+ medium: "6px",
382
+ large: "8px"
383
+ }, W = {
384
+ fade: "fade-transform",
385
+ slide: "fade-slide",
386
+ zoom: "fade-zoom",
387
+ none: ""
388
+ }, G = {
389
+ themeMode: "light",
390
+ primaryColor: "#409eff",
391
+ borderRadius: "medium",
392
+ transitionType: "slide",
393
+ enableTransition: !0,
394
+ layoutMode: "side",
395
+ menuExpandMode: "inline",
396
+ collapsed: !1,
397
+ fixedHeader: !0,
398
+ showBreadcrumb: !0,
399
+ showBreadcrumbIcon: !0,
400
+ showTagsView: !0,
401
+ tagsViewHeight: 44,
402
+ tagsViewStyle: "default",
403
+ showFooter: !0,
404
+ sidebarWidth: 220,
405
+ sidebarCollapsedWidth: 64,
406
+ headerHeight: 56,
407
+ enableHotkeys: !0,
408
+ version: "3.2.1"
409
+ }, K = B.map((e) => e.value), q = () => typeof document > "u" ? void 0 : document.documentElement;
410
+ function J(e, t) {
411
+ let n = d(e.primaryColor), r = {
412
+ "primary-color": n,
413
+ "primary-color-hover": z(n, 10),
414
+ "primary-color-pressed": z(n, -10),
415
+ "border-radius": d(e.borderRadiusValue),
416
+ "sidebar-width": `${d(e.sidebarWidth)}px`,
417
+ "sidebar-collapsed-width": `${d(e.sidebarCollapsedWidth)}px`,
418
+ "header-height": `${d(e.headerHeight)}px`,
419
+ "tags-view-height": `${d(e.tagsViewHeight)}px`
420
+ };
421
+ return Object.entries(r).flatMap(([e, n]) => {
422
+ let r = [[`--ra-layout-${e}`, n]];
423
+ return t && r.push([`--${e}`, n]), r;
424
+ });
425
+ }
426
+ function Y(e, t = {}) {
427
+ let n, r = /* @__PURE__ */ new Map(), i = !1, a = () => {
428
+ if (n) {
429
+ for (let [e, t] of r) t ? n.style.setProperty(e, t) : n.style.removeProperty(e);
430
+ n = void 0, r = /* @__PURE__ */ new Map();
431
+ }
432
+ }, o = () => {
433
+ if (i) return;
434
+ let o = t.target ? d(t.target) ?? void 0 : q();
435
+ if (!o) {
436
+ a();
437
+ return;
438
+ }
439
+ let s = J(e, t.legacyAliases ?? !1);
440
+ n !== o && (a(), n = o, r = new Map(s.map(([e]) => [e, o.style.getPropertyValue(e)])));
441
+ for (let [e, t] of s) o.style.setProperty(e, t);
442
+ }, s = f(() => [
443
+ d(e.primaryColor),
444
+ d(e.borderRadiusValue),
445
+ d(e.sidebarWidth),
446
+ d(e.sidebarCollapsedWidth),
447
+ d(e.headerHeight),
448
+ d(e.tagsViewHeight),
449
+ t.target ? d(t.target) : void 0
450
+ ], o, { immediate: !0 });
451
+ return {
452
+ dispose: () => {
453
+ i || (i = !0, s(), a());
454
+ },
455
+ sync: o
456
+ };
457
+ }
458
+ function ee(e, t = {}) {
459
+ let r = Y(e, t);
460
+ return n() && s(r.dispose), r;
461
+ }
462
+ //#endregion
463
+ //#region src/stores/settings.ts
464
+ function X(t = {}) {
465
+ let { id: n = "settings", defaults: r = {}, onThemeModeChange: i, syncCssVariables: a = !0 } = t;
466
+ if (typeof n != "string" || !n.trim()) throw RangeError("Settings store id 不能为空");
467
+ let o = {
468
+ ...G,
469
+ ...L(r)
470
+ };
471
+ I(o);
472
+ let c = Object.freeze({ ...o });
473
+ return h(n, () => {
474
+ let t = u(o.themeMode), n = u(o.primaryColor), r = u(o.borderRadius), l = u(o.transitionType), d = u(o.enableTransition), f = u(o.layoutMode), p = u(o.menuExpandMode), m = u(o.collapsed), h = u(o.fixedHeader), g = u(o.showBreadcrumb), _ = u(o.showBreadcrumbIcon), v = u(o.showTagsView), y = u(o.tagsViewHeight), b = u(o.tagsViewStyle), x = u(o.showFooter), S = u(o.sidebarWidth), C = u(o.sidebarCollapsedWidth), w = u(o.headerHeight), T = u(o.enableHotkeys), E = u(o.version), D = e(() => U[r.value]), O = e(() => d.value && l.value !== "none"), k = e(() => O.value ? W[l.value] : ""), A = e(() => ({
475
+ themeMode: t.value,
476
+ primaryColor: n.value,
477
+ borderRadius: r.value,
478
+ transitionType: l.value,
479
+ enableTransition: d.value,
480
+ layoutMode: f.value,
481
+ menuExpandMode: p.value,
482
+ collapsed: m.value,
483
+ fixedHeader: h.value,
484
+ showBreadcrumb: g.value,
485
+ showBreadcrumbIcon: _.value,
486
+ showTagsView: v.value,
487
+ tagsViewHeight: y.value,
488
+ tagsViewStyle: b.value,
489
+ showFooter: x.value,
490
+ sidebarWidth: S.value,
491
+ sidebarCollapsedWidth: C.value,
492
+ headerHeight: w.value,
493
+ enableHotkeys: T.value,
494
+ version: E.value
495
+ })), j = a ? Y({
496
+ primaryColor: n,
497
+ borderRadiusValue: D,
498
+ sidebarWidth: S,
499
+ sidebarCollapsedWidth: C,
500
+ headerHeight: w,
501
+ tagsViewHeight: y
502
+ }, { legacyAliases: !0 }) : void 0;
503
+ return j && s(j.dispose), {
504
+ defaults: c,
505
+ themeMode: t,
506
+ primaryColor: n,
507
+ borderRadius: r,
508
+ transitionType: l,
509
+ enableTransition: d,
510
+ layoutMode: f,
511
+ menuExpandMode: p,
512
+ collapsed: m,
513
+ fixedHeader: h,
514
+ showBreadcrumb: g,
515
+ showBreadcrumbIcon: _,
516
+ showTagsView: v,
517
+ tagsViewHeight: y,
518
+ tagsViewStyle: b,
519
+ showFooter: x,
520
+ sidebarWidth: S,
521
+ sidebarCollapsedWidth: C,
522
+ headerHeight: w,
523
+ enableHotkeys: T,
524
+ version: E,
525
+ borderRadiusValue: D,
526
+ transitionName: k,
527
+ shouldEnableTransition: O,
528
+ settingsState: A,
529
+ syncCSSVariables: () => j?.sync(),
530
+ applyPreset: async (e) => {
531
+ let t = L({
532
+ primaryColor: e.primaryColor,
533
+ ...e.settings
534
+ });
535
+ n.value = t.primaryColor, t.borderRadius && (r.value = t.borderRadius), t.transitionType && (l.value = t.transitionType), t.showBreadcrumb !== void 0 && (g.value = t.showBreadcrumb), t.showTagsView !== void 0 && (v.value = t.showTagsView), t.tagsViewStyle && (b.value = t.tagsViewStyle);
536
+ },
537
+ resetSettings: () => {
538
+ t.value = o.themeMode, n.value = o.primaryColor, r.value = o.borderRadius, l.value = o.transitionType, d.value = o.enableTransition, f.value = o.layoutMode, p.value = o.menuExpandMode, m.value = o.collapsed, h.value = o.fixedHeader, g.value = o.showBreadcrumb, _.value = o.showBreadcrumbIcon, v.value = o.showTagsView, y.value = o.tagsViewHeight, b.value = o.tagsViewStyle, x.value = o.showFooter, S.value = o.sidebarWidth, C.value = o.sidebarCollapsedWidth, w.value = o.headerHeight, T.value = o.enableHotkeys, E.value = o.version;
539
+ },
540
+ updateThemeMode: async (e) => {
541
+ L({ themeMode: e });
542
+ let n = t.value;
543
+ t.value = e;
544
+ try {
545
+ i && await i(e);
546
+ } catch (e) {
547
+ throw t.value = n, e;
548
+ }
549
+ },
550
+ toggleCollapse: () => {
551
+ m.value = !m.value;
552
+ }
553
+ };
554
+ });
555
+ }
556
+ var te = X();
557
+ //#endregion
558
+ //#region src/setup.ts
559
+ function ne(e, t = {}) {
560
+ let n = X(t), r = n();
561
+ return e.provide(_, r), n;
562
+ }
563
+ //#endregion
564
+ //#region src/utils/menu.ts
565
+ function Z(e) {
566
+ return e.flatMap((e) => {
567
+ let t = e.path || e.key;
568
+ if (!t) return [];
569
+ let n = e.meta?.title || e.label || e.name || t, r = e.meta?.icon ?? (typeof e.icon == "string" ? e.icon : void 0), i = {
570
+ ...e.meta,
571
+ title: n,
572
+ ...r ? { icon: r } : {}
573
+ };
574
+ return [{
575
+ ...e,
576
+ key: e.key || t,
577
+ path: t,
578
+ meta: i,
579
+ children: e.children ? Z(e.children) : void 0
580
+ }];
581
+ });
582
+ }
583
+ //#endregion
584
+ //#region src/composables/createLayoutContext.ts
585
+ function Q(t) {
586
+ let { settings: n } = t;
587
+ return {
588
+ menus: e(() => d(t.menus)),
589
+ isDark: e(() => d(t.isDark)),
590
+ layoutMode: e(() => n.layoutMode),
591
+ collapsed: e({
592
+ get: () => n.collapsed,
593
+ set: (e) => {
594
+ n.collapsed = e;
595
+ }
596
+ }),
597
+ menuExpandMode: e(() => n.menuExpandMode),
598
+ sidebarWidth: e(() => n.sidebarWidth),
599
+ sidebarCollapsedWidth: e(() => n.sidebarCollapsedWidth),
600
+ showFooter: e(() => n.showFooter),
601
+ showTagsView: e(() => n.showTagsView),
602
+ tagsViewHeight: e(() => n.tagsViewHeight),
603
+ headerHeight: e(() => n.headerHeight),
604
+ transitionName: e(() => n.transitionName),
605
+ showBreadcrumb: e(() => n.showBreadcrumb),
606
+ showBreadcrumbIcon: e(() => n.showBreadcrumbIcon),
607
+ fixedHeader: e(() => n.fixedHeader),
608
+ brand: {
609
+ ...S,
610
+ ...t.brand
611
+ },
612
+ iconComponent: t.iconComponent
613
+ };
614
+ }
615
+ function re(e) {
616
+ return x(Q(e));
617
+ }
618
+ //#endregion
619
+ //#region src/composables/useSettingsController.ts
620
+ var $ = class extends Error {
621
+ constructor(e) {
622
+ super(`[Layout] Host action "${e}" is not configured.`), this.name = "LayoutActionUnavailableError";
623
+ }
624
+ }, ie = () => typeof document > "u" ? void 0 : document;
625
+ function ae(t) {
626
+ let { store: r } = t, i = t.visualRoot?.ownerDocument ?? t.watermarkContainer?.ownerDocument ?? ie(), a = t.visualRoot ?? i?.documentElement, o = t.watermarkContainer ?? i?.body, c = Number.isFinite(t.maxImportBytes) && (t.maxImportBytes ?? 0) > 0 ? Math.floor(t.maxImportBytes ?? 1024 * 1024) : 1024 * 1024, l = a?.classList.contains("gray-mode") ?? !1, d = a?.classList.contains("color-weak-mode") ?? !1, p = u(l), m = u(d), h = u(!1), g = u(t.watermarkText ?? "Robot Admin"), _, v = () => {
627
+ _?.remove(), _ = void 0;
628
+ }, y = (e) => {
629
+ if (v(), !i || !o) return;
630
+ let n = i.createElement("canvas"), r = n.getContext("2d");
631
+ if (!r) {
632
+ t.onVisualEffectError?.("当前浏览器无法创建水印画布");
633
+ return;
634
+ }
635
+ n.width = 200, n.height = 150, r.font = "14px Microsoft JhengHei", r.fillStyle = "rgba(120, 120, 120, 0.15)", r.rotate(-20 * Math.PI / 180), r.fillText(e, 0, 80), _ = i.createElement("div"), _.dataset.robotAdminLayoutWatermark = "true", Object.assign(_.style, {
636
+ backgroundImage: `url(${n.toDataURL()})`,
637
+ backgroundRepeat: "repeat",
638
+ height: "100%",
639
+ left: "0",
640
+ pointerEvents: "none",
641
+ position: "fixed",
642
+ top: "0",
643
+ userSelect: "none",
644
+ width: "100%",
645
+ zIndex: "9999"
646
+ }), o.appendChild(_);
647
+ }, b = f(p, (e) => a?.classList.toggle("gray-mode", e)), x = f(m, (e) => a?.classList.toggle("color-weak-mode", e)), S = f(h, (e) => {
648
+ e ? y(g.value) : v();
649
+ }), C = f(g, (e) => {
650
+ h.value && y(e);
651
+ }), w = e(() => {
652
+ let e = i?.defaultView, t = e?.navigator;
653
+ if (!e || !t) return {
654
+ browser: "Unknown",
655
+ os: "Unknown",
656
+ resolution: "Unknown",
657
+ pixelRatio: "Unknown",
658
+ language: "Unknown",
659
+ timezone: "Unknown"
660
+ };
661
+ let n = t.userAgent, r = "Unknown", a = "Unknown";
662
+ return n.includes("Edg/") ? r = "Edge" : n.includes("Firefox") ? r = "Firefox" : n.includes("Chrome") ? r = "Chrome" : n.includes("Safari") && (r = "Safari"), n.includes("Windows") ? a = "Windows" : n.includes("Mac") ? a = "macOS" : n.includes("Android") ? a = "Android" : n.includes("iOS") ? a = "iOS" : n.includes("Linux") && (a = "Linux"), {
663
+ browser: r,
664
+ os: a,
665
+ resolution: `${e.screen.width} × ${e.screen.height}`,
666
+ pixelRatio: `${e.devicePixelRatio}x`,
667
+ language: t.language,
668
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
669
+ };
670
+ }), T = (e) => r.applyPreset(e), E = (e) => r.updateThemeMode(e), D = async () => {
671
+ await r.updateThemeMode(r.defaults.themeMode), r.primaryColor = r.defaults.primaryColor, r.borderRadius = r.defaults.borderRadius, r.transitionType = r.defaults.transitionType, r.enableTransition = r.defaults.enableTransition;
672
+ }, O = () => {
673
+ r.layoutMode = r.defaults.layoutMode, r.menuExpandMode = r.defaults.menuExpandMode, r.fixedHeader = r.defaults.fixedHeader, r.showBreadcrumb = r.defaults.showBreadcrumb, r.showBreadcrumbIcon = r.defaults.showBreadcrumbIcon, r.showTagsView = r.defaults.showTagsView, r.tagsViewHeight = r.defaults.tagsViewHeight, r.tagsViewStyle = r.defaults.tagsViewStyle, r.showFooter = r.defaults.showFooter, r.sidebarWidth = r.defaults.sidebarWidth, r.sidebarCollapsedWidth = r.defaults.sidebarCollapsedWidth, r.headerHeight = r.defaults.headerHeight;
674
+ }, k = async () => {
675
+ let e = { ...r.settingsState };
676
+ try {
677
+ r.resetSettings(), await r.updateThemeMode(r.themeMode);
678
+ } catch (t) {
679
+ throw r.$patch(e), t;
680
+ }
681
+ }, A = async () => {
682
+ if (!t.actions?.clearCache) throw new $("clearCache");
683
+ await t.actions.clearCache();
684
+ }, j = () => {
685
+ t.actions?.reloadPage ? t.actions.reloadPage() : i?.defaultView?.location.reload();
686
+ }, M = () => ({
687
+ schemaVersion: 1,
688
+ settings: r.settingsState,
689
+ gray: p.value,
690
+ colorWeak: m.value,
691
+ watermark: {
692
+ enabled: h.value,
693
+ text: g.value
694
+ },
695
+ exportTime: (/* @__PURE__ */ new Date()).toISOString()
696
+ }), N = () => {
697
+ if (!i || typeof Blob > "u" || typeof URL > "u" || typeof URL.createObjectURL != "function") return !1;
698
+ let e = new Blob([JSON.stringify(M(), null, 2)], { type: "application/json" }), t = URL.createObjectURL(e), n = i.createElement("a");
699
+ return n.href = t, n.download = `robot-admin-config-${Date.now()}.json`, n.click(), URL.revokeObjectURL(t), !0;
700
+ }, P = async (e) => {
701
+ let t = R(e);
702
+ if (I({
703
+ ...r.settingsState,
704
+ ...t.settings
705
+ }), t.settings !== void 0) {
706
+ let { themeMode: e, ...n } = t.settings;
707
+ e !== void 0 && await r.updateThemeMode(e), r.$patch(n);
708
+ }
709
+ return t.gray !== void 0 && (p.value = t.gray), t.colorWeak !== void 0 && (m.value = t.colorWeak), t.watermark !== void 0 && (h.value = t.watermark.enabled, g.value = t.watermark.text), t;
710
+ }, F = async (e) => {
711
+ if (e.size > c) throw RangeError("配置文件过大");
712
+ return P(JSON.parse(await e.text()));
713
+ }, L = !1, z = () => {
714
+ L || (L = !0, b(), x(), S(), C(), v(), a?.classList.toggle("gray-mode", l), a?.classList.toggle("color-weak-mode", d));
715
+ };
716
+ return n() && s(z), {
717
+ applyImportedConfig: P,
718
+ applyPreset: T,
719
+ clearCache: A,
720
+ colorWeakMode: m,
721
+ createExportConfig: M,
722
+ dispose: z,
723
+ downloadConfig: N,
724
+ grayMode: p,
725
+ importFile: F,
726
+ reloadPage: j,
727
+ resetAll: k,
728
+ resetAppearance: D,
729
+ resetLayout: O,
730
+ systemInfo: w,
731
+ updateThemeMode: E,
732
+ watermarkEnabled: h,
733
+ watermarkText: g
734
+ };
735
+ }
736
+ //#endregion
737
+ export { w as A, j as C, T as D, E, v as F, x as I, b as L, y as M, g as N, D as O, _ as P, L as S, k as T, W as _, Z as a, I as b, te as c, U as d, K as f, V as g, B as h, re as i, S as j, C as k, Y as l, H as m, ae as n, ne as o, G as p, Q as r, X as s, $ as t, ee as u, F as v, O as w, R as x, z as y };
738
+
739
+ //# sourceMappingURL=vue-h8jl2I5K.js.map