From b3b4cbbe1a44d2e803f9c3da47a1454dddedd7e7 Mon Sep 17 00:00:00 2001 From: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com> Date: Wed, 28 Oct 2026 10:20:26 +0800 Subject: [PATCH] feat(settings): Group page description, collapsed page tree and a seamless title bar - Group pages open with a short description and list their pages as indented links. - The page tree starts collapsed, expanding only the current page's ancestors. - The Settings window title bar sits on the dialog surface without a hairline. --- .../settings/dialog/SettingsDialog.module.css | 29 ++++++++++---- .../settings/dialog/SettingsDialog.tsx | 40 +++++++++++++++---- src/platform/locales/text/zh.json | 7 +++- src/workbench/TitleBar.module.css | 5 +++ src/workbench/TitleBar.tsx | 2 +- 5 files changed, 66 insertions(+), 17 deletions(-) diff --git a/src/features/settings/dialog/SettingsDialog.module.css b/src/features/settings/dialog/SettingsDialog.module.css index 19a24314..24fdea93 100644 --- a/src/features/settings/dialog/SettingsDialog.module.css +++ b/src/features/settings/dialog/SettingsDialog.module.css @@ -147,24 +147,37 @@ } .groupPage { + padding-top: 8px; +} +.groupDescription { + margin: 0 0 14px; + max-width: 720px; + color: var(--fg); + line-height: 1.45; +} +.groupLinks { display: flex; flex-direction: column; - max-width: 420px; + align-items: flex-start; + gap: 2px; + padding-left: 32px; } .groupLink { - display: flex; - align-items: center; - justify-content: space-between; - height: 28px; - padding: 0 8px; - border-radius: var(--radius-row); + height: 20px; + padding: 0; + border: 0; + background: none; color: var(--link); + font: inherit; text-align: left; cursor: pointer; } .groupLink:hover { - background: var(--bg-hover); color: var(--link-hover); + text-decoration: underline; +} +.groupLink:focus-visible { + outline: 2px solid var(--focus-ring, var(--accent)); } .footerStatus { diff --git a/src/features/settings/dialog/SettingsDialog.tsx b/src/features/settings/dialog/SettingsDialog.tsx index 0fcd8734..233977a0 100644 --- a/src/features/settings/dialog/SettingsDialog.tsx +++ b/src/features/settings/dialog/SettingsDialog.tsx @@ -42,20 +42,46 @@ import { PageErrorBoundary } from "./PageErrorBoundary"; import styles from "./SettingsDialog.module.css"; import { tx } from "@/platform/i18n"; +/** Keys of the nodes above `key`, root first. */ +function ancestorKeys(nodes: readonly PageNode[], key: string): string[] { + for (const n of nodes) { + if (n.key === key) return []; + const sub = ancestorKeys(n.children, key); + if (sub.length || n.children.some((c) => c.key === key)) return [n.key, ...sub]; + } + return []; +} + function firstPage(nodes: readonly PageNode[]): string | null { const list = flatten(nodes).filter((n) => n.page); return (list.find((n) => n.matched) ?? list[0])?.key ?? null; } +const GROUP_DESCRIPTIONS: Record = { + "Appearance & Behavior": + "Customize IDE appearance and behavior: change themes and font size, configure system settings and notifications.", + Editor: "Configure code editing: completion, folding, tabs, fonts, colors, code style and inspections.", + "Build, Execution, Deployment": "Configure build tools, run configurations, debugger and deployment.", + "Languages & Frameworks": "Configure language servers, interpreters, SDKs and framework support.", + Tools: "Configure external tools, terminal, database and other integrations.", +}; + function GroupPage({ node }: { node: PageNode }) { + const description = GROUP_DESCRIPTIONS[node.title]; return (
- {node.children.map((c) => ( - - ))} + {description && ( +

+ {description} +

+ )} +
+ {node.children.map((c) => ( + + ))} +
); } @@ -263,7 +289,7 @@ export function SettingsLayout() { getLabel={(n) => tx(n.title)} getChildren={(n) => (n.children.length ? n.children : undefined)} isExpandable={(n) => n.children.length > 0} - defaultExpanded={all.filter((n) => n.children.length).map((n) => n.key)} + defaultExpanded={current ? ancestorKeys(tree, current.key) : []} expanded={query ? expanded : undefined} selected={current ? new Set([current.key]) : new Set()} onSelectionChange={(_sel, node) => node && selectPage(node.key)} diff --git a/src/platform/locales/text/zh.json b/src/platform/locales/text/zh.json index df19d125..c2e07b3a 100644 --- a/src/platform/locales/text/zh.json +++ b/src/platform/locales/text/zh.json @@ -4198,5 +4198,10 @@ "0 results": "0 个结果", "Time the agent took to answer": "智能体回答所用的时间", "Edit and Resend": "编辑后重新发送", - "Send Again": "再次发送" + "Send Again": "再次发送", + "Customize IDE appearance and behavior: change themes and font size, configure system settings and notifications.": "自定义 IDE 的外观和行为:更改主题和字号,配置系统设置和通知。", + "Configure code editing: completion, folding, tabs, fonts, colors, code style and inspections.": "配置代码编辑:补全、折叠、标签页、字体、配色、代码样式和检查。", + "Configure build tools, run configurations, debugger and deployment.": "配置构建工具、运行配置、调试器和部署。", + "Configure language servers, interpreters, SDKs and framework support.": "配置语言服务器、解释器、SDK 和框架支持。", + "Configure external tools, terminal, database and other integrations.": "配置外部工具、终端、数据库和其他集成。" } diff --git a/src/workbench/TitleBar.module.css b/src/workbench/TitleBar.module.css index 7c567d97..afed9c4b 100644 --- a/src/workbench/TitleBar.module.css +++ b/src/workbench/TitleBar.module.css @@ -19,6 +19,11 @@ background: var(--bg-elev); box-shadow: inset 0 -1px 0 var(--border); } +/* Dialog window (Settings): the title sits on the dialog surface, no hairline. */ +.dialogBar { + background: var(--bg-dialog, var(--bg-elev)); + box-shadow: none; +} .windowTitle { min-width: 0; overflow: hidden; diff --git a/src/workbench/TitleBar.tsx b/src/workbench/TitleBar.tsx index 21266e1d..eb77cee5 100644 --- a/src/workbench/TitleBar.tsx +++ b/src/workbench/TitleBar.tsx @@ -292,7 +292,7 @@ export function TitleBar({ const entry = (id: string) => ; return (
{ if (minimal || e.defaultPrevented) return;