dishui 0.0.82 → 0.0.83
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.
- package/dist/components/Button/index.d.ts +1 -0
- package/dist/components/Button/index.js.map +1 -1
- package/dist/components/ButtonMenu/index.d.ts +28 -0
- package/dist/components/ButtonMenu/index.js +197 -0
- package/dist/components/ButtonMenu/index.js.map +1 -0
- package/dist/components/Demo/index.d.ts +5 -0
- package/dist/components/Demo/index.js +131 -56
- package/dist/components/Demo/index.js.map +1 -1
- package/dist/components/Demo/source.d.ts +9 -0
- package/dist/components/Demo/source.js +32 -0
- package/dist/components/Demo/source.js.map +1 -0
- package/dist/components/Field/index.d.ts +8 -0
- package/dist/components/Field/index.js +43 -0
- package/dist/components/Field/index.js.map +1 -0
- package/dist/components/LayoutSuite/DashboardSuite.d.ts +35 -0
- package/dist/components/LayoutSuite/DashboardSuite.js +61 -0
- package/dist/components/LayoutSuite/DashboardSuite.js.map +1 -0
- package/dist/components/LayoutSuite/index.d.ts +56 -0
- package/dist/components/LayoutSuite/index.js +101 -0
- package/dist/components/LayoutSuite/index.js.map +1 -0
- package/dist/components/Modal/focusScope.d.ts +1 -0
- package/dist/components/Modal/focusScope.js +81 -0
- package/dist/components/Modal/focusScope.js.map +1 -0
- package/dist/components/Modal/index.d.ts +4 -1
- package/dist/components/Modal/index.js +48 -43
- package/dist/components/Modal/index.js.map +1 -1
- package/dist/components/Page/Float.d.ts +14 -0
- package/dist/components/Page/Float2.js +154 -0
- package/dist/components/Page/Float2.js.map +1 -0
- package/dist/components/Page/index.d.ts +18 -5
- package/dist/components/Page/index.js +103 -34
- package/dist/components/Page/index.js.map +1 -1
- package/dist/components/Page/resize.d.ts +28 -0
- package/dist/components/Page/resize2.js +95 -0
- package/dist/components/Page/resize2.js.map +1 -0
- package/dist/components/PageHeader/index.d.ts +10 -3
- package/dist/components/PageHeader/index.js +46 -25
- package/dist/components/PageHeader/index.js.map +1 -1
- package/dist/components/PagePanel/index.d.ts +29 -0
- package/dist/components/PagePanel/index.js +99 -0
- package/dist/components/PagePanel/index.js.map +1 -0
- package/dist/components/Resizable/ResizeGrip.d.ts +5 -0
- package/dist/components/Resizable/ResizeGrip.js +14 -0
- package/dist/components/Resizable/ResizeGrip.js.map +1 -0
- package/dist/components/Resizable/index.js +57 -59
- package/dist/components/Resizable/index.js.map +1 -1
- package/dist/components/Resizable/useResize.d.ts +6 -0
- package/dist/components/Resizable/useResize.js +29 -28
- package/dist/components/Resizable/useResize.js.map +1 -1
- package/dist/components/SidebarToggleButton/index.d.ts +5 -3
- package/dist/components/SidebarToggleButton/index.js +24 -21
- package/dist/components/SidebarToggleButton/index.js.map +1 -1
- package/dist/components/Table/index.d.ts +10 -12
- package/dist/components/Table/index.js +25 -20
- package/dist/components/Table/index.js.map +1 -1
- package/dist/components/Text/index.d.ts +1 -1
- package/dist/components/Text/index.js +11 -10
- package/dist/components/Text/index.js.map +1 -1
- package/dist/components/Textarea/index.d.ts +14 -0
- package/dist/components/Textarea/index.js +44 -0
- package/dist/components/Textarea/index.js.map +1 -0
- package/dist/components/Tree/Tree.d.ts +2 -0
- package/dist/components/Tree/Tree.js +49 -40
- package/dist/components/Tree/Tree.js.map +1 -1
- package/dist/dishui.css +1 -1
- package/dist/index-nostyled.d.ts +9 -0
- package/dist/index.d.ts +11 -2
- package/dist/index.js +119 -113
- package/dist/layouts/Sidebar.d.ts +12 -1
- package/dist/layouts/Sidebar.js +121 -97
- package/dist/layouts/Sidebar.js.map +1 -1
- package/dist/lite.d.ts +10 -2
- package/dist/lite.js +17 -12
- package/dist/utils/menu.js +14 -16
- package/dist/utils/menu.js.map +1 -1
- package/package.json +3 -1
package/dist/layouts/Sidebar.js
CHANGED
|
@@ -1,41 +1,55 @@
|
|
|
1
|
-
import
|
|
2
|
-
import t from "../
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
1
|
+
import e from "../components/Text/index.js";
|
|
2
|
+
import { getMenuItems as t } from "../utils/menu.js";
|
|
3
|
+
import { generateSidebarActiveStyles as n } from "../styles/themeStyles.js";
|
|
4
|
+
import r from "../components/Tree/Tree.js";
|
|
5
|
+
import { DesktopSidebarToggleButton as i } from "../components/SidebarToggleButton/index.js";
|
|
6
|
+
import { useEffect as a, useMemo as o, useRef as s, useState as c } from "react";
|
|
7
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
8
|
+
import { useNavigate as d, useRouterState as f } from "@tanstack/react-router";
|
|
8
9
|
//#region src/layouts/Sidebar.tsx
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
var p = [
|
|
11
|
+
{
|
|
12
|
+
size: "base",
|
|
13
|
+
weight: "semibold"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
size: "sm",
|
|
17
|
+
weight: "medium"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
size: "sm",
|
|
21
|
+
weight: "normal"
|
|
22
|
+
}
|
|
23
|
+
], m = ({ isCollapsed: m, side: h = "left", language: g, items: _, levelText: v, getMenuItems: y, onWidthChange: b, initialWidth: x = 280, collapsedWidth: S = 64, onToggle: C, minWidth: w = 160, maxWidth: T = 400 }) => {
|
|
24
|
+
let [E, D] = c([]), [O, k] = c(""), [A, j] = c(() => Math.max(w, Math.min(x, T))), M = s(null), N = s(null), P = f({ select: (e) => e.location }), F = d();
|
|
25
|
+
a(() => {
|
|
26
|
+
j(Math.max(w, Math.min(x, T)));
|
|
13
27
|
}, [
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
28
|
+
x,
|
|
29
|
+
w,
|
|
30
|
+
T
|
|
17
31
|
]);
|
|
18
|
-
let
|
|
19
|
-
let t = Math.max(
|
|
20
|
-
|
|
32
|
+
let I = (e) => {
|
|
33
|
+
let t = Math.max(w, Math.min(e, T));
|
|
34
|
+
j(t), b?.(t);
|
|
21
35
|
};
|
|
22
|
-
|
|
23
|
-
|
|
36
|
+
a(() => {
|
|
37
|
+
D(_ === void 0 ? y ? y(g) : t(g) : _);
|
|
24
38
|
}, [
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
]),
|
|
29
|
-
if (!
|
|
39
|
+
g,
|
|
40
|
+
_,
|
|
41
|
+
y
|
|
42
|
+
]), a(() => {
|
|
43
|
+
if (!O) return;
|
|
30
44
|
let e = setTimeout(() => {
|
|
31
|
-
|
|
45
|
+
N.current?.querySelector(".tree-node-content-active")?.scrollIntoView({
|
|
32
46
|
block: "nearest",
|
|
33
47
|
behavior: "smooth"
|
|
34
48
|
});
|
|
35
49
|
}, 350);
|
|
36
50
|
return () => clearTimeout(e);
|
|
37
|
-
}, [
|
|
38
|
-
let e =
|
|
51
|
+
}, [O]), a(() => {
|
|
52
|
+
let e = N.current;
|
|
39
53
|
if (!e) return;
|
|
40
54
|
let t = (t) => {
|
|
41
55
|
if (e.scrollHeight <= e.clientHeight) return;
|
|
@@ -46,35 +60,35 @@ var f = ({ isCollapsed: f, language: p, items: m, getMenuItems: h, onWidthChange
|
|
|
46
60
|
};
|
|
47
61
|
return e.addEventListener("wheel", t, { passive: !1 }), () => e.removeEventListener("wheel", t);
|
|
48
62
|
}, []);
|
|
49
|
-
let
|
|
63
|
+
let L = (e, t = !0) => e.map((e) => ({
|
|
50
64
|
id: e.id,
|
|
51
65
|
label: e.label,
|
|
52
|
-
icon: e.icon || (t ? void 0 : /* @__PURE__ */
|
|
66
|
+
icon: e.icon || (t ? void 0 : /* @__PURE__ */ l("svg", {
|
|
53
67
|
xmlns: "http://www.w3.org/2000/svg",
|
|
54
68
|
className: "h-4 w-4",
|
|
55
69
|
fill: "none",
|
|
56
70
|
viewBox: "0 0 24 24",
|
|
57
71
|
stroke: "currentColor",
|
|
58
|
-
children: /* @__PURE__ */
|
|
72
|
+
children: /* @__PURE__ */ l("path", {
|
|
59
73
|
strokeLinecap: "round",
|
|
60
74
|
strokeLinejoin: "round",
|
|
61
75
|
strokeWidth: "2",
|
|
62
76
|
d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
|
63
77
|
})
|
|
64
78
|
})),
|
|
65
|
-
children: e.children ?
|
|
79
|
+
children: e.children ? L(e.children, !1) : void 0,
|
|
66
80
|
meta: { path: e.path }
|
|
67
|
-
})),
|
|
68
|
-
if (
|
|
81
|
+
})), R = o(() => L(E, !0), [E]), z = o(() => {
|
|
82
|
+
if (E.length === 0) return [];
|
|
69
83
|
let e = (t) => {
|
|
70
84
|
let n = [];
|
|
71
85
|
for (let r of t) r.children?.length && (n.push(r.id), n = [...n, ...e(r.children)]);
|
|
72
86
|
return n;
|
|
73
87
|
};
|
|
74
|
-
return e(
|
|
75
|
-
}, [
|
|
76
|
-
return
|
|
77
|
-
let e =
|
|
88
|
+
return e(E);
|
|
89
|
+
}, [E]);
|
|
90
|
+
return a(() => {
|
|
91
|
+
let e = P.pathname, t = (n) => {
|
|
78
92
|
for (let r of n) {
|
|
79
93
|
if (r.path === e) return r.id;
|
|
80
94
|
if (r.children) {
|
|
@@ -83,77 +97,79 @@ var f = ({ isCollapsed: f, language: p, items: m, getMenuItems: h, onWidthChange
|
|
|
83
97
|
}
|
|
84
98
|
}
|
|
85
99
|
return null;
|
|
86
|
-
}, n = t(
|
|
87
|
-
n &&
|
|
88
|
-
}, [
|
|
89
|
-
ref:
|
|
100
|
+
}, n = t(E);
|
|
101
|
+
n && k(n);
|
|
102
|
+
}, [E, P.pathname]), m ? /* @__PURE__ */ u("div", {
|
|
103
|
+
ref: M,
|
|
90
104
|
className: "blade-sidebar h-full bg-base-200 overflow-visible transition-all duration-200 ease-in-out relative",
|
|
91
|
-
style: { width: `${
|
|
92
|
-
children: [
|
|
93
|
-
isCollapsed:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
105
|
+
style: { width: `${S}px` },
|
|
106
|
+
children: [C && /* @__PURE__ */ l(i, {
|
|
107
|
+
isCollapsed: m,
|
|
108
|
+
side: h,
|
|
109
|
+
onToggle: C,
|
|
110
|
+
sidebarWidth: A,
|
|
111
|
+
collapsedWidth: S,
|
|
112
|
+
onWidthChange: b ? I : void 0,
|
|
113
|
+
minWidth: w,
|
|
114
|
+
maxWidth: T,
|
|
115
|
+
anchorRef: M
|
|
116
|
+
}), /* @__PURE__ */ l("ul", {
|
|
102
117
|
className: "flex flex-col p-2 gap-1 h-full overflow-y-auto overflow-x-hidden",
|
|
103
|
-
children:
|
|
104
|
-
onClick: () =>
|
|
118
|
+
children: E.map((e) => /* @__PURE__ */ l("li", { children: e.path ? /* @__PURE__ */ l("button", {
|
|
119
|
+
onClick: () => F({ to: e.path }),
|
|
105
120
|
"aria-label": e.label,
|
|
106
121
|
className: "flex justify-center items-center rounded-lg hover:bg-base-300 transition-colors w-full",
|
|
107
122
|
style: {
|
|
108
123
|
WebkitTapHighlightColor: "transparent",
|
|
109
|
-
height: `${Math.min(
|
|
110
|
-
width: `${Math.min(
|
|
124
|
+
height: `${Math.min(S - 16, 40)}px`,
|
|
125
|
+
width: `${Math.min(S - 16, 40)}px`,
|
|
111
126
|
margin: "0 auto"
|
|
112
127
|
},
|
|
113
|
-
children: e.icon || /* @__PURE__ */
|
|
128
|
+
children: e.icon || /* @__PURE__ */ l("span", {
|
|
114
129
|
className: "text-sm",
|
|
115
130
|
children: e.label.charAt(0)
|
|
116
131
|
})
|
|
117
|
-
}) : /* @__PURE__ */
|
|
132
|
+
}) : /* @__PURE__ */ l("div", {
|
|
118
133
|
className: "flex justify-center items-center",
|
|
119
134
|
style: {
|
|
120
135
|
WebkitTapHighlightColor: "transparent",
|
|
121
|
-
height: `${Math.min(
|
|
122
|
-
width: `${Math.min(
|
|
136
|
+
height: `${Math.min(S - 16, 40)}px`,
|
|
137
|
+
width: `${Math.min(S - 16, 40)}px`,
|
|
123
138
|
margin: "0 auto"
|
|
124
139
|
},
|
|
125
|
-
children: e.icon || /* @__PURE__ */
|
|
140
|
+
children: e.icon || /* @__PURE__ */ l("span", {
|
|
126
141
|
className: "text-sm",
|
|
127
142
|
children: e.label.charAt(0)
|
|
128
143
|
})
|
|
129
144
|
}) }, e.id))
|
|
130
145
|
})]
|
|
131
|
-
}) : /* @__PURE__ */
|
|
132
|
-
ref:
|
|
146
|
+
}) : /* @__PURE__ */ u("div", {
|
|
147
|
+
ref: M,
|
|
133
148
|
className: "blade-sidebar h-full bg-base-200 overflow-visible flex flex-col transition-colors duration-200 ease-in-out relative",
|
|
134
149
|
style: {
|
|
135
|
-
width: `${
|
|
136
|
-
maxWidth:
|
|
137
|
-
minWidth:
|
|
150
|
+
width: `${A}px`,
|
|
151
|
+
maxWidth: T,
|
|
152
|
+
minWidth: w
|
|
138
153
|
},
|
|
139
154
|
children: [
|
|
140
|
-
|
|
141
|
-
isCollapsed:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
155
|
+
C && /* @__PURE__ */ l(i, {
|
|
156
|
+
isCollapsed: m,
|
|
157
|
+
side: h,
|
|
158
|
+
onToggle: C,
|
|
159
|
+
sidebarWidth: A,
|
|
160
|
+
collapsedWidth: S,
|
|
161
|
+
onWidthChange: b ? I : void 0,
|
|
162
|
+
minWidth: w,
|
|
163
|
+
maxWidth: T,
|
|
164
|
+
anchorRef: M
|
|
149
165
|
}),
|
|
150
|
-
/* @__PURE__ */
|
|
151
|
-
ref:
|
|
166
|
+
/* @__PURE__ */ l("div", {
|
|
167
|
+
ref: N,
|
|
152
168
|
className: "sidebar-scroll min-h-0 flex-grow overflow-y-auto scrollbar-thin scrollbar-thumb-base-300 scrollbar-track-transparent",
|
|
153
|
-
children: /* @__PURE__ */
|
|
154
|
-
data:
|
|
155
|
-
activeNodeId:
|
|
156
|
-
defaultExpandedIds:
|
|
169
|
+
children: /* @__PURE__ */ l(r, {
|
|
170
|
+
data: R,
|
|
171
|
+
activeNodeId: O,
|
|
172
|
+
defaultExpandedIds: z,
|
|
157
173
|
showSearch: !1,
|
|
158
174
|
showExpandAll: !1,
|
|
159
175
|
showIcon: !0,
|
|
@@ -162,10 +178,24 @@ var f = ({ isCollapsed: f, language: p, items: m, getMenuItems: h, onWidthChange
|
|
|
162
178
|
indent: 1,
|
|
163
179
|
togglePosition: "right",
|
|
164
180
|
maxHeight: "100%",
|
|
165
|
-
className: "sidebar-tree"
|
|
181
|
+
className: `sidebar-tree${v === void 0 ? "" : " sidebar-tree-level-text"}`,
|
|
182
|
+
renderLabel: (t, n) => {
|
|
183
|
+
let r = Math.min(n, 2), i = v?.[r], a = p[r];
|
|
184
|
+
return /* @__PURE__ */ l(e, {
|
|
185
|
+
size: i?.size ?? a.size,
|
|
186
|
+
weight: i?.weight ?? a.weight,
|
|
187
|
+
color: O === t.id ? "inherit" : i?.color ?? "inherit",
|
|
188
|
+
style: v === void 0 ? {
|
|
189
|
+
fontSize: "inherit",
|
|
190
|
+
lineHeight: "inherit",
|
|
191
|
+
fontWeight: "inherit"
|
|
192
|
+
} : void 0,
|
|
193
|
+
children: t.label
|
|
194
|
+
});
|
|
195
|
+
},
|
|
166
196
|
onNodeClick: (e) => {
|
|
167
197
|
if (e.meta?.path) {
|
|
168
|
-
|
|
198
|
+
k(e.id), F({ to: e.meta.path });
|
|
169
199
|
return;
|
|
170
200
|
}
|
|
171
201
|
if (e.children && e.children.length > 0) {
|
|
@@ -179,12 +209,12 @@ var f = ({ isCollapsed: f, language: p, items: m, getMenuItems: h, onWidthChange
|
|
|
179
209
|
}
|
|
180
210
|
return null;
|
|
181
211
|
}, n = t(e.children);
|
|
182
|
-
n ? (
|
|
183
|
-
} else
|
|
212
|
+
n ? (k(n.id), F({ to: n.meta.path })) : k(e.id);
|
|
213
|
+
} else k(e.id);
|
|
184
214
|
}
|
|
185
215
|
})
|
|
186
216
|
}),
|
|
187
|
-
/* @__PURE__ */
|
|
217
|
+
/* @__PURE__ */ l("style", { children: `
|
|
188
218
|
/* Sidebar Tree 自定义样式 */
|
|
189
219
|
.sidebar-tree {
|
|
190
220
|
background: transparent;
|
|
@@ -205,7 +235,7 @@ var f = ({ isCollapsed: f, language: p, items: m, getMenuItems: h, onWidthChange
|
|
|
205
235
|
}
|
|
206
236
|
|
|
207
237
|
/* 主题活跃状态样式 - 从共用配置生成 */
|
|
208
|
-
${
|
|
238
|
+
${n()}
|
|
209
239
|
|
|
210
240
|
/* 悬停状态 */
|
|
211
241
|
.sidebar-tree .tree-node-content:hover:not(.tree-node-active .tree-node-content):not(.tree-node-content-active) {
|
|
@@ -263,16 +293,10 @@ var f = ({ isCollapsed: f, language: p, items: m, getMenuItems: h, onWidthChange
|
|
|
263
293
|
opacity: 0.8;
|
|
264
294
|
}
|
|
265
295
|
|
|
266
|
-
/*
|
|
267
|
-
.sidebar-tree .tree-node-label {
|
|
268
|
-
font-size: 0.9375rem;
|
|
269
|
-
line-height: 1.4rem;
|
|
270
|
-
font-weight: 450;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/* 一级菜单标签更大 */
|
|
274
|
-
.sidebar-tree > div > .tree-nodes > .tree-node .tree-node-label {
|
|
296
|
+
/* Preserve the legacy all-level appearance only when typography is not configured. */
|
|
297
|
+
.sidebar-tree:not(.sidebar-tree-level-text) .tree-node-label {
|
|
275
298
|
font-size: 1rem;
|
|
299
|
+
line-height: 1.4rem;
|
|
276
300
|
font-weight: 500;
|
|
277
301
|
}
|
|
278
302
|
|
|
@@ -325,6 +349,6 @@ var f = ({ isCollapsed: f, language: p, items: m, getMenuItems: h, onWidthChange
|
|
|
325
349
|
});
|
|
326
350
|
};
|
|
327
351
|
//#endregion
|
|
328
|
-
export {
|
|
352
|
+
export { m as default };
|
|
329
353
|
|
|
330
354
|
//# sourceMappingURL=Sidebar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sidebar.js","names":[],"sources":["../../src/layouts/Sidebar.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useMemo } from 'react';\nimport { useNavigate, useRouterState } from '@tanstack/react-router';\nimport { MenuItem } from '../types/menu';\nimport { getMenuItems as defaultGetMenuItems } from '../utils/menu';\nimport { Tree, TreeNode } from '../components/Tree';\nimport { generateSidebarActiveStyles } from '../styles/themeStyles';\nimport { DesktopSidebarToggleButton } from '../components/SidebarToggleButton';\n\n// 组件属性\ntype SidebarProps = {\n isCollapsed: boolean;\n language: 'zh' | 'en';\n items?: MenuItem[];\n getMenuItems?: (language: 'zh' | 'en') => MenuItem[];\n onWidthChange?: (width: number) => void;\n initialWidth?: number;\n collapsedWidth?: number;\n /**\n * 折叠 / 展开切换回调。传入后,侧边栏会在其边缘渲染统一的悬浮 pill 控制条\n * (点击折叠、拖拽调节宽度),无需再在外层单独渲染 SidebarToggleButtons。\n */\n onToggle?: () => void;\n /** 拖拽调节宽度的最小值(px) */\n minWidth?: number;\n /** 拖拽调节宽度的最大值(px) */\n maxWidth?: number;\n};\n\nconst Sidebar: React.FC<SidebarProps> = ({\n isCollapsed,\n language,\n items: propItems,\n getMenuItems,\n onWidthChange,\n initialWidth = 280,\n collapsedWidth = 64,\n onToggle,\n minWidth = 160,\n maxWidth = 400,\n}) => {\n const [items, setItems] = useState<MenuItem[]>([]);\n const [activeNodeId, setActiveNodeId] = useState<string | number>('');\n const [sidebarWidth, setSidebarWidth] = useState(() => Math.max(minWidth, Math.min(initialWidth, maxWidth)));\n const sidebarRef = useRef<HTMLDivElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n const routerState = useRouterState({ select: (s: { location: { pathname: string } }) => s.location });\n const navigate = useNavigate();\n\n // 当 initialWidth 改变时,更新侧边栏宽度\n useEffect(() => {\n setSidebarWidth(Math.max(minWidth, Math.min(initialWidth, maxWidth)));\n }, [initialWidth, minWidth, maxWidth]);\n\n // 统一的宽度变更处理:同步内部状态并通知父组件。\n // pill 拖拽与外部同步都通过此入口,避免必须回传 initialWidth 才能生效。\n const handleInternalWidthChange = (width: number) => {\n const next = Math.max(minWidth, Math.min(width, maxWidth));\n setSidebarWidth(next);\n onWidthChange?.(next);\n };\n\n // 当语言改变或传入items prop时,更新菜单项\n useEffect(() => {\n if (propItems !== undefined) {\n setItems(propItems);\n } else if (getMenuItems) {\n setItems(getMenuItems(language));\n } else {\n setItems(defaultGetMenuItems(language));\n }\n }, [language, propItems, getMenuItems]);\n\n // 活跃节点变化时,自动滚动到可见区域(菜单过长时保证当前页可见)。\n // 延迟 350ms:Tree 展开动画(max-height 0.3s)期间布局仍在变化,立即\n // scrollIntoView 会计算到动画中途的位置而滚动不到位。\n useEffect(() => {\n if (!activeNodeId) return;\n const t = setTimeout(() => {\n scrollRef.current\n ?.querySelector('.tree-node-content-active')\n ?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }, 350);\n return () => clearTimeout(t);\n }, [activeNodeId]);\n\n // 兜底:确保鼠标悬停在菜单任意位置都能滚轮滚动。\n // 部分浏览器/嵌套滚动场景下原生滚轮可能不作用于该容器,这里用非被动\n // 监听手动滚动;成功滚动后 preventDefault,避免浏览器默认行为造成双重滚动。\n useEffect(() => {\n const el = scrollRef.current;\n if (!el) return;\n const onWheel = (e: WheelEvent) => {\n if (el.scrollHeight <= el.clientHeight) return;\n const dy = e.deltaMode === 1 ? e.deltaY * 16 : e.deltaY; // 行模式 → 像素\n if (dy === 0) return;\n const before = el.scrollTop;\n el.scrollTop = before + dy;\n if (el.scrollTop !== before) e.preventDefault();\n };\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => el.removeEventListener('wheel', onWheel);\n }, []);\n\n // 将 MenuItem 转换为 TreeNode\n const convertToTreeNodes = (menuItems: MenuItem[], isTopLevel: boolean = true): TreeNode[] => {\n return menuItems.map(item => ({\n id: item.id,\n label: item.label,\n icon: item.icon || (!isTopLevel ? (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" />\n </svg>\n ) : undefined),\n children: item.children ? convertToTreeNodes(item.children, false) : undefined,\n meta: {\n path: item.path,\n },\n }));\n };\n\n // 转换后的树形数据\n const treeData = useMemo(() => convertToTreeNodes(items, true), [items]);\n\n // 获取默认展开的节点ID(默认全部展开)\n const defaultExpandedIds = useMemo(() => {\n if (items.length === 0) return [];\n\n // 收集所有有子节点的项的ID,使其默认全展开\n const collectAllExpandableIds = (menuItems: MenuItem[]): string[] => {\n let result: string[] = [];\n for (const item of menuItems) {\n if (item.children?.length) {\n result.push(item.id);\n result = [...result, ...collectAllExpandableIds(item.children)];\n }\n }\n return result;\n };\n\n return collectAllExpandableIds(items);\n }, [items]);\n\n // 更新活跃节点ID\n useEffect(() => {\n const currentPath = routerState.pathname;\n const findNodeByPath = (menuItems: MenuItem[]): string | null => {\n for (const item of menuItems) {\n if (item.path === currentPath) {\n return item.id;\n }\n if (item.children) {\n const found = findNodeByPath(item.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n const nodeId = findNodeByPath(items);\n if (nodeId) {\n setActiveNodeId(nodeId);\n }\n }, [items, routerState.pathname]);\n\n\n\n // 处理节点点击\n const handleNodeClick = (node: TreeNode) => {\n // 如果节点有路径,直接导航\n if (node.meta?.path) {\n setActiveNodeId(node.id);\n navigate({ to: node.meta.path });\n return;\n }\n\n // 如果没有路径但有子节点,寻找第一个有路径的后代节点\n if (node.children && node.children.length > 0) {\n const findFirstPath = (nodes: TreeNode[]): TreeNode | null => {\n for (const n of nodes) {\n if (n.meta?.path) return n;\n if (n.children && n.children.length > 0) {\n const found = findFirstPath(n.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n const firstNodeWithPath = findFirstPath(node.children);\n if (firstNodeWithPath) {\n setActiveNodeId(firstNodeWithPath.id);\n navigate({ to: firstNodeWithPath.meta!.path });\n } else {\n // 全都没有路径则激活当前节点\n setActiveNodeId(node.id);\n }\n } else {\n setActiveNodeId(node.id);\n }\n };\n\n if (isCollapsed) {\n return (\n <div\n ref={sidebarRef}\n className=\"blade-sidebar h-full bg-base-200 overflow-visible transition-all duration-200 ease-in-out relative\"\n style={{ width: `${collapsedWidth}px` }}\n >\n {onToggle && (\n <DesktopSidebarToggleButton\n isCollapsed={isCollapsed}\n onToggle={onToggle}\n sidebarWidth={sidebarWidth}\n collapsedWidth={collapsedWidth}\n onWidthChange={onWidthChange ? handleInternalWidthChange : undefined}\n minWidth={minWidth}\n maxWidth={maxWidth}\n anchorRef={sidebarRef}\n />\n )}\n <ul className=\"flex flex-col p-2 gap-1 h-full overflow-y-auto overflow-x-hidden\">\n {items.map(item => (\n <li key={item.id}>\n {item.path ? (\n <button\n onClick={() => navigate({ to: item.path! })}\n aria-label={item.label}\n className=\"flex justify-center items-center rounded-lg hover:bg-base-300 transition-colors w-full\"\n style={{\n WebkitTapHighlightColor: 'transparent',\n height: `${Math.min(collapsedWidth - 16, 40)}px`,\n width: `${Math.min(collapsedWidth - 16, 40)}px`,\n margin: '0 auto'\n }}\n >\n {item.icon || <span className=\"text-sm\">{item.label.charAt(0)}</span>}\n </button>\n ) : (\n <div\n className=\"flex justify-center items-center\"\n style={{\n WebkitTapHighlightColor: 'transparent',\n height: `${Math.min(collapsedWidth - 16, 40)}px`,\n width: `${Math.min(collapsedWidth - 16, 40)}px`,\n margin: '0 auto'\n }}\n >\n {item.icon || <span className=\"text-sm\">{item.label.charAt(0)}</span>}\n </div>\n )}\n </li>\n ))}\n </ul>\n </div>\n );\n }\n\n return (\n <div\n ref={sidebarRef}\n className=\"blade-sidebar h-full bg-base-200 overflow-visible flex flex-col transition-colors duration-200 ease-in-out relative\"\n style={{ width: `${sidebarWidth}px`, maxWidth, minWidth }}\n >\n {onToggle && (\n <DesktopSidebarToggleButton\n isCollapsed={isCollapsed}\n onToggle={onToggle}\n sidebarWidth={sidebarWidth}\n collapsedWidth={collapsedWidth}\n onWidthChange={onWidthChange ? handleInternalWidthChange : undefined}\n minWidth={minWidth}\n maxWidth={maxWidth}\n anchorRef={sidebarRef}\n />\n )}\n <div ref={scrollRef} className=\"sidebar-scroll min-h-0 flex-grow overflow-y-auto scrollbar-thin scrollbar-thumb-base-300 scrollbar-track-transparent\">\n <Tree\n data={treeData}\n activeNodeId={activeNodeId}\n defaultExpandedIds={defaultExpandedIds}\n showSearch={false}\n showExpandAll={false}\n showIcon={true}\n showCount={false}\n showLine={true}\n indent={1}\n togglePosition=\"right\"\n maxHeight=\"100%\"\n className=\"sidebar-tree\"\n onNodeClick={handleNodeClick}\n />\n </div>\n\n <style>{`\n /* Sidebar Tree 自定义样式 */\n .sidebar-tree {\n background: transparent;\n border: none;\n padding: 0.5rem;\n }\n \n .sidebar-tree .tree-node-content {\n padding: 0.5rem 1rem;\n border-radius: 0.5rem;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n /* 活跃状态 - 为每个主题设置匹配的配色 */\n .sidebar-tree .tree-node-content-active {\n font-weight: 600 !important;\n padding-left: calc(1rem - 4px) !important;\n }\n \n /* 主题活跃状态样式 - 从共用配置生成 */\n ${generateSidebarActiveStyles()}\n \n /* 悬停状态 */\n .sidebar-tree .tree-node-content:hover:not(.tree-node-active .tree-node-content):not(.tree-node-content-active) {\n background-color: var(--color-base-200);\n }\n \n /* 右侧展开按钮样式 */\n .sidebar-tree .tree-node-toggle-right {\n width: auto;\n height: auto;\n min-width: auto;\n min-height: auto;\n padding: 0.25rem;\n opacity: 0.6;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n border-radius: 0.25rem;\n }\n \n .sidebar-tree .tree-node-toggle-right:hover {\n opacity: 1;\n background-color: var(--color-base-300);\n }\n \n /* 右侧按钮图标旋转 */\n .sidebar-tree .tree-node-toggle-right svg {\n width: 1rem;\n height: 1rem;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n .sidebar-tree .tree-node-toggle-right.tree-node-toggle-expanded svg {\n transform: rotate(90deg);\n }\n \n /* 图标样式 */\n .sidebar-tree .tree-node-icon {\n width: 1.25rem;\n height: 1.25rem;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: color 0.2s ease;\n }\n \n .sidebar-tree .tree-node-icon svg {\n width: 1.25rem;\n height: 1.25rem;\n }\n \n /* 子节点图标稍小 */\n .sidebar-tree .tree-node-children .tree-node-icon svg {\n width: 1rem;\n height: 1rem;\n opacity: 0.8;\n }\n \n /* 标签样式 - 增大字体和行高 */\n .sidebar-tree .tree-node-label {\n font-size: 0.9375rem;\n line-height: 1.4rem;\n font-weight: 450;\n }\n \n /* 一级菜单标签更大 */\n .sidebar-tree > div > .tree-nodes > .tree-node .tree-node-label {\n font-size: 1rem;\n font-weight: 500;\n }\n \n /* 连接线样式 - 强制显示!向右移动并加粗,增加整体左边距 */\n /* 使用双重选择器增加优先级,避免被其他 Tree 组件样式覆盖 */\n .sidebar-tree.sidebar-tree .tree-show-line .tree-node-children-expanded,\n .sidebar-tree.sidebar-tree .tree-node-children.tree-node-children-expanded,\n div.sidebar-tree .tree-show-line .tree-node-children-expanded,\n div.sidebar-tree .tree-node-children.tree-node-children-expanded {\n border-left: 3px solid rgba(128, 128, 128, 0.35) !important;\n margin-left: 24px !important;\n padding-left: 8px !important;\n box-sizing: border-box !important;\n }\n \n /* 隐藏 Tree 组件的圆点装饰 - 避免与 Sidebar 样式冲突 */\n .sidebar-tree.sidebar-tree .tree-show-line .tree-node-children-expanded::before,\n div.sidebar-tree .tree-show-line .tree-node-children-expanded::before {\n display: none !important;\n }\n \n /* 隐藏 Tree 组件的标题和操作按钮 */\n .sidebar-tree .tree-header,\n .sidebar-tree .tree-search,\n .sidebar-tree .tree-actions {\n display: none;\n }\n \n /* 移除内边距 */\n .sidebar-tree > div:first-child {\n padding: 0;\n }\n \n /* 子节点动画优化 - 减小间距 */\n .sidebar-tree .tree-node-children {\n margin-top: 0.125rem !important;\n }\n \n /* 一级菜单项间距 */\n .sidebar-tree > div > .tree-nodes > .tree-node {\n margin-bottom: 0.375rem;\n }\n \n /* 二级菜单项间距 */\n .sidebar-tree .tree-node-children > .tree-node {\n margin-bottom: 0.125rem;\n }\n `}</style>\n </div>\n );\n};\n\nexport default Sidebar; "],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Sidebar.js","names":[],"sources":["../../src/layouts/Sidebar.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useMemo } from 'react';\nimport { useNavigate, useRouterState } from '@tanstack/react-router';\nimport { MenuItem } from '../types/menu';\nimport { getMenuItems as defaultGetMenuItems } from '../utils/menu';\nimport { Tree, TreeNode } from '../components/Tree';\nimport { generateSidebarActiveStyles } from '../styles/themeStyles';\nimport { DesktopSidebarToggleButton } from '../components/SidebarToggleButton';\nimport Text, { type TextProps } from '../components/Text';\n\nexport type SidebarLevelText = Pick<TextProps, 'size' | 'weight' | 'color'>;\n\nconst DEFAULT_LEVEL_TEXT = [\n { size: 'base', weight: 'semibold' },\n { size: 'sm', weight: 'medium' },\n { size: 'sm', weight: 'normal' },\n] as const satisfies readonly SidebarLevelText[];\n\n// 组件属性\nexport type SidebarProps = {\n isCollapsed: boolean;\n /** 侧栏所在侧,控制内侧 pill 的位置与调宽方向。 */\n side?: 'left' | 'right';\n language: 'zh' | 'en';\n items?: MenuItem[];\n /**\n * Opt-in typography for levels 1–3; deeper nodes reuse level 3.\n * Omitted: preserve legacy Sidebar/LayoutSuite typography. When supplied,\n * missing values default to base/sm/sm, semibold/medium/normal and inherited color.\n * Selected labels always inherit the active row color.\n */\n levelText?: readonly [SidebarLevelText?, SidebarLevelText?, SidebarLevelText?];\n getMenuItems?: (language: 'zh' | 'en') => MenuItem[];\n onWidthChange?: (width: number) => void;\n initialWidth?: number;\n collapsedWidth?: number;\n /**\n * 折叠 / 展开切换回调。传入后,侧边栏会在其边缘渲染统一的悬浮 pill 控制条\n * (点击折叠、拖拽调节宽度),无需再在外层单独渲染 SidebarToggleButtons。\n */\n onToggle?: () => void;\n /** 拖拽调节宽度的最小值(px) */\n minWidth?: number;\n /** 拖拽调节宽度的最大值(px) */\n maxWidth?: number;\n};\n\nconst Sidebar: React.FC<SidebarProps> = ({\n isCollapsed,\n side = 'left',\n language,\n items: propItems,\n levelText,\n getMenuItems,\n onWidthChange,\n initialWidth = 280,\n collapsedWidth = 64,\n onToggle,\n minWidth = 160,\n maxWidth = 400,\n}) => {\n const [items, setItems] = useState<MenuItem[]>([]);\n const [activeNodeId, setActiveNodeId] = useState<string | number>('');\n const [sidebarWidth, setSidebarWidth] = useState(() => Math.max(minWidth, Math.min(initialWidth, maxWidth)));\n const sidebarRef = useRef<HTMLDivElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n const routerState = useRouterState({ select: (s: { location: { pathname: string } }) => s.location });\n const navigate = useNavigate();\n\n // 当 initialWidth 改变时,更新侧边栏宽度\n useEffect(() => {\n setSidebarWidth(Math.max(minWidth, Math.min(initialWidth, maxWidth)));\n }, [initialWidth, minWidth, maxWidth]);\n\n // 统一的宽度变更处理:同步内部状态并通知父组件。\n // pill 拖拽与外部同步都通过此入口,避免必须回传 initialWidth 才能生效。\n const handleInternalWidthChange = (width: number) => {\n const next = Math.max(minWidth, Math.min(width, maxWidth));\n setSidebarWidth(next);\n onWidthChange?.(next);\n };\n\n // 当语言改变或传入items prop时,更新菜单项\n useEffect(() => {\n if (propItems !== undefined) {\n setItems(propItems);\n } else if (getMenuItems) {\n setItems(getMenuItems(language));\n } else {\n setItems(defaultGetMenuItems(language));\n }\n }, [language, propItems, getMenuItems]);\n\n // 活跃节点变化时,自动滚动到可见区域(菜单过长时保证当前页可见)。\n // 延迟 350ms:Tree 展开动画(max-height 0.3s)期间布局仍在变化,立即\n // scrollIntoView 会计算到动画中途的位置而滚动不到位。\n useEffect(() => {\n if (!activeNodeId) return;\n const t = setTimeout(() => {\n scrollRef.current\n ?.querySelector('.tree-node-content-active')\n ?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }, 350);\n return () => clearTimeout(t);\n }, [activeNodeId]);\n\n // 兜底:确保鼠标悬停在菜单任意位置都能滚轮滚动。\n // 部分浏览器/嵌套滚动场景下原生滚轮可能不作用于该容器,这里用非被动\n // 监听手动滚动;成功滚动后 preventDefault,避免浏览器默认行为造成双重滚动。\n useEffect(() => {\n const el = scrollRef.current;\n if (!el) return;\n const onWheel = (e: WheelEvent) => {\n if (el.scrollHeight <= el.clientHeight) return;\n const dy = e.deltaMode === 1 ? e.deltaY * 16 : e.deltaY; // 行模式 → 像素\n if (dy === 0) return;\n const before = el.scrollTop;\n el.scrollTop = before + dy;\n if (el.scrollTop !== before) e.preventDefault();\n };\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => el.removeEventListener('wheel', onWheel);\n }, []);\n\n // 将 MenuItem 转换为 TreeNode\n const convertToTreeNodes = (menuItems: MenuItem[], isTopLevel: boolean = true): TreeNode[] => {\n return menuItems.map(item => ({\n id: item.id,\n label: item.label,\n icon: item.icon || (!isTopLevel ? (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" />\n </svg>\n ) : undefined),\n children: item.children ? convertToTreeNodes(item.children, false) : undefined,\n meta: {\n path: item.path,\n },\n }));\n };\n\n // 转换后的树形数据\n const treeData = useMemo(() => convertToTreeNodes(items, true), [items]);\n\n // 获取默认展开的节点ID(默认全部展开)\n const defaultExpandedIds = useMemo(() => {\n if (items.length === 0) return [];\n\n // 收集所有有子节点的项的ID,使其默认全展开\n const collectAllExpandableIds = (menuItems: MenuItem[]): string[] => {\n let result: string[] = [];\n for (const item of menuItems) {\n if (item.children?.length) {\n result.push(item.id);\n result = [...result, ...collectAllExpandableIds(item.children)];\n }\n }\n return result;\n };\n\n return collectAllExpandableIds(items);\n }, [items]);\n\n // 更新活跃节点ID\n useEffect(() => {\n const currentPath = routerState.pathname;\n const findNodeByPath = (menuItems: MenuItem[]): string | null => {\n for (const item of menuItems) {\n if (item.path === currentPath) {\n return item.id;\n }\n if (item.children) {\n const found = findNodeByPath(item.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n const nodeId = findNodeByPath(items);\n if (nodeId) {\n setActiveNodeId(nodeId);\n }\n }, [items, routerState.pathname]);\n\n\n\n // 处理节点点击\n const handleNodeClick = (node: TreeNode) => {\n // 如果节点有路径,直接导航\n if (node.meta?.path) {\n setActiveNodeId(node.id);\n navigate({ to: node.meta.path });\n return;\n }\n\n // 如果没有路径但有子节点,寻找第一个有路径的后代节点\n if (node.children && node.children.length > 0) {\n const findFirstPath = (nodes: TreeNode[]): TreeNode | null => {\n for (const n of nodes) {\n if (n.meta?.path) return n;\n if (n.children && n.children.length > 0) {\n const found = findFirstPath(n.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n const firstNodeWithPath = findFirstPath(node.children);\n if (firstNodeWithPath) {\n setActiveNodeId(firstNodeWithPath.id);\n navigate({ to: firstNodeWithPath.meta!.path });\n } else {\n // 全都没有路径则激活当前节点\n setActiveNodeId(node.id);\n }\n } else {\n setActiveNodeId(node.id);\n }\n };\n\n if (isCollapsed) {\n return (\n <div\n ref={sidebarRef}\n className=\"blade-sidebar h-full bg-base-200 overflow-visible transition-all duration-200 ease-in-out relative\"\n style={{ width: `${collapsedWidth}px` }}\n >\n {onToggle && (\n <DesktopSidebarToggleButton\n isCollapsed={isCollapsed}\n side={side}\n onToggle={onToggle}\n sidebarWidth={sidebarWidth}\n collapsedWidth={collapsedWidth}\n onWidthChange={onWidthChange ? handleInternalWidthChange : undefined}\n minWidth={minWidth}\n maxWidth={maxWidth}\n anchorRef={sidebarRef}\n />\n )}\n <ul className=\"flex flex-col p-2 gap-1 h-full overflow-y-auto overflow-x-hidden\">\n {items.map(item => (\n <li key={item.id}>\n {item.path ? (\n <button\n onClick={() => navigate({ to: item.path! })}\n aria-label={item.label}\n className=\"flex justify-center items-center rounded-lg hover:bg-base-300 transition-colors w-full\"\n style={{\n WebkitTapHighlightColor: 'transparent',\n height: `${Math.min(collapsedWidth - 16, 40)}px`,\n width: `${Math.min(collapsedWidth - 16, 40)}px`,\n margin: '0 auto'\n }}\n >\n {item.icon || <span className=\"text-sm\">{item.label.charAt(0)}</span>}\n </button>\n ) : (\n <div\n className=\"flex justify-center items-center\"\n style={{\n WebkitTapHighlightColor: 'transparent',\n height: `${Math.min(collapsedWidth - 16, 40)}px`,\n width: `${Math.min(collapsedWidth - 16, 40)}px`,\n margin: '0 auto'\n }}\n >\n {item.icon || <span className=\"text-sm\">{item.label.charAt(0)}</span>}\n </div>\n )}\n </li>\n ))}\n </ul>\n </div>\n );\n }\n\n return (\n <div\n ref={sidebarRef}\n className=\"blade-sidebar h-full bg-base-200 overflow-visible flex flex-col transition-colors duration-200 ease-in-out relative\"\n style={{ width: `${sidebarWidth}px`, maxWidth, minWidth }}\n >\n {onToggle && (\n <DesktopSidebarToggleButton\n isCollapsed={isCollapsed}\n side={side}\n onToggle={onToggle}\n sidebarWidth={sidebarWidth}\n collapsedWidth={collapsedWidth}\n onWidthChange={onWidthChange ? handleInternalWidthChange : undefined}\n minWidth={minWidth}\n maxWidth={maxWidth}\n anchorRef={sidebarRef}\n />\n )}\n <div ref={scrollRef} className=\"sidebar-scroll min-h-0 flex-grow overflow-y-auto scrollbar-thin scrollbar-thumb-base-300 scrollbar-track-transparent\">\n <Tree\n data={treeData}\n activeNodeId={activeNodeId}\n defaultExpandedIds={defaultExpandedIds}\n showSearch={false}\n showExpandAll={false}\n showIcon={true}\n showCount={false}\n showLine={true}\n indent={1}\n togglePosition=\"right\"\n maxHeight=\"100%\"\n className={`sidebar-tree${levelText !== undefined ? ' sidebar-tree-level-text' : ''}`}\n renderLabel={(node, depth) => {\n const level = Math.min(depth, 2);\n const text = levelText?.[level];\n const defaults = DEFAULT_LEVEL_TEXT[level];\n return (\n <Text\n size={text?.size ?? defaults.size}\n weight={text?.weight ?? defaults.weight}\n color={activeNodeId === node.id ? 'inherit' : text?.color ?? 'inherit'}\n style={levelText === undefined\n ? { fontSize: 'inherit', lineHeight: 'inherit', fontWeight: 'inherit' }\n : undefined}\n >\n {node.label}\n </Text>\n );\n }}\n onNodeClick={handleNodeClick}\n />\n </div>\n\n <style>{`\n /* Sidebar Tree 自定义样式 */\n .sidebar-tree {\n background: transparent;\n border: none;\n padding: 0.5rem;\n }\n \n .sidebar-tree .tree-node-content {\n padding: 0.5rem 1rem;\n border-radius: 0.5rem;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n /* 活跃状态 - 为每个主题设置匹配的配色 */\n .sidebar-tree .tree-node-content-active {\n font-weight: 600 !important;\n padding-left: calc(1rem - 4px) !important;\n }\n \n /* 主题活跃状态样式 - 从共用配置生成 */\n ${generateSidebarActiveStyles()}\n \n /* 悬停状态 */\n .sidebar-tree .tree-node-content:hover:not(.tree-node-active .tree-node-content):not(.tree-node-content-active) {\n background-color: var(--color-base-200);\n }\n \n /* 右侧展开按钮样式 */\n .sidebar-tree .tree-node-toggle-right {\n width: auto;\n height: auto;\n min-width: auto;\n min-height: auto;\n padding: 0.25rem;\n opacity: 0.6;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n border-radius: 0.25rem;\n }\n \n .sidebar-tree .tree-node-toggle-right:hover {\n opacity: 1;\n background-color: var(--color-base-300);\n }\n \n /* 右侧按钮图标旋转 */\n .sidebar-tree .tree-node-toggle-right svg {\n width: 1rem;\n height: 1rem;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n .sidebar-tree .tree-node-toggle-right.tree-node-toggle-expanded svg {\n transform: rotate(90deg);\n }\n \n /* 图标样式 */\n .sidebar-tree .tree-node-icon {\n width: 1.25rem;\n height: 1.25rem;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: color 0.2s ease;\n }\n \n .sidebar-tree .tree-node-icon svg {\n width: 1.25rem;\n height: 1.25rem;\n }\n \n /* 子节点图标稍小 */\n .sidebar-tree .tree-node-children .tree-node-icon svg {\n width: 1rem;\n height: 1rem;\n opacity: 0.8;\n }\n \n /* Preserve the legacy all-level appearance only when typography is not configured. */\n .sidebar-tree:not(.sidebar-tree-level-text) .tree-node-label {\n font-size: 1rem;\n line-height: 1.4rem;\n font-weight: 500;\n }\n \n /* 连接线样式 - 强制显示!向右移动并加粗,增加整体左边距 */\n /* 使用双重选择器增加优先级,避免被其他 Tree 组件样式覆盖 */\n .sidebar-tree.sidebar-tree .tree-show-line .tree-node-children-expanded,\n .sidebar-tree.sidebar-tree .tree-node-children.tree-node-children-expanded,\n div.sidebar-tree .tree-show-line .tree-node-children-expanded,\n div.sidebar-tree .tree-node-children.tree-node-children-expanded {\n border-left: 3px solid rgba(128, 128, 128, 0.35) !important;\n margin-left: 24px !important;\n padding-left: 8px !important;\n box-sizing: border-box !important;\n }\n \n /* 隐藏 Tree 组件的圆点装饰 - 避免与 Sidebar 样式冲突 */\n .sidebar-tree.sidebar-tree .tree-show-line .tree-node-children-expanded::before,\n div.sidebar-tree .tree-show-line .tree-node-children-expanded::before {\n display: none !important;\n }\n \n /* 隐藏 Tree 组件的标题和操作按钮 */\n .sidebar-tree .tree-header,\n .sidebar-tree .tree-search,\n .sidebar-tree .tree-actions {\n display: none;\n }\n \n /* 移除内边距 */\n .sidebar-tree > div:first-child {\n padding: 0;\n }\n \n /* 子节点动画优化 - 减小间距 */\n .sidebar-tree .tree-node-children {\n margin-top: 0.125rem !important;\n }\n \n /* 一级菜单项间距 */\n .sidebar-tree > div > .tree-nodes > .tree-node {\n margin-bottom: 0.375rem;\n }\n \n /* 二级菜单项间距 */\n .sidebar-tree .tree-node-children > .tree-node {\n margin-bottom: 0.125rem;\n }\n `}</style>\n </div>\n );\n};\n\nexport default Sidebar; "],"mappings":"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"}
|
package/dist/lite.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
export { Resizable, ResizablePanel, ResizableHandle, useResize } from './components/Resizable';
|
|
2
2
|
export type { ResizableProps, ResizablePanelProps, ResizableHandleProps, UseResizeOptions } from './components/Resizable';
|
|
3
|
+
export { default as ButtonMenu } from './components/ButtonMenu';
|
|
4
|
+
export type { ButtonMenuProps, ButtonMenuItem } from './components/ButtonMenu';
|
|
3
5
|
export { default as Button } from './components/Button';
|
|
4
6
|
export type { ButtonProps } from './components/Button';
|
|
5
7
|
export { default as Badge } from './components/Badge';
|
|
6
8
|
export type { BadgeProps } from './components/Badge';
|
|
7
9
|
export { default as Input } from './components/Input';
|
|
8
10
|
export type { InputProps } from './components/Input';
|
|
11
|
+
export { default as Field } from './components/Field';
|
|
12
|
+
export type { FieldProps } from './components/Field';
|
|
13
|
+
export { default as Textarea } from './components/Textarea';
|
|
14
|
+
export type { TextareaProps } from './components/Textarea';
|
|
9
15
|
export { default as Card } from './components/Card';
|
|
10
16
|
export type { CardProps, CardMetricProps, CardMetricItem } from './components/Card';
|
|
11
17
|
export { default as GroupButton } from './components/GroupButton';
|
|
@@ -22,8 +28,10 @@ export { default as Section } from './components/Section';
|
|
|
22
28
|
export type { SectionProps, SectionSlotProps } from './components/Section';
|
|
23
29
|
export { default as Text } from './components/Text';
|
|
24
30
|
export type { TextProps } from './components/Text';
|
|
25
|
-
export { default as Page } from './components/Page';
|
|
26
|
-
export type { PageProps, PageBodyProps, PageAsideProps, PageMainProps } from './components/Page';
|
|
31
|
+
export { default as Page, PageFooter, PageFloat } from './components/Page';
|
|
32
|
+
export type { PageProps, PageBodyProps, PageAsideProps, PageMainProps, PageFooterProps, PageFloatProps, PagePanelProps } from './components/Page';
|
|
33
|
+
export { DashboardSuite, LayoutSuite } from './components/LayoutSuite/DashboardSuite';
|
|
34
|
+
export type { DashboardSuiteProps } from './components/LayoutSuite/DashboardSuite';
|
|
27
35
|
export { default as EmptyState } from './components/EmptyState';
|
|
28
36
|
export type { EmptyStateProps } from './components/EmptyState';
|
|
29
37
|
export { default as Layout, Container, Grid, GridItem, Flex, Group, Space } from './components/Layout';
|
package/dist/lite.js
CHANGED
|
@@ -6,15 +6,20 @@ import o from "./components/Skeleton/index.js";
|
|
|
6
6
|
import s from "./components/GroupedTable/index.js";
|
|
7
7
|
import c from "./components/NavigationList/index.js";
|
|
8
8
|
import l from "./components/Section/index.js";
|
|
9
|
-
import u from "./components/
|
|
10
|
-
import d from "./components/
|
|
11
|
-
import f from "./components/
|
|
12
|
-
import p from "./components/
|
|
13
|
-
import m from "./components/
|
|
14
|
-
import h from "./components/
|
|
15
|
-
import g from "./components/
|
|
16
|
-
import _ from "./components/
|
|
17
|
-
import v
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
|
|
9
|
+
import u from "./components/Text/index.js";
|
|
10
|
+
import d from "./components/ButtonMenu/index.js";
|
|
11
|
+
import f from "./components/Badge/index.js";
|
|
12
|
+
import p from "./components/Input/index.js";
|
|
13
|
+
import m from "./components/Field/index.js";
|
|
14
|
+
import h from "./components/Textarea/index.js";
|
|
15
|
+
import g from "./components/Label/index.js";
|
|
16
|
+
import _ from "./components/Checkbox/index.js";
|
|
17
|
+
import v from "./components/Select/index.js";
|
|
18
|
+
import y from "./components/Card/index.js";
|
|
19
|
+
import b from "./components/Page/Float2.js";
|
|
20
|
+
import x, { PageFooter as S } from "./components/Page/index.js";
|
|
21
|
+
import C from "./components/Tree/Tree.js";
|
|
22
|
+
import w, { Container as T, Flex as E, Grid as D, GridItem as O, Group as k, Space as A } from "./components/Layout/index.js";
|
|
23
|
+
import { DashboardSuite as j, LayoutSuite as M } from "./components/LayoutSuite/DashboardSuite.js";
|
|
24
|
+
import N from "./components/EmptyState/index.js";
|
|
25
|
+
export { f as Badge, i as Button, d as ButtonMenu, y as Card, _ as Checkbox, T as Container, j as DashboardSuite, N as EmptyState, m as Field, E as Flex, D as Grid, O as GridItem, k as Group, a as GroupButton, s as GroupedTable, p as Input, g as Label, w as Layout, M as LayoutSuite, c as NavigationList, x as Page, b as PageFloat, S as PageFooter, t as Resizable, n as ResizableHandle, r as ResizablePanel, l as Section, v as Select, o as Skeleton, A as Space, u as Text, h as Textarea, C as Tree, e as useResize };
|
package/dist/utils/menu.js
CHANGED
|
@@ -75,12 +75,10 @@ var n = (n) => {
|
|
|
75
75
|
let m = l.flatMap((e) => {
|
|
76
76
|
let t = p.get(e.id);
|
|
77
77
|
return t ? [t] : f.has(e.id) ? [] : [e];
|
|
78
|
-
})
|
|
79
|
-
for (let e of u) {
|
|
78
|
+
}), h = u.flatMap((e) => {
|
|
80
79
|
let t = p.get(e.id);
|
|
81
|
-
t
|
|
82
|
-
}
|
|
83
|
-
let h = Object.values(a.children || {}), g = u.filter((e) => !f.has(e.id)), _ = c ? Object.values(c.children || {}) : [], v = [
|
|
80
|
+
return t ? [t] : f.has(e.id) ? [] : [e];
|
|
81
|
+
}), g = Object.values(a.children || {}), _ = c ? Object.values(c.children || {}) : [], v = [
|
|
84
82
|
{
|
|
85
83
|
...r,
|
|
86
84
|
icon: /* @__PURE__ */ t("svg", {
|
|
@@ -131,7 +129,7 @@ var n = (n) => {
|
|
|
131
129
|
d: "M4 5a1 1 0 011-1h16v6H4V5zm0 9h7v6H4v-6zm11 0h6v6h-6v-6z"
|
|
132
130
|
})
|
|
133
131
|
}),
|
|
134
|
-
children:
|
|
132
|
+
children: g
|
|
135
133
|
},
|
|
136
134
|
{
|
|
137
135
|
...o,
|
|
@@ -150,9 +148,9 @@ var n = (n) => {
|
|
|
150
148
|
})
|
|
151
149
|
}
|
|
152
150
|
];
|
|
153
|
-
return
|
|
154
|
-
id:
|
|
155
|
-
label:
|
|
151
|
+
return s && v.push({
|
|
152
|
+
id: s.id,
|
|
153
|
+
label: s.label,
|
|
156
154
|
icon: /* @__PURE__ */ t("svg", {
|
|
157
155
|
xmlns: "http://www.w3.org/2000/svg",
|
|
158
156
|
className: "h-5 w-5",
|
|
@@ -163,13 +161,13 @@ var n = (n) => {
|
|
|
163
161
|
strokeLinecap: "round",
|
|
164
162
|
strokeLinejoin: "round",
|
|
165
163
|
strokeWidth: "2",
|
|
166
|
-
d: "
|
|
164
|
+
d: "M19.428 15.428a2 2 0 00-1.022-.547l-2.384-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"
|
|
167
165
|
})
|
|
168
166
|
}),
|
|
169
|
-
children:
|
|
170
|
-
}),
|
|
171
|
-
id:
|
|
172
|
-
label:
|
|
167
|
+
children: h
|
|
168
|
+
}), c && v.push({
|
|
169
|
+
id: c.id,
|
|
170
|
+
label: c.label,
|
|
173
171
|
icon: /* @__PURE__ */ t("svg", {
|
|
174
172
|
xmlns: "http://www.w3.org/2000/svg",
|
|
175
173
|
className: "h-5 w-5",
|
|
@@ -180,10 +178,10 @@ var n = (n) => {
|
|
|
180
178
|
strokeLinecap: "round",
|
|
181
179
|
strokeLinejoin: "round",
|
|
182
180
|
strokeWidth: "2",
|
|
183
|
-
d: "
|
|
181
|
+
d: "M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
|
184
182
|
})
|
|
185
183
|
}),
|
|
186
|
-
children:
|
|
184
|
+
children: _
|
|
187
185
|
}), v;
|
|
188
186
|
};
|
|
189
187
|
//#endregion
|
package/dist/utils/menu.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.js","names":[],"sources":["../../src/utils/menu.tsx"],"sourcesContent":["// 菜单配置\nimport React from 'react';\nimport { MenuItem } from '../types/menu';\nimport { getTranslations, Language } from './i18n';\n\n// 转换扁平化的菜单项字典为菜单树\nexport const getMenuItems = (language: Language): MenuItem[] => {\n const translations = getTranslations(language);\n const { home, components, layouts, charts, advanced, showcase } = translations.sidebar.menu;\n\n // Keep legacy routes and exports available without duplicating retired documentation entries.\n const componentDocs = Object.values(components.children || {})\n .filter(doc => doc.id !== 'checkbox' && doc.id !== 'label');\n const advancedDocs = advanced ? Object.values(advanced.children || {}) : [];\n const allDocs = [...componentDocs, ...advancedDocs];\n const groupedIds = new Set<string>();\n const groups = new Map<string, MenuItem>();\n\n for (const doc of allDocs) {\n // 已被其他分组收纳的文档不再单独成组(如 datatable 已归入表格分组)。\n if (groupedIds.has(doc.id)) continue;\n const related = allDocs.filter(candidate => candidate.id !== doc.id && (\n (doc.path && candidate.path?.startsWith(`${doc.path}/`)) ||\n (doc.id === 'table' && ['groupedtable', 'datatable', 'datatableadvanced', 'datatableadvancedtree', 'datatablehooks', 'datatablepivot', 'list'].includes(candidate.id)) ||\n (doc.id === 'card' && candidate.id === 'cardmetric')\n ));\n if (!related.length) continue;\n\n groupedIds.add(doc.id);\n related.forEach(item => groupedIds.add(item.id));\n groups.set(doc.id, {\n id: `${doc.id}-docs`,\n label: doc.label,\n children: [\n { ...doc, label: language === 'zh' ? '基础用法' : 'Overview' },\n ...related,\n ],\n });\n }\n\n const categories = [\n { anchor: 'button', id: 'basic', zh: '基础', en: 'Basic', members: ['button', 'badge', 'text'] },\n { anchor: 'select', id: 'choice', zh: '选择', en: 'Choice', members: ['choicepicker', 'multiplechoice', 'select', 'tabs', 'groupbutton'] },\n { anchor: 'navigationlist', id: 'vertical-collection', zh: '垂直收纳', en: 'VerticalCollection', members: ['sidebar-demo', 'tree', 'navigationlist', 'accordion'] },\n ];\n for (const category of categories) {\n const children = category.members.flatMap(id => {\n const doc = allDocs.find(item => item.id === id);\n return doc ? [doc] : [];\n });\n children.forEach(doc => groupedIds.add(doc.id));\n groups.set(category.anchor, {\n id: `${category.id}-docs`,\n label: language === 'zh' ? category.zh : category.en,\n children,\n });\n }\n\n //
|
|
1
|
+
{"version":3,"file":"menu.js","names":[],"sources":["../../src/utils/menu.tsx"],"sourcesContent":["// 菜单配置\nimport React from 'react';\nimport { MenuItem } from '../types/menu';\nimport { getTranslations, Language } from './i18n';\n\n// 转换扁平化的菜单项字典为菜单树\nexport const getMenuItems = (language: Language): MenuItem[] => {\n const translations = getTranslations(language);\n const { home, components, layouts, charts, advanced, showcase } = translations.sidebar.menu;\n\n // Keep legacy routes and exports available without duplicating retired documentation entries.\n const componentDocs = Object.values(components.children || {})\n .filter(doc => doc.id !== 'checkbox' && doc.id !== 'label');\n const advancedDocs = advanced ? Object.values(advanced.children || {}) : [];\n const allDocs = [...componentDocs, ...advancedDocs];\n const groupedIds = new Set<string>();\n const groups = new Map<string, MenuItem>();\n\n for (const doc of allDocs) {\n // 已被其他分组收纳的文档不再单独成组(如 datatable 已归入表格分组)。\n if (groupedIds.has(doc.id)) continue;\n const related = allDocs.filter(candidate => candidate.id !== doc.id && (\n (doc.path && candidate.path?.startsWith(`${doc.path}/`)) ||\n (doc.id === 'table' && ['groupedtable', 'datatable', 'datatableadvanced', 'datatableadvancedtree', 'datatablehooks', 'datatablepivot', 'list'].includes(candidate.id)) ||\n (doc.id === 'card' && candidate.id === 'cardmetric')\n ));\n if (!related.length) continue;\n\n groupedIds.add(doc.id);\n related.forEach(item => groupedIds.add(item.id));\n groups.set(doc.id, {\n id: `${doc.id}-docs`,\n label: doc.label,\n children: [\n { ...doc, label: language === 'zh' ? '基础用法' : 'Overview' },\n ...related,\n ],\n });\n }\n\n const categories = [\n { anchor: 'button', id: 'basic', zh: '基础', en: 'Basic', members: ['button', 'badge', 'text'] },\n { anchor: 'select', id: 'choice', zh: '选择', en: 'Choice', members: ['choicepicker', 'multiplechoice', 'select', 'tabs', 'groupbutton'] },\n { anchor: 'navigationlist', id: 'vertical-collection', zh: '垂直收纳', en: 'VerticalCollection', members: ['sidebar-demo', 'tree', 'navigationlist', 'accordion'] },\n ];\n for (const category of categories) {\n const children = category.members.flatMap(id => {\n const doc = allDocs.find(item => item.id === id);\n return doc ? [doc] : [];\n });\n children.forEach(doc => groupedIds.add(doc.id));\n groups.set(category.anchor, {\n id: `${category.id}-docs`,\n label: language === 'zh' ? category.zh : category.en,\n children,\n });\n }\n\n // 分组跟随主文档所属分类,跨分类收纳的叶子仍保留原有 ID 与路由。\n const componentsChildren = componentDocs.flatMap(doc => {\n const group = groups.get(doc.id);\n return group ? [group] : groupedIds.has(doc.id) ? [] : [doc];\n });\n const advancedChildren = advancedDocs.flatMap(doc => {\n const group = groups.get(doc.id);\n return group ? [group] : groupedIds.has(doc.id) ? [] : [doc];\n });\n\n const layoutsChildren = Object.values(layouts.children || {});\n const showcaseChildren = showcase ? Object.values(showcase.children || {}) : [];\n\n // 创建完整菜单树,确保结构正确\n const menuItems: MenuItem[] = [\n {\n ...home,\n icon: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6\" />\n </svg>\n },\n\n {\n id: components.id,\n label: components.label,\n icon: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01\" />\n </svg>,\n children: componentsChildren\n },\n {\n id: layouts.id,\n label: layouts.label,\n icon: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M4 5a1 1 0 011-1h16v6H4V5zm0 9h7v6H4v-6zm11 0h6v6h-6v-6z\" />\n </svg>,\n children: layoutsChildren\n },\n {\n ...charts,\n icon: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M4 19V9m6 10V5m6 14v-7m4 7H2\" />\n </svg>,\n },\n ];\n\n if (advanced) {\n menuItems.push({\n id: advanced.id,\n label: advanced.label,\n icon: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M19.428 15.428a2 2 0 00-1.022-.547l-2.384-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z\" />\n </svg>,\n children: advancedChildren\n });\n }\n\n if (showcase) {\n menuItems.push({\n id: showcase.id,\n label: showcase.label,\n icon: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\" />\n </svg>,\n children: showcaseChildren\n });\n }\n\n return menuItems;\n};\n"],"mappings":"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"}
|