dishui 0.0.71 → 0.0.73
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 +4 -4
- package/dist/components/Button/index.js +18 -17
- package/dist/components/Button/index.js.map +1 -1
- package/dist/components/Card/Metric.d.ts +17 -0
- package/dist/components/Card/Metric2.js +50 -0
- package/dist/components/Card/Metric2.js.map +1 -0
- package/dist/components/Card/index.d.ts +3 -0
- package/dist/components/Card/index.js +118 -117
- package/dist/components/Card/index.js.map +1 -1
- package/dist/components/Group/index.d.ts +2 -0
- package/dist/components/GroupButton/index.d.ts +16 -0
- package/dist/components/GroupButton/index.js +41 -0
- package/dist/components/GroupButton/index.js.map +1 -0
- package/dist/components/GroupedTable/index.d.ts +38 -0
- package/dist/components/GroupedTable/index.js +92 -0
- package/dist/components/GroupedTable/index.js.map +1 -0
- package/dist/components/Layout/index.d.ts +4 -2
- package/dist/components/Layout/index.js +1 -1
- package/dist/components/Layout/index.js.map +1 -1
- package/dist/components/NavigationList/index.d.ts +17 -0
- package/dist/components/NavigationList/index.js +48 -0
- package/dist/components/NavigationList/index.js.map +1 -0
- package/dist/components/Section/index.d.ts +28 -0
- package/dist/components/Section/index.js +58 -0
- package/dist/components/Section/index.js.map +1 -0
- package/dist/components/Select/index.d.ts +2 -0
- package/dist/components/Select/index.js +83 -82
- package/dist/components/Select/index.js.map +1 -1
- package/dist/components/SidebarToggleButton/index.d.ts +16 -1
- package/dist/components/SidebarToggleButton/index.js +90 -30
- package/dist/components/SidebarToggleButton/index.js.map +1 -1
- package/dist/components/Skeleton/index.d.ts +7 -0
- package/dist/components/Skeleton/index.js +21 -0
- package/dist/components/Skeleton/index.js.map +1 -0
- package/dist/components/Tree/Tree.js +5 -2
- package/dist/components/Tree/Tree.js.map +1 -1
- package/dist/components/pro/RichTextEditor/AIRewrite.js +114 -72
- package/dist/components/pro/RichTextEditor/AIRewrite.js.map +1 -1
- package/dist/components/pro/RichTextEditor/BlockHandle.js +315 -196
- package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
- package/dist/components/pro/RichTextEditor/BubbleToolbar.d.ts +1 -1
- package/dist/components/pro/RichTextEditor/BubbleToolbar.js +69 -33
- package/dist/components/pro/RichTextEditor/BubbleToolbar.js.map +1 -1
- package/dist/components/pro/RichTextEditor/CommentPanel.d.ts +2 -1
- package/dist/components/pro/RichTextEditor/CommentPanel.js +100 -81
- package/dist/components/pro/RichTextEditor/CommentPanel.js.map +1 -1
- package/dist/components/pro/RichTextEditor/CommentPopover.d.ts +2 -1
- package/dist/components/pro/RichTextEditor/CommentPopover.js +92 -68
- package/dist/components/pro/RichTextEditor/CommentPopover.js.map +1 -1
- package/dist/components/pro/RichTextEditor/RichTextEditor.js +24 -22
- package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
- package/dist/components/pro/RichTextEditor/SearchReplace.d.ts +7 -0
- package/dist/components/pro/RichTextEditor/SlashMenu.js +136 -73
- package/dist/components/pro/RichTextEditor/SlashMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.d.ts +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js +346 -313
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/CodeBlockView.js +114 -146
- package/dist/components/pro/RichTextEditor/extensions/CodeBlockView.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/CommentMark.js +2 -2
- package/dist/components/pro/RichTextEditor/extensions/CommentMark.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/FloatingDialog.js +178 -163
- package/dist/components/pro/RichTextEditor/extensions/FloatingDialog.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/FontSize.js +8 -5
- package/dist/components/pro/RichTextEditor/extensions/FontSize.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/MarkdownBlock.d.ts +6 -0
- package/dist/components/pro/RichTextEditor/extensions/MarkdownBlock.js +85 -74
- package/dist/components/pro/RichTextEditor/extensions/MarkdownBlock.js.map +1 -1
- package/dist/components/pro/RichTextEditor/searchUtils.d.ts +23 -0
- package/dist/contexts/AppContext.js +47 -45
- package/dist/contexts/AppContext.js.map +1 -1
- package/dist/dishui.css +1 -1
- package/dist/index-nostyled.d.ts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +119 -114
- package/dist/layouts/MainLayout.js +9 -10
- package/dist/layouts/MainLayout.js.map +1 -1
- package/dist/layouts/Sidebar.d.ts +9 -0
- package/dist/layouts/Sidebar.js +99 -80
- package/dist/layouts/Sidebar.js.map +1 -1
- package/dist/layouts/headbar/Headbar.d.ts +1 -1
- package/dist/layouts/headbar/Headbar.js +2 -2
- package/dist/layouts/headbar/Headbar.js.map +1 -1
- package/dist/lite.d.ts +19 -1
- package/dist/lite.js +17 -8
- package/dist/styles/themeStyles.js +6 -6
- package/dist/styles/themeStyles.js.map +1 -1
- package/dist/utils/i18n.d.ts +3 -0
- package/dist/utils/i18n.js +78 -0
- package/dist/utils/i18n.js.map +1 -1
- package/dist/utils/menu.js +23 -6
- package/dist/utils/menu.js.map +1 -1
- package/package.json +8 -2
package/dist/layouts/Sidebar.js
CHANGED
|
@@ -1,31 +1,36 @@
|
|
|
1
1
|
import { generateSidebarActiveStyles as e } from "../styles/themeStyles.js";
|
|
2
2
|
import t from "../components/Tree/Tree.js";
|
|
3
3
|
import { getMenuItems as n } from "../utils/menu.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { DesktopSidebarToggleButton as r } from "../components/SidebarToggleButton/index.js";
|
|
5
|
+
import { useEffect as i, useMemo as a, useRef as o, useState as s } from "react";
|
|
6
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
7
|
+
import { useNavigate as u, useRouterState as d } from "@tanstack/react-router";
|
|
7
8
|
//#region src/layouts/Sidebar.tsx
|
|
8
|
-
var
|
|
9
|
-
let [
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}, [
|
|
13
|
-
|
|
9
|
+
var f = ({ isCollapsed: f, language: p, items: m, getMenuItems: h, onWidthChange: g, initialWidth: _ = 280, collapsedWidth: v = 64, onToggle: y, minWidth: b = 160, maxWidth: x = 400 }) => {
|
|
10
|
+
let [S, C] = s([]), [w, T] = s(""), [E, D] = s(!1), [O, k] = s(_), A = o(null), j = o(null), M = d({ select: (e) => e.location }), N = u();
|
|
11
|
+
i(() => {
|
|
12
|
+
k(_);
|
|
13
|
+
}, [_]);
|
|
14
|
+
let P = (e) => {
|
|
15
|
+
k(e), g?.(e);
|
|
16
|
+
};
|
|
17
|
+
i(() => {
|
|
18
|
+
C(m === void 0 ? h ? h(p) : n(p) : m);
|
|
14
19
|
}, [
|
|
15
|
-
f,
|
|
16
20
|
p,
|
|
17
|
-
m
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
m,
|
|
22
|
+
h
|
|
23
|
+
]), i(() => {
|
|
24
|
+
if (!w) return;
|
|
20
25
|
let e = setTimeout(() => {
|
|
21
|
-
|
|
26
|
+
j.current?.querySelector(".tree-node-content-active")?.scrollIntoView({
|
|
22
27
|
block: "nearest",
|
|
23
28
|
behavior: "smooth"
|
|
24
29
|
});
|
|
25
30
|
}, 350);
|
|
26
31
|
return () => clearTimeout(e);
|
|
27
|
-
}, [
|
|
28
|
-
let e =
|
|
32
|
+
}, [w]), i(() => {
|
|
33
|
+
let e = j.current;
|
|
29
34
|
if (!e) return;
|
|
30
35
|
let t = (t) => {
|
|
31
36
|
if (e.scrollHeight <= e.clientHeight) return;
|
|
@@ -36,35 +41,35 @@ var d = ({ isCollapsed: d, language: f, items: p, getMenuItems: m, onWidthChange
|
|
|
36
41
|
};
|
|
37
42
|
return e.addEventListener("wheel", t, { passive: !1 }), () => e.removeEventListener("wheel", t);
|
|
38
43
|
}, []);
|
|
39
|
-
let
|
|
44
|
+
let F = (e, t = !0) => e.map((e) => ({
|
|
40
45
|
id: e.id,
|
|
41
46
|
label: e.label,
|
|
42
|
-
icon: e.icon || (t ? void 0 : /* @__PURE__ */
|
|
47
|
+
icon: e.icon || (t ? void 0 : /* @__PURE__ */ c("svg", {
|
|
43
48
|
xmlns: "http://www.w3.org/2000/svg",
|
|
44
49
|
className: "h-4 w-4",
|
|
45
50
|
fill: "none",
|
|
46
51
|
viewBox: "0 0 24 24",
|
|
47
52
|
stroke: "currentColor",
|
|
48
|
-
children: /* @__PURE__ */
|
|
53
|
+
children: /* @__PURE__ */ c("path", {
|
|
49
54
|
strokeLinecap: "round",
|
|
50
55
|
strokeLinejoin: "round",
|
|
51
56
|
strokeWidth: "2",
|
|
52
57
|
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"
|
|
53
58
|
})
|
|
54
59
|
})),
|
|
55
|
-
children: e.children ?
|
|
60
|
+
children: e.children ? F(e.children, !1) : void 0,
|
|
56
61
|
meta: { path: e.path }
|
|
57
|
-
})),
|
|
58
|
-
if (
|
|
62
|
+
})), I = a(() => F(S, !0), [S]), L = a(() => {
|
|
63
|
+
if (S.length === 0) return [];
|
|
59
64
|
let e = (t) => {
|
|
60
65
|
let n = [];
|
|
61
66
|
for (let r of t) r.children?.length && (n.push(r.id), n = [...n, ...e(r.children)]);
|
|
62
67
|
return n;
|
|
63
68
|
};
|
|
64
|
-
return e(
|
|
65
|
-
}, [
|
|
66
|
-
return
|
|
67
|
-
let e =
|
|
69
|
+
return e(S);
|
|
70
|
+
}, [S]);
|
|
71
|
+
return i(() => {
|
|
72
|
+
let e = M.pathname, t = (n) => {
|
|
68
73
|
for (let r of n) {
|
|
69
74
|
if (r.path === e) return r.id;
|
|
70
75
|
if (r.children) {
|
|
@@ -73,74 +78,93 @@ var d = ({ isCollapsed: d, language: f, items: p, getMenuItems: m, onWidthChange
|
|
|
73
78
|
}
|
|
74
79
|
}
|
|
75
80
|
return null;
|
|
76
|
-
}, n = t(
|
|
77
|
-
n &&
|
|
78
|
-
}, [
|
|
79
|
-
let e = (
|
|
80
|
-
|
|
81
|
-
}, t = () => {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
let t = e.clientX, n = Math.max(160, Math.min(t, 400));
|
|
86
|
-
T(n), h && h(n);
|
|
81
|
+
}, n = t(S);
|
|
82
|
+
n && T(n);
|
|
83
|
+
}, [S, M.pathname]), i(() => {
|
|
84
|
+
let e = () => {
|
|
85
|
+
D(!1), document.body.style.userSelect = "", document.body.style.cursor = "";
|
|
86
|
+
}, t = (e) => {
|
|
87
|
+
if (E && A.current) {
|
|
88
|
+
let t = A.current.getBoundingClientRect().left, n = e.clientX - t, r = Math.max(160, Math.min(n, 400));
|
|
89
|
+
k(r), g && g(r);
|
|
87
90
|
}
|
|
88
|
-
}
|
|
89
|
-
return
|
|
90
|
-
|
|
91
|
+
};
|
|
92
|
+
return document.addEventListener("mouseup", e), document.addEventListener("mousemove", t), () => {
|
|
93
|
+
document.removeEventListener("mouseup", e), document.removeEventListener("mousemove", t);
|
|
91
94
|
};
|
|
92
95
|
}, [
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
]),
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
96
|
+
E,
|
|
97
|
+
g,
|
|
98
|
+
A
|
|
99
|
+
]), f ? /* @__PURE__ */ l("div", {
|
|
100
|
+
ref: A,
|
|
101
|
+
className: "blade-sidebar h-full bg-base-200 overflow-visible transition-all duration-200 ease-in-out relative",
|
|
102
|
+
style: { width: `${v}px` },
|
|
103
|
+
children: [y && /* @__PURE__ */ c(r, {
|
|
104
|
+
isCollapsed: f,
|
|
105
|
+
onToggle: y,
|
|
106
|
+
sidebarWidth: O,
|
|
107
|
+
collapsedWidth: v,
|
|
108
|
+
onWidthChange: g ? P : void 0,
|
|
109
|
+
minWidth: b,
|
|
110
|
+
maxWidth: x,
|
|
111
|
+
anchorRef: A
|
|
112
|
+
}), /* @__PURE__ */ c("ul", {
|
|
113
|
+
className: "flex flex-col p-2 gap-1 h-full overflow-y-auto overflow-x-hidden",
|
|
114
|
+
children: S.map((e) => /* @__PURE__ */ c("li", { children: e.path ? /* @__PURE__ */ c("button", {
|
|
115
|
+
onClick: () => N({ to: e.path }),
|
|
116
|
+
"aria-label": e.label,
|
|
103
117
|
className: "flex justify-center items-center rounded-lg hover:bg-base-300 transition-colors w-full",
|
|
104
118
|
style: {
|
|
105
119
|
WebkitTapHighlightColor: "transparent",
|
|
106
|
-
height: `${Math.min(
|
|
107
|
-
width: `${Math.min(
|
|
120
|
+
height: `${Math.min(v - 16, 40)}px`,
|
|
121
|
+
width: `${Math.min(v - 16, 40)}px`,
|
|
108
122
|
margin: "0 auto"
|
|
109
123
|
},
|
|
110
|
-
children: e.icon || /* @__PURE__ */
|
|
124
|
+
children: e.icon || /* @__PURE__ */ c("span", {
|
|
111
125
|
className: "text-sm",
|
|
112
126
|
children: e.label.charAt(0)
|
|
113
127
|
})
|
|
114
|
-
}) : /* @__PURE__ */
|
|
128
|
+
}) : /* @__PURE__ */ c("div", {
|
|
115
129
|
className: "flex justify-center items-center",
|
|
116
130
|
style: {
|
|
117
131
|
WebkitTapHighlightColor: "transparent",
|
|
118
|
-
height: `${Math.min(
|
|
119
|
-
width: `${Math.min(
|
|
132
|
+
height: `${Math.min(v - 16, 40)}px`,
|
|
133
|
+
width: `${Math.min(v - 16, 40)}px`,
|
|
120
134
|
margin: "0 auto"
|
|
121
135
|
},
|
|
122
|
-
children: e.icon || /* @__PURE__ */
|
|
136
|
+
children: e.icon || /* @__PURE__ */ c("span", {
|
|
123
137
|
className: "text-sm",
|
|
124
138
|
children: e.label.charAt(0)
|
|
125
139
|
})
|
|
126
140
|
}) }, e.id))
|
|
127
|
-
})
|
|
128
|
-
}) : /* @__PURE__ */
|
|
129
|
-
ref:
|
|
130
|
-
className: "h-full bg-base-200 overflow-
|
|
141
|
+
})]
|
|
142
|
+
}) : /* @__PURE__ */ l("div", {
|
|
143
|
+
ref: A,
|
|
144
|
+
className: "blade-sidebar h-full bg-base-200 overflow-visible flex flex-col transition-colors duration-200 ease-in-out relative",
|
|
131
145
|
style: {
|
|
132
|
-
width: `${
|
|
146
|
+
width: `${O}px`,
|
|
133
147
|
maxWidth: "400px",
|
|
134
148
|
minWidth: "160px"
|
|
135
149
|
},
|
|
136
150
|
children: [
|
|
137
|
-
/* @__PURE__ */
|
|
138
|
-
|
|
151
|
+
y && /* @__PURE__ */ c(r, {
|
|
152
|
+
isCollapsed: f,
|
|
153
|
+
onToggle: y,
|
|
154
|
+
sidebarWidth: O,
|
|
155
|
+
collapsedWidth: v,
|
|
156
|
+
onWidthChange: g ? P : void 0,
|
|
157
|
+
minWidth: b,
|
|
158
|
+
maxWidth: x,
|
|
159
|
+
anchorRef: A
|
|
160
|
+
}),
|
|
161
|
+
/* @__PURE__ */ c("div", {
|
|
162
|
+
ref: j,
|
|
139
163
|
className: "sidebar-scroll min-h-0 flex-grow overflow-y-auto scrollbar-thin scrollbar-thumb-base-300 scrollbar-track-transparent",
|
|
140
|
-
children: /* @__PURE__ */
|
|
141
|
-
data:
|
|
142
|
-
activeNodeId:
|
|
143
|
-
defaultExpandedIds:
|
|
164
|
+
children: /* @__PURE__ */ c(t, {
|
|
165
|
+
data: I,
|
|
166
|
+
activeNodeId: w,
|
|
167
|
+
defaultExpandedIds: L,
|
|
144
168
|
showSearch: !1,
|
|
145
169
|
showExpandAll: !1,
|
|
146
170
|
showIcon: !0,
|
|
@@ -152,7 +176,7 @@ var d = ({ isCollapsed: d, language: f, items: p, getMenuItems: m, onWidthChange
|
|
|
152
176
|
className: "sidebar-tree",
|
|
153
177
|
onNodeClick: (e) => {
|
|
154
178
|
if (e.meta?.path) {
|
|
155
|
-
|
|
179
|
+
T(e.id), N({ to: e.meta.path });
|
|
156
180
|
return;
|
|
157
181
|
}
|
|
158
182
|
if (e.children && e.children.length > 0) {
|
|
@@ -166,17 +190,12 @@ var d = ({ isCollapsed: d, language: f, items: p, getMenuItems: m, onWidthChange
|
|
|
166
190
|
}
|
|
167
191
|
return null;
|
|
168
192
|
}, n = t(e.children);
|
|
169
|
-
n ? (
|
|
170
|
-
} else
|
|
193
|
+
n ? (T(n.id), N({ to: n.meta.path })) : T(e.id);
|
|
194
|
+
} else T(e.id);
|
|
171
195
|
}
|
|
172
196
|
})
|
|
173
197
|
}),
|
|
174
|
-
/* @__PURE__ */
|
|
175
|
-
ref: O,
|
|
176
|
-
className: "absolute top-0 right-0 w-2 h-full cursor-ew-resize hover:bg-primary hover:opacity-50 transition-all z-50",
|
|
177
|
-
style: { right: "-1px" }
|
|
178
|
-
}),
|
|
179
|
-
/* @__PURE__ */ s("style", { children: `
|
|
198
|
+
/* @__PURE__ */ c("style", { children: `
|
|
180
199
|
/* Sidebar Tree 自定义样式 */
|
|
181
200
|
.sidebar-tree {
|
|
182
201
|
background: transparent;
|
|
@@ -201,7 +220,7 @@ var d = ({ isCollapsed: d, language: f, items: p, getMenuItems: m, onWidthChange
|
|
|
201
220
|
|
|
202
221
|
/* 悬停状态 */
|
|
203
222
|
.sidebar-tree .tree-node-content:hover:not(.tree-node-active .tree-node-content):not(.tree-node-content-active) {
|
|
204
|
-
background-color:
|
|
223
|
+
background-color: var(--color-base-200);
|
|
205
224
|
}
|
|
206
225
|
|
|
207
226
|
/* 右侧展开按钮样式 */
|
|
@@ -218,7 +237,7 @@ var d = ({ isCollapsed: d, language: f, items: p, getMenuItems: m, onWidthChange
|
|
|
218
237
|
|
|
219
238
|
.sidebar-tree .tree-node-toggle-right:hover {
|
|
220
239
|
opacity: 1;
|
|
221
|
-
background-color: var(--
|
|
240
|
+
background-color: var(--color-base-300);
|
|
222
241
|
}
|
|
223
242
|
|
|
224
243
|
/* 右侧按钮图标旋转 */
|
|
@@ -317,6 +336,6 @@ var d = ({ isCollapsed: d, language: f, items: p, getMenuItems: m, onWidthChange
|
|
|
317
336
|
});
|
|
318
337
|
};
|
|
319
338
|
//#endregion
|
|
320
|
-
export {
|
|
339
|
+
export { f as default };
|
|
321
340
|
|
|
322
341
|
//# 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';\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\nconst Sidebar: React.FC<SidebarProps> = ({\n isCollapsed,\n language,\n items: propItems,\n getMenuItems,\n onWidthChange,\n initialWidth = 280,\n collapsedWidth = 64,\n}) => {\n const [items, setItems] = useState<MenuItem[]>([]);\n const [activeNodeId, setActiveNodeId] = useState<string | number>('');\n const [isDragging, setIsDragging] = useState(false);\n const [sidebarWidth, setSidebarWidth] = useState(initialWidth); // 使用传入的初始宽度\n const sidebarRef = useRef<HTMLDivElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n const resizeHandleRef = 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(initialWidth);\n }, [initialWidth]);\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 useEffect(() => {\n const handleMouseDown = (e: MouseEvent) => {\n setIsDragging(true);\n document.body.style.userSelect = 'none';\n document.body.style.cursor = 'ew-resize';\n e.preventDefault(); // 防止文本选择\n };\n\n const handleMouseUp = () => {\n setIsDragging(false);\n document.body.style.userSelect = '';\n document.body.style.cursor = '';\n };\n\n const handleMouseMove = (e: MouseEvent) => {\n if (isDragging && sidebarRef.current) {\n const newWidth = e.clientX;\n // 最小宽度160px,最大宽度400px\n const clampedWidth = Math.max(160, Math.min(newWidth, 400));\n setSidebarWidth(clampedWidth);\n if (onWidthChange) {\n onWidthChange(clampedWidth);\n }\n }\n };\n\n const resizeHandle = resizeHandleRef.current;\n if (resizeHandle) {\n resizeHandle.addEventListener('mousedown', handleMouseDown);\n }\n\n document.addEventListener('mouseup', handleMouseUp);\n document.addEventListener('mousemove', handleMouseMove);\n\n return () => {\n if (resizeHandle) {\n resizeHandle.removeEventListener('mousedown', handleMouseDown);\n }\n document.removeEventListener('mouseup', handleMouseUp);\n document.removeEventListener('mousemove', handleMouseMove);\n };\n }, [isDragging, onWidthChange, sidebarRef]);\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 className=\"h-full bg-base-200 overflow-y-auto overflow-x-hidden shadow-lg transition-all duration-300 ease-in-out\"\n style={{ width: `${collapsedWidth}px` }}\n >\n <ul className=\"flex flex-col p-2 gap-1\">\n {items.map(item => (\n <li key={item.id}>\n {item.path ? (\n <button\n onClick={() => navigate({ to: item.path! })}\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=\"h-full bg-base-200 overflow-hidden flex flex-col transition-all duration-300 ease-in-out relative\"\n style={{ width: `${sidebarWidth}px`, maxWidth: '400px', minWidth: '160px' }}\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 {/* 调整大小的手柄 */}\n <div\n ref={resizeHandleRef}\n className=\"absolute top-0 right-0 w-2 h-full cursor-ew-resize hover:bg-primary hover:opacity-50 transition-all z-50\"\n style={{ right: '-1px' }}\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: oklch(var(--b2));\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(--fallback-b3, oklch(var(--b3) / 0.5));\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';\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 [isDragging, setIsDragging] = useState(false);\n const [sidebarWidth, setSidebarWidth] = useState(initialWidth); // 使用传入的初始宽度\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(initialWidth);\n }, [initialWidth]);\n\n // 统一的宽度变更处理:同步内部状态并通知父组件。\n // pill 拖拽与外部同步都通过此入口,避免必须回传 initialWidth 才能生效。\n const handleInternalWidthChange = (width: number) => {\n setSidebarWidth(width);\n onWidthChange?.(width);\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 useEffect(() => {\n const handleMouseUp = () => {\n setIsDragging(false);\n document.body.style.userSelect = '';\n document.body.style.cursor = '';\n };\n\n const handleMouseMove = (e: MouseEvent) => {\n if (isDragging && sidebarRef.current) {\n // 宽度 = 指针位置 - 侧边栏左边缘(适配侧边栏内嵌于页面中的情况)。\n const sidebarLeft = sidebarRef.current.getBoundingClientRect().left;\n const newWidth = e.clientX - sidebarLeft;\n const clampedWidth = Math.max(160, Math.min(newWidth, 400));\n setSidebarWidth(clampedWidth);\n if (onWidthChange) {\n onWidthChange(clampedWidth);\n }\n }\n };\n\n document.addEventListener('mouseup', handleMouseUp);\n document.addEventListener('mousemove', handleMouseMove);\n\n return () => {\n document.removeEventListener('mouseup', handleMouseUp);\n document.removeEventListener('mousemove', handleMouseMove);\n };\n }, [isDragging, onWidthChange, sidebarRef]);\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: '400px', minWidth: '160px' }}\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,8 +1,8 @@
|
|
|
1
1
|
import "react";
|
|
2
2
|
import { jsx as e, jsxs as t } from "react/jsx-runtime";
|
|
3
3
|
//#region src/layouts/headbar/Headbar.tsx
|
|
4
|
-
var n = ({ left: n, middle: r, right: i, height: a =
|
|
5
|
-
className: `navbar bg-base-100
|
|
4
|
+
var n = ({ left: n, middle: r, right: i, height: a = 52, className: o }) => /* @__PURE__ */ t("div", {
|
|
5
|
+
className: `navbar bg-base-100 border-b border-base-300 ${o || ""}`,
|
|
6
6
|
style: {
|
|
7
7
|
height: `${a}px`,
|
|
8
8
|
minHeight: `${a}px`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Headbar.js","names":[],"sources":["../../../src/layouts/headbar/Headbar.tsx"],"sourcesContent":["import React from 'react';\n\nexport type HeadbarProps = {\n /** 左侧插槽内容 */\n left?: React.ReactNode;\n /** 中间插槽内容 */\n middle?: React.ReactNode;\n /** 右侧插槽内容 */\n right?: React.ReactNode;\n /** 高度(像素),默认
|
|
1
|
+
{"version":3,"file":"Headbar.js","names":[],"sources":["../../../src/layouts/headbar/Headbar.tsx"],"sourcesContent":["import React from 'react';\n\nexport type HeadbarProps = {\n /** 左侧插槽内容 */\n left?: React.ReactNode;\n /** 中间插槽内容 */\n middle?: React.ReactNode;\n /** 右侧插槽内容 */\n right?: React.ReactNode;\n /** 高度(像素),默认 52 */\n height?: number;\n /** 自定义 className */\n className?: string;\n};\n\n/**\n * Headbar - 纯布局容器,提供 left / middle / right 三个插槽。\n * 不包含任何业务逻辑,所有内容通过 props 注入。\n */\nconst Headbar: React.FC<HeadbarProps> = ({\n left,\n middle,\n right,\n height = 52,\n className,\n}) => {\n return (\n <div\n className={`navbar bg-base-100 border-b border-base-300 ${className || ''}`}\n style={{\n height: `${height}px`,\n minHeight: `${height}px`,\n maxHeight: `${height}px`,\n }}\n >\n <div className=\"navbar-start\">{left}</div>\n <div className=\"navbar-center hidden lg:flex\">{middle}</div>\n <div className=\"navbar-end\">{right}</div>\n </div>\n );\n};\n\nexport default Headbar;\n"],"mappings":";;;AAmBA,IAAM,KAAmC,EACvC,SACA,WACA,UACA,YAAS,IACT,mBAGE,kBAAC,OAAD;CACE,WAAW,+CAA+C,KAAa;CACvE,OAAO;EACL,QAAQ,GAAG,EAAO;EAClB,WAAW,GAAG,EAAO;EACrB,WAAW,GAAG,EAAO;CACvB;CANF,UAAA;EAQE,kBAAC,OAAD;GAAK,WAAU;GAAgB,UAAA;EAAU,CAAA;EACzC,kBAAC,OAAD;GAAK,WAAU;GAAgC,UAAA;EAAY,CAAA;EAC3D,kBAAC,OAAD;GAAK,WAAU;GAAc,UAAA;EAAW,CAAA;CACrC"}
|
package/dist/lite.d.ts
CHANGED
|
@@ -5,7 +5,25 @@ export type { BadgeProps } from './components/Badge';
|
|
|
5
5
|
export { default as Input } from './components/Input';
|
|
6
6
|
export type { InputProps } from './components/Input';
|
|
7
7
|
export { default as Card } from './components/Card';
|
|
8
|
-
export type { CardProps } from './components/Card';
|
|
8
|
+
export type { CardProps, CardMetricProps, CardMetricItem } from './components/Card';
|
|
9
|
+
export { default as GroupButton } from './components/GroupButton';
|
|
10
|
+
export type { GroupButtonProps, GroupButtonOption } from './components/GroupButton';
|
|
11
|
+
export { default as GroupedTable } from './components/GroupedTable';
|
|
12
|
+
export type { GroupedTableProps, GroupedTableColumn, GroupedTableGroup } from './components/GroupedTable';
|
|
13
|
+
export { default as NavigationList } from './components/NavigationList';
|
|
14
|
+
export type { NavigationListProps, NavigationListItem } from './components/NavigationList';
|
|
15
|
+
export { Tree } from './components/Tree';
|
|
16
|
+
export type { TreeNode, TreeProps } from './components/Tree';
|
|
17
|
+
export { default as Skeleton } from './components/Skeleton';
|
|
18
|
+
export type { SkeletonProps } from './components/Skeleton';
|
|
19
|
+
export { default as Section } from './components/Section';
|
|
20
|
+
export type { SectionProps, SectionSlotProps } from './components/Section';
|
|
21
|
+
export { default as Text } from './components/Text';
|
|
22
|
+
export type { TextProps } from './components/Text';
|
|
23
|
+
export { default as Page } from './components/Page';
|
|
24
|
+
export type { PageProps, PageBodyProps, PageAsideProps, PageMainProps } from './components/Page';
|
|
25
|
+
export { default as EmptyState } from './components/EmptyState';
|
|
26
|
+
export type { EmptyStateProps } from './components/EmptyState';
|
|
9
27
|
export { default as Layout, Container, Grid, GridItem, Flex, Group, Space } from './components/Layout';
|
|
10
28
|
export type { LayoutCompound, LayoutContainerProps, LayoutGridProps, LayoutGridItemProps, LayoutFlexProps, LayoutGroupProps, LayoutSpaceProps, LayoutGap, LayoutMaxWidth, LayoutAlign, LayoutJustify, GridColumns, GridPlacement, } from './components/Layout';
|
|
11
29
|
export { default as Label } from './components/Label';
|
package/dist/lite.js
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import e from "./components/Button/index.js";
|
|
2
|
-
import t from "./components/
|
|
3
|
-
import n from "./components/
|
|
4
|
-
import r from "./components/
|
|
5
|
-
import i from "./components/
|
|
6
|
-
import a from "./components/
|
|
7
|
-
import o from "./components/
|
|
8
|
-
import s
|
|
9
|
-
|
|
2
|
+
import t from "./components/GroupButton/index.js";
|
|
3
|
+
import n from "./components/Skeleton/index.js";
|
|
4
|
+
import r from "./components/GroupedTable/index.js";
|
|
5
|
+
import i from "./components/NavigationList/index.js";
|
|
6
|
+
import a from "./components/Section/index.js";
|
|
7
|
+
import o from "./components/Badge/index.js";
|
|
8
|
+
import s from "./components/Input/index.js";
|
|
9
|
+
import c from "./components/Label/index.js";
|
|
10
|
+
import l from "./components/Checkbox/index.js";
|
|
11
|
+
import u from "./components/Select/index.js";
|
|
12
|
+
import d from "./components/Card/index.js";
|
|
13
|
+
import f from "./components/Page/index.js";
|
|
14
|
+
import p from "./components/EmptyState/index.js";
|
|
15
|
+
import m, { Container as h, Flex as g, Grid as _, GridItem as v, Group as y, Space as b } from "./components/Layout/index.js";
|
|
16
|
+
import x from "./components/Text/index.js";
|
|
17
|
+
import S from "./components/Tree/Tree.js";
|
|
18
|
+
export { o as Badge, e as Button, d as Card, l as Checkbox, h as Container, p as EmptyState, g as Flex, _ as Grid, v as GridItem, y as Group, t as GroupButton, r as GroupedTable, s as Input, c as Label, m as Layout, i as NavigationList, f as Page, a as Section, u as Select, n as Skeleton, b as Space, x as Text, S as Tree };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
//#region src/styles/themeStyles.ts
|
|
2
2
|
var e = {
|
|
3
3
|
light: {
|
|
4
|
-
backgroundColor: "
|
|
5
|
-
borderColor: "
|
|
6
|
-
textColor: "
|
|
4
|
+
backgroundColor: "var(--blade-accent)",
|
|
5
|
+
borderColor: "var(--blade-accent)",
|
|
6
|
+
textColor: "var(--blade-accent-fg)"
|
|
7
7
|
},
|
|
8
8
|
dark: {
|
|
9
|
-
backgroundColor: "
|
|
10
|
-
borderColor: "
|
|
11
|
-
textColor: "
|
|
9
|
+
backgroundColor: "var(--blade-accent)",
|
|
10
|
+
borderColor: "var(--blade-accent)",
|
|
11
|
+
textColor: "var(--blade-accent-fg)"
|
|
12
12
|
},
|
|
13
13
|
cursor: {
|
|
14
14
|
backgroundColor: "rgba(96, 165, 250, 0.16)",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"themeStyles.js","names":[],"sources":["../../src/styles/themeStyles.ts"],"sourcesContent":["// 共用主题样式配置\n// 用于 Tree 组件和 Sidebar 组件的活跃状态样式\n\nexport interface ThemeActiveStyle {\n backgroundColor: string;\n borderColor: string;\n textColor: string;\n}\n\n// 主题配色映射\nexport const themeActiveStyles: Record<string, ThemeActiveStyle> = {\n light: {\n backgroundColor: '
|
|
1
|
+
{"version":3,"file":"themeStyles.js","names":[],"sources":["../../src/styles/themeStyles.ts"],"sourcesContent":["// 共用主题样式配置\n// 用于 Tree 组件和 Sidebar 组件的活跃状态样式\n\nexport interface ThemeActiveStyle {\n backgroundColor: string;\n borderColor: string;\n textColor: string;\n}\n\n// 主题配色映射\nexport const themeActiveStyles: Record<string, ThemeActiveStyle> = {\n light: {\n backgroundColor: 'var(--blade-accent)',\n borderColor: 'var(--blade-accent)',\n textColor: 'var(--blade-accent-fg)',\n },\n dark: {\n backgroundColor: 'var(--blade-accent)',\n borderColor: 'var(--blade-accent)',\n textColor: 'var(--blade-accent-fg)',\n },\n cursor: {\n backgroundColor: 'rgba(96, 165, 250, 0.16)',\n borderColor: 'rgb(96, 165, 250)',\n textColor: 'rgb(147, 197, 253)',\n },\n retro: {\n backgroundColor: 'rgba(239, 68, 68, 0.15)',\n borderColor: 'rgb(239, 68, 68)',\n textColor: 'rgb(239, 68, 68)',\n },\n cyberpunk: {\n backgroundColor: 'rgba(255, 221, 0, 0.18)',\n borderColor: 'rgb(255, 221, 0)',\n textColor: 'rgb(255, 221, 0)',\n },\n matrix: {\n backgroundColor: 'rgba(0, 255, 65, 0.15)',\n borderColor: 'rgb(0, 255, 65)',\n textColor: 'rgb(0, 255, 65)',\n },\n oceanblue: {\n backgroundColor: 'rgba(6, 95, 212, 0.18)',\n borderColor: 'rgb(6, 95, 212)',\n textColor: 'rgb(6, 95, 212)',\n },\n eyecare: {\n backgroundColor: 'rgba(34, 139, 34, 0.18)',\n borderColor: 'rgb(34, 139, 34)',\n textColor: 'rgb(34, 139, 34)',\n },\n ghibli: {\n backgroundColor: 'rgba(249, 115, 22, 0.18)',\n borderColor: 'rgb(249, 115, 22)',\n textColor: 'rgb(249, 115, 22)',\n },\n pinkgirl: {\n backgroundColor: 'rgba(236, 72, 153, 0.15)',\n borderColor: 'rgb(236, 72, 153)',\n textColor: 'rgb(236, 72, 153)',\n },\n mintgirl: {\n backgroundColor: 'rgba(52, 211, 153, 0.15)',\n borderColor: 'rgb(52, 211, 153)',\n textColor: 'rgb(52, 211, 153)',\n },\n\n wuxing: {\n backgroundColor: 'rgba(180, 120, 60, 0.15)',\n borderColor: 'rgb(180, 120, 60)',\n textColor: 'rgb(140, 90, 40)',\n },\n jukebox: {\n backgroundColor: 'rgba(147, 51, 234, 0.18)',\n borderColor: 'rgb(147, 51, 234)',\n textColor: 'rgb(167, 139, 250)',\n },\n};\n\n// 生成 Tree 组件的主题活跃状态 CSS\nexport const generateTreeActiveStyles = (): string => {\n return Object.entries(themeActiveStyles)\n .map(([theme, style]) => `\n /* ${theme.charAt(0).toUpperCase() + theme.slice(1)} 主题 */\n [data-theme=\"${theme}\"] .tree-node-content-active {\n background-color: ${style.backgroundColor} !important;\n border-left: 4px solid ${style.borderColor} !important;\n color: ${style.textColor} !important;\n }\n [data-theme=\"${theme}\"] .tree-node-content-active .tree-node-icon,\n [data-theme=\"${theme}\"] .tree-node-content-active .tree-node-label {\n color: ${style.textColor} !important;\n }`)\n .join('\\n');\n};\n\n// 生成 Sidebar 组件的主题活跃状态 CSS\nexport const generateSidebarActiveStyles = (): string => {\n return Object.entries(themeActiveStyles)\n .map(([theme, style]) => `\n /* ${theme.charAt(0).toUpperCase() + theme.slice(1)} 主题 */\n [data-theme=\"${theme}\"] .sidebar-tree .tree-node-content-active {\n background-color: ${style.backgroundColor} !important;\n border-left: 4px solid ${style.borderColor} !important;\n }\n [data-theme=\"${theme}\"] .sidebar-tree .tree-node-content-active .tree-node-label,\n [data-theme=\"${theme}\"] .sidebar-tree .tree-node-content-active .tree-node-icon svg {\n color: ${style.textColor} !important;\n stroke: ${style.textColor} !important;\n }`)\n .join('\\n');\n};\n\n"],"mappings":";AAUA,IAAa,IAAsD;CACjE,OAAO;EACL,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,MAAM;EACJ,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,QAAQ;EACN,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,OAAO;EACL,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,WAAW;EACT,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,QAAQ;EACN,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,WAAW;EACT,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,SAAS;EACP,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,QAAQ;EACN,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,UAAU;EACR,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,UAAU;EACR,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CAEA,QAAQ;EACN,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,SAAS;EACP,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;AACF,GAGa,UACJ,OAAO,QAAQ,CAAiB,CAAC,CACrC,KAAK,CAAC,GAAO,OAAW;aAChB,EAAM,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,EAAM,MAAM,CAAC,EAAE;uBACrC,EAAM;8BACC,EAAM,gBAAgB;mCACjB,EAAM,YAAY;mBAClC,EAAM,UAAU;;uBAEZ,EAAM;uBACN,EAAM;mBACV,EAAM,UAAU;UACzB,CAAC,CACN,KAAK,IAAI,GAID,UACJ,OAAO,QAAQ,CAAiB,CAAC,CACrC,KAAK,CAAC,GAAO,OAAW;aAChB,EAAM,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,EAAM,MAAM,CAAC,EAAE;uBACrC,EAAM;8BACC,EAAM,gBAAgB;mCACjB,EAAM,YAAY;;uBAE9B,EAAM;uBACN,EAAM;mBACV,EAAM,UAAU;oBACf,EAAM,UAAU;UAC1B,CAAC,CACN,KAAK,IAAI"}
|