界面与页面
shadcn/ui 技术栈、命令面板、布局与内置页面。
渲染进程是一个标准的 React SPA:Tailwind v4、shadcn/ui、带懒加载路由的 react-router、一个 cmdk 命令面板,以及 sonner 提示。本页梳理 UI 层,并逐一列出 你所继承的页面。
技术栈
| 关注点 | 库 | 位置 |
|---|---|---|
| 样式 | Tailwind v4 + tw-animate-css | app/styles/globals.css |
| 组件 | shadcn/ui(new-york 风格) | app/components/ui/、components.json |
| 命令面板 | cmdk | app/components/command-palette/ |
| 提示 | sonner | app/components/ui/(Toaster)+ use-toast |
| 动画 | framer-motion | 引导、过渡 |
| 路由 | react-router 7(HashRouter) | app/app.tsx |
路由使用 HashRouter——打包构建中渲染进程从 file:// 文档加载,哈希路由可避开
服务端路径解析。用 pnpm dlx shadcn@latest add <component> 添加 shadcn 组件;
new-york 风格与 CSS 变量主题已在 components.json 中配置好。强调色层参见
主题。
布局与侧边栏
AppShell(app/components/layout/)用自定义标题栏、侧边栏与内容区包裹已登录的
页面。认证界面改用 ShellLessLayout。侧边栏由 sidebar-items.ts 数据驱动,分为
工作区(Workspace)、模板(Template,受标志开关控制的能力展示)与
应用(Application)三组:
// app/components/layout/sidebar-items.ts
export const SIDEBAR_GROUPS = [
{ id: 'workspace', items: [{ id: 'home', to: '/home', /* ... */ }] },
// [template-demo] 模板分组——仅在 showcase 启用时出现
{ id: 'application', items: [/* 账单(受标志控制)、日志、帮助、设置、关于 */] },
]账单仅在 billingConfig.enabled 时出现,模板分组仅在 showcaseConfig.enabled
时出现——因此被裁剪的构建不会留下失效入口。
命令面板
面板用 Cmd/Ctrl+K 打开(一个应用内快捷键,并非全局热键——参见
通知与快捷键)。它的内容来自
command-sources.ts 中的命令源:
| 命令源 | 提供 |
|---|---|
routesSource | 应用路由(首页、设置、关于、账户、日志、帮助、更新,以及启用时的账单)。 |
settingsSource | 每一项可搜索的设置,深链到其标签页(/settings?tab=…)。 |
recentFilesSource | 最近打开的文件。 |
showcaseSource | 能力展示演示(受标志控制,[template-demo])。 |
用 registerCommandSource 从应用代码注册你自己的命令,它会返回一个取消注册的
函数:
import { registerCommandSource } from '@/app/components/command-palette/command-sources'
const off = registerCommandSource((ctx) => [
{ id: 'export', title: ctx.t('common:actions.export'), group: 'navigation', perform: () => {/* ... */} },
])页面清单
路由采用代码分割(React.lazy),因此初始包只承载外壳;每个页面在首次导航时才
解析。
| 页面 | 路由 | 是什么 |
|---|---|---|
| 首页 | /home | 落地面板:一份改品牌清单、中性快捷操作(日志/设置/帮助),以及——当 showcase 开启时——能力目录。 |
| 帮助 | /help | 文档链接、反馈 mailto、指向 ${REPO_URL}/issues/new 的报错链接,外加跳转到日志。 |
| 关于 | /about | 应用/系统诊断,带一个已脱敏的"复制诊断信息"按钮。 |
| 更新 | /update | 更新状态与手动检查/下载/安装。参见自动更新。 |
| 日志 | /logs | 日志文件路径 +"打开日志文件夹"。参见可观测性。 |
| 设置 | /settings | 设置中心。参见设置存储。 |
| 账户 | /account | 个人资料 + 头像。参见示例功能。 |
| 账单 | /billing | 套餐与授权(受标志控制)。参见账单。 |
| 错误 / 未找到 | /error、* | 带主题的 ErrorPage 与 NotFoundPage。 |
帮助页的支持入口由品牌驱动:反馈 mailto 使用 SUPPORT_EMAIL,报错链接使用
shared/constants.ts 中的 REPO_URL,因此改品牌会
自动重定向它们。
引导
OnboardingGate(app/components/onboarding/)读取持久化设置,并在设置
onboardingCompleted 之前显示一个首次运行流程。它可选地以 EULA 作为门槛:
让 shared/constants.ts 中的 EULA_URL 留空即可不带 EULA 出厂(默认),或
设置它(连同 EULA_VERSION)来要求接受——提升版本会强制重新接受。完成状态经由
设置存储持久化,因此每次安装只显示一次。
添加一个页面
添加路由
在 app/app.tsx 的 AppShell 元素内添加一个懒加载导入与一个 <Route>。
加入导航
添加一条 sidebar-items.ts 记录(且/或让 routesSource 在面板中呈现它)。
(若可深链)把路由加入白名单
把它加入 event-schema.ts 的 navigationRouteSchema,使深度链接能抵达它。参见
深度链接。
