From 617c3c7e70221c1e49d0652729e6b62dacaef62e Mon Sep 17 00:00:00 2001
From: sikongyue <3155157671@qq.com>
Date: Thu, 20 Aug 2026 00:50:17 +0800
Subject: [PATCH] =?UTF-8?q?feat(web):=20=E5=B7=A5=E4=BD=9C=E5=8C=BA?=
=?UTF-8?q?=E5=B8=83=E5=B1=80=20-=20=E4=BE=A7=E6=A0=8F=E5=88=86=E7=BB=84?=
=?UTF-8?q?=E5=AF=BC=E8=88=AA=E6=94=AF=E6=8C=81=E6=8A=98=E5=8F=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新增 NavGroup 组件:有标题的分组(工作台管理)可点击折叠/展开,Chevron 旋转指示,grid-rows 平滑动画;激活项所在分组自动展开\n- 折叠按钮借鉴 SelectItem 交互:紧凑 28px 高度、hover/focus-visible 浅背景反馈、标签文字与图标随 hover 加深(36% -> 55% / 35% -> 70%)\n- 无标题主分组(核心导航入口)保持常驻;分组标签 padding 移交折叠按钮,样式单一来源
---
.../layout/workspace-sidebar-nav.tsx | 79 +++++++++++++++----
web/src/styles/globals.css | 33 +++++++-
2 files changed, 95 insertions(+), 17 deletions(-)
diff --git a/web/src/components/layout/workspace-sidebar-nav.tsx b/web/src/components/layout/workspace-sidebar-nav.tsx
index e81a4e9dd..e5c45c1de 100644
--- a/web/src/components/layout/workspace-sidebar-nav.tsx
+++ b/web/src/components/layout/workspace-sidebar-nav.tsx
@@ -266,6 +266,62 @@ function NavItem({ item, activeId, onSelect, onOpenSearch, onLogout, level = 0 }
);
}
+function NavGroup({ group, activeId, onNavigate, onOpenSearch, onLogout }: {
+ group: WorkspaceNavGroup;
+ activeId: string;
+ onNavigate: () => void;
+ onOpenSearch: () => void;
+ onLogout: () => void;
+}) {
+ const [isOpen, setIsOpen] = useState(true);
+ const hasActive = group.items.some((item) => item.id === activeId || (item.id === "settings" && activeId.startsWith("settings:")));
+
+ // 激活项所在分组自动展开,保证当前位置可见。
+ useEffect(() => {
+ if (hasActive) setIsOpen(true);
+ }, [hasActive]);
+
+ const content = (
+
+ {group.items.map((item) => (
+
+ ))}
+
+ );
+
+ // 无标题分组(核心导航入口)常驻展示,不做折叠。
+ if (!group.heading) {
+ return {content}
;
+ }
+
+ return (
+
+
+
+
+ );
+}
+
export function WorkspaceSidebarNav({ onNavigate, onOpenSearch }: { onNavigate: () => void; onOpenSearch: () => void }) {
const { pathname } = useLocation();
const [searchParams] = useSearchParams();
@@ -325,21 +381,14 @@ export function WorkspaceSidebarNav({ onNavigate, onOpenSearch }: { onNavigate:
)}
>
{groups.map((group, index) => (
-
- {group.heading ?
{group.heading} : null}
-
- {group.items.map((item) => (
- void handleLogout()}
- />
- ))}
-
-
+ void handleLogout()}
+ />
))}
diff --git a/web/src/styles/globals.css b/web/src/styles/globals.css
index a2d26fc38..cec08d8e9 100644
--- a/web/src/styles/globals.css
+++ b/web/src/styles/globals.css
@@ -941,15 +941,44 @@
pointer-events: none;
}
- /* 分组标题:小号大写标签,弱化但可读 */
+ /* 分组标题:小号大写标签,弱化但可读;有标题的分组支持折叠,padding/间距由折叠按钮接管 */
.app-workspace-nav-group-label {
display: block;
- padding: 0 10px 6px;
font-size: var(--fs-label);
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: color-mix(in srgb, var(--foreground) 36%, transparent);
+ transition: color var(--motion-instant) ease-out;
+ }
+
+ .app-workspace-nav-group-toggle {
+ display: flex;
+ width: 100%;
+ min-height: 28px;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+ padding: 0 8px;
+ border-radius: var(--r-sm);
+ text-align: left;
+ color: inherit;
+ transition: background-color var(--motion-instant) ease-out;
+ }
+
+ .app-workspace-nav-group-toggle:hover,
+ .app-workspace-nav-group-toggle:focus-visible {
+ background: var(--surface-hover);
+ }
+
+ .app-workspace-nav-group-toggle:hover .app-workspace-nav-group-label,
+ .app-workspace-nav-group-toggle:focus-visible .app-workspace-nav-group-label {
+ color: color-mix(in srgb, var(--foreground) 55%, transparent);
+ }
+
+ .app-workspace-nav-group-toggle:hover svg,
+ .app-workspace-nav-group-toggle:focus-visible svg {
+ color: color-mix(in srgb, var(--foreground) 70%, transparent);
}
/* 工作区切换器下拉浮层 */