18 KiB
参考 URDF-Studio 补全前端组件计划
Context
目标是在不改变现有 MuJoCo 导入、编译、仿真、渲染和资源生命周期逻辑的前提下,参考本机 /home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio 的前端信息架构与视觉样式,逐项补全 wasm/web_platform 缺少的前端组件。
关键约束:
- 只借鉴前端布局、视觉语言与交互组织,不直接迁移 URDF-Studio 的机器人解析、编辑或 Three.js 运行时。
- 新组件接入前必须先向用户展示候选清单、用途、影响范围并逐项获得确认。
- 第一批 A–H 已按批准计划实施;后续新增组件仍遵循先确认再接入。
初步现状:
- 本项目 UI 高度集中在
wasm/web_platform/src/app/App.tsx,已有顶部工具栏、工程/模型结构左栏、三维视口、模型控制右栏、底部性能状态栏、入口选择、加载态和诊断卡片。 - MuJoCo 与 Three.js 对象由
MainThreadPhysicsAdapter、MuJoCoViewer和 React refs 持有;Zustand 仅保存 UI 可消费快照。后续 UI 重构应保持这一边界。 - URDF-Studio 已将 Header、WorkspaceSidebars、Viewer overlays、通用 UI 控件、拖动窗口、设置弹窗等拆成独立组件,可作为组件边界和样式参考。
- 当前资源树和模型结构树已具备纯数据构建函数及单测,不应重写;只需替换字符图标、颜色和行样式,并保留原有树语义。
- 当前没有
App.tsx级组件测试;后续应通过抽出无状态壳层组件来增加 UI 测试,避免在测试中初始化 WebGL/WASM。
已确认产品方向:
- 第一批聚焦工作台外壳:顶部工具栏、可折叠侧栏、视口工具、底部状态栏、通知与弹窗。
- 只采用 URDF-Studio 的专业工作台风格,保留 MuJoCo 平台品牌、中文信息架构和现有布局特色,不做像素级复刻。
- 允许新增
lucide-react,用于替代当前字符/Emoji 图标并统一视觉语言。
Approach
- 对照两个项目的页面壳层、工具栏、左右侧栏、视口叠层、弹窗/通知和基础控件,形成“已有 / 缺少 / 不适用”的组件差异表。
- 将候选组件按纯展示、现有动作封装、需要新增产品能力三类分级;第一目标只推荐前两类,避免触碰底层 MuJoCo 逻辑。
- 第一批 A–H 已全部获得用户确认;后续若发现需要新增候选组件,必须再次确认,不能顺带加入。
- 先建立精简语义样式令牌和无状态基础组件,再拆分
App.tsx的布局组件;业务回调继续由App注入,adapter/viewer 生命周期不下沉到展示组件。 - 第一批布局采用 40px 紧凑 Header、现有左右固定侧栏和 28px 状态栏;交互模式工具组停靠在 Header 中央。右栏默认展开“模型信息、当前选择、关节”,折叠其他低频分区。
- 不照搬 URDF-Studio 的移动端底部工具条、复杂响应式菜单或 Floating UI。保持当前
min-w-[1024px]桌面产品边界。 - 每批只接入少量组件并执行回归验证,确保模型导入、仿真和三维交互行为不变。
Files to modify
wasm/web_platform/src/app/App.tsx:仅保留 viewer/adapter 生命周期、业务状态和事件编排,以 props 连接新 UI 组件。wasm/web_platform/src/app/components/WorkbenchHeader.tsx:品牌区、文件导入、仿真传输控制、速度、面板/主题动作与中央工具栏插槽。wasm/web_platform/src/app/components/ViewerToolDock.tsx:select/joint/force 模式与相机复位的图标工具组。wasm/web_platform/src/app/components/SidebarPanel.tsx:左右侧栏壳层、标题、折叠分区和滚动区域。wasm/web_platform/src/app/components/StatusBar.tsx:性能、WASM 和快捷键状态。wasm/web_platform/src/app/components/EntrySelectionDialog.tsx:多入口选择的领域弹窗。wasm/web_platform/src/app/components/DiagnosticNotice.tsx:诊断摘要、路径和可展开详情。wasm/web_platform/src/app/components/WorkspaceOverlays.tsx:加载 HUD、空工作区和中心叠层组织。wasm/web_platform/src/components/ui/Button.tsx、IconButton.tsx、Tooltip.tsx、Select.tsx、Dialog.tsx、CollapsibleSection.tsx、ToolbarToggleGroup.tsx:第一批基础控件。wasm/web_platform/src/components/ui/index.ts:稳定导出边界。wasm/web_platform/src/project/ProjectTree.tsx、ModelStructureTree.tsx:仅做令牌化视觉和 Lucide 图标替换,保留构树逻辑及公开 props。wasm/web_platform/src/app/ErrorBoundary.tsx:使用新基础控件和语义样式,不改错误边界行为。wasm/web_platform/src/styles.css、wasm/web_platform/tailwind.config.cjs:颜色、表面、文字、强调色、滚动条、焦点环和组件令牌;移除依赖深色工具类覆盖的主题实现。wasm/web_platform/src/app/components/*.test.tsx、wasm/web_platform/src/components/ui/*.test.tsx:新增组件测试。wasm/web_platform/e2e/app.spec.ts:保持业务断言并更新因图标化/折叠带来的交互定位。wasm/package.json/wasm/package-lock.json:加入已确认的lucide-react;不引入@floating-ui/react。
Reuse
本项目继续复用:
wasm/web_platform/src/app/App.tsx中的导入、加载、播放/暂停、单步、重置、模式切换及面板状态回调。wasm/web_platform/src/stores/useAppStore.ts的工程、快照、选择、性能和诊断状态。wasm/web_platform/src/project/ProjectTree.tsx与ModelStructureTree.tsx。wasm/web_platform/src/simulation/PhysicsAdapter.ts和SimulationSession.ts(保持不改或仅由现有接口调用)。wasm/web_platform/src/viewer/MuJoCoViewer.ts(保持渲染和交互接口不变)。
样式/结构参考(只读来源):
/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/app/components/Header.tsx/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/app/components/workspace/WorkspaceSidebars.tsx/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/app/components/AppLayoutView.tsx/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/shared/components/ui//home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/shared/components/Panel/OptionsPanel.tsx:参考可折叠分区及紧凑面板标题,不移植拖动/悬浮窗逻辑。/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/features/urdf-viewer/components/ViewerToolbar.tsx:参考图标化工具模式组和活动态,不移植 Portal/移动端工具条。/home/cen/Embodied_Workspace/Mujoco_Projects/URDF-Studio/src/styles/index.css:仅提炼语义表面、边框、文字、强调色、滚动条和 focus ring;不复制其 AI、编辑器、字体缩放等无关样式。
第一批组件(已确认)
| 编号 | 候选组件 | 复用现有能力 | 预期变化 | 底层风险 |
|---|---|---|---|---|
| A ✅ | WorkbenchHeader |
导入、播放、单步、重置、速度、主题、面板开关回调 | 40px 紧凑品牌栏,动作分组,Lucide 图标 + 文案/提示 | 低,仅回调透传 |
| B ✅ | ViewerToolDock + ToolbarToggleGroup |
select/joint/force 模式、相机复位 | Header 中央停靠工具组,活动态更清晰 | 低,仅调用现有 mode/viewer API |
| C ✅ | SidebarPanel + CollapsibleSection |
左右侧栏现有内容和开关 | 统一面板标题、滚动条、分区折叠;保留 resize-x;右栏低频区默认折叠 | 低,内容插槽化 |
| D ✅ | StatusBar |
时间、FPS、step、内存、WASM、预算警告 | 图标化状态、语义色和更紧凑层级 | 低,纯展示 |
| E ✅ | Dialog + EntrySelectionDialog |
多入口 loadEntry |
Portal、Esc、焦点圈定、焦点恢复和统一弹窗外观 | 低,不改入口判断/加载 |
| F ✅ | DiagnosticNotice |
AppDiagnostic |
摘要以通知样式展示,可展开技术详情;保留手动关闭 | 低,不改错误生成 |
| G ✅ | LoadingOverlay + EmptyWorkspace |
loading、空状态、拖放导入 |
统一 HUD、图标、引导层次,不伪造加载百分比 | 低,纯展示 |
| H ✅ | 基础 UI:Button、IconButton、Tooltip、Select |
替换 .btn/.icon-btn/.field |
统一尺寸、变体、禁用态、focus ring;Tooltip 不增加 Floating UI 依赖 | 低,HTML 原生语义 |
Steps
- 审计 URDF-Studio 页面布局、样式令牌和第一批组件职责。
- 审计本项目已有组件及其与 MuJoCo/viewer 的耦合边界。
- 形成第一批组件差异矩阵;排除源码编辑、属性编辑、导出、快照、AI、测量、绘制、撤销/重做、移动端工具条等新增业务能力。
- 获得用户对第一批 A–H、Header 中央工具组和右栏默认折叠策略的确认。
- 基础层:安装
lucide-react;定义 light/dark 语义 CSS 变量并映射到 Tailwind;实现 Button、IconButton、Tooltip、Select、Dialog、CollapsibleSection、ToolbarToggleGroup。Tooltip 使用 hover/focus CSS 展示,Dialog 使用 portal、Esc、焦点圈定和焦点恢复。 - 工作台壳层:实现 40px
WorkbenchHeader,左侧保留 MuJoCo 品牌和文件动作,中间放 select/joint/force 工具组,右侧放相机、侧栏和主题动作;保留按钮可访问名称及原有回调。 - 侧栏拆分:实现
SidebarPanel,将左栏工程资源/模型结构和右栏模型信息、URDF、警告、选择、Actuator、关节、外力内容从App.tsx搬入展示组件;业务回调和adapter.current调用仍在App中生成后传入。右栏“模型信息、当前选择、关节”默认展开,其余默认折叠,警告出现时自动展开。 - 叠层与反馈:用
WorkspaceOverlays组织空态/加载态,用EntrySelectionDialog替换内联入口对话框,用DiagnosticNotice替换诊断卡;不改变 loading/diagnostic/entries 的状态来源和加载时序。 - 状态栏与树视觉:实现
StatusBar;为两棵现有树替换 Emoji/字符图标并应用语义令牌,不改buildProjectTree、buildBodyTree或选择/hover 行为。 - 收敛 App:删除已迁移的内联
PanelTitle、EmptyImport、EntryDialog、DiagnosticCard等展示函数;将无状态滑杆展示移入侧栏组件,不改数值换算、范围或 onChange 逻辑。 - 测试与验收:为基础控件、折叠区、Header 回调、Dialog 焦点/Esc、诊断详情和状态栏增加 Testing Library 测试;更新 E2E 图标/折叠定位并跑完整回归。
Verification
- 运行
npm run typecheck:platform --prefix wasm、npm run lint:platform --prefix wasm、npm run test:platform --prefix wasm、npm run build:platform --prefix wasm和npm run test:e2e:platform --prefix wasm,全部通过。 - 新组件测试覆盖:Header 各动作只触发一次;模式按钮
aria-pressed;折叠区默认状态;Dialog Esc/Tab/焦点恢复;诊断详情展开与关闭;Loading/Empty 的互斥显示。 - 用现有 MJCF、URDF、文件夹和 ZIP 路径回归导入及入口切换。
- 回归播放/暂停、单步、重置、速度、关节、actuator、外力、碰撞显示、选择和相机复位。
- 检查 adapter/viewer 初始化与销毁次数,确认 UI 拆分未造成重复会话、重复渲染循环或 WASM 资源泄漏。
- 对照 URDF-Studio 检查布局密度、层级、悬停/选中/禁用态及深浅主题;桌面窄宽度下检查折叠与溢出。
- 对新增弹窗、菜单和提示执行键盘操作、焦点管理和 ARIA 冒烟检查。
Implementation Result
- 已完成 A–H 第一批组件和
lucide-react接入;MuJoCo adapter、viewer、manifest 和业务命令仍由App.tsx持有。 App.tsx已收敛为生命周期/事件编排层;工作台 Header、工具组、侧栏、状态栏、弹窗、诊断和加载/空态均拆为展示组件。- 深浅主题完成语义令牌化,并在 1440×900 下完成暗色、亮色人工截图检查。
- 审查发现并修复:必选入口弹窗重渲染抢焦点、原生输入焦点可见性、模型树 ARIA 层级、侧栏重开折叠状态丢失和侧栏按钮展开状态缺失。
- 验证结果:TypeScript、ESLint、12 个测试文件共 28 个单元/组件测试、5 个 Playwright E2E 和生产构建全部通过。
- 已知非阻塞项:生产构建仍有约 972 KiB 主 JS chunk 警告,与原 MVP 记录的代码分割遗留项一致。
Second Batch Result
ResizablePanel/PanelResizeHandle:支持鼠标拖动、键盘调整、ARIA 数值和本地宽度持久化。TreeSearchField:工程树和模型结构树支持本地过滤,并保留匹配节点的祖先路径。ViewportHUD:复用现有仿真、交互模式和选择状态,在视口内提供轻量状态反馈。ShortcutHelpDialog:Header 帮助入口集中说明现有键盘与鼠标操作。Badge、Tabs、Separator、Skeleton:补齐基础层,并升级模型加载反馈。- 侧栏标签页:左栏拆分“工程 / 模型结构”,右栏拆分“属性 / 控制”;非活动面板保持挂载,保留树和折叠状态。
- 第二批验证:TypeScript、ESLint、14 个测试文件共 36 个测试、生产构建及 5 个 Playwright E2E 全部通过;完成加载模型和快捷键弹窗的人工截图检查。
- 审查修复:Tabs roving tabindex/方向键导航、侧栏宽度边界与指针取消清理、Dialog 打开时快捷键隔离、搜索结果目录锁定展开,以及重编译失败快照清理和新 Session 速度恢复。
Third Batch Result
ConfirmDialog:统一替换移除工程的原生确认框。CommandPalette:支持 Header 入口、Ctrl+K、搜索、方向键和 Enter,复用现有仿真/视口/布局动作。PerformancePopover:从状态栏查看 FPS、物理步进、内存与预算状态。Kbd、PropertyRow、CopyButton:统一快捷键和属性展示,并支持复制已有选择信息。TreeSearchSummary、SearchHighlight、EmptySearchState:显示匹配数量、高亮命中并统一无结果反馈。ViewportFullscreenToggle:支持浏览器全屏进入、退出及状态同步。- 第三批验证:TypeScript、ESLint、16 个测试文件共 42 个测试、生产构建及 5 个 Playwright E2E 全部通过;完成命令面板和完整工作台截图检查。
- 审查修复:全屏元素内 Dialog Portal、Popover 与命令面板互斥关闭、树搜索计数同源、Clipboard API 降级,以及命令面板 combobox/listbox 活动项关联。
Fourth Batch Result
-
ToastViewport/NotificationCenter:模型加载成功、兼容提示和编译失败进入会话通知队列,并提供即时 Toast。 -
LayoutSettingsDialog:统一左右栏显示、宽度重置和默认/宽视口/工程浏览/控制调试预设。 -
ProjectBreadcrumb/EntrySwitcher:展示工程入口路径,并可在多入口工程中直接切换。 -
VirtualTreeViewport:大型工程文件树及 Body/Joint 树超过阈值时启用窗口化渲染。 -
SettingsDialog:集中管理主题、角度单位、碰撞几何、关节高级信息和外力强度。 -
Header 接入通知、布局和设置入口;1024px 产品边界下隐藏品牌长标题以避免工具区重叠。
-
第四批验证:TypeScript、ESLint、18 个测试文件共 49 个测试、生产构建及 5 个 Playwright E2E 全部通过。
-
审查修复:入口切换加载锁与禁用态、1024px Header 轨道约束及 E2E 边界检查、虚拟树 roving active descendant/方向键导航和层级展开折叠。
Fifth Batch Result
-
ToolbarOverflowMenu:1024px 工具区通过“更多”菜单承载命令、布局、设置、全屏、帮助与主题动作。 -
通用
Popover/DropdownMenu:统一外部点击、Escape、焦点恢复及菜单方向键行为,并重构性能和通知弹层。 -
ImportProgressPanel/ProgressBar:在不改变转换逻辑的前提下显示读取、资源处理、WASM/编译和视口创建阶段。 -
DiagnosticsDrawer/ EventLog:按全部、警告和错误分类查看、复制及清空会话事件。 -
SearchableCombobox:多入口工程支持路径搜索和键盘选择。 -
ErrorRecoveryPanel:诊断反馈提供重试入口、复制详情和返回工程树动作。 -
LiveRegion:统一 Toast、加载阶段和诊断变化的辅助技术播报。 -
第五批验证:TypeScript、ESLint、20 个测试文件共 56 个测试和生产构建通过;Playwright E2E 完整回归覆盖更多菜单、事件日志与错误恢复。
-
审查修复:拖放文件收集与导入共享互斥锁、仅模型编译错误允许重试、菜单首项聚焦及触发器恢复、Combobox 完整状态与 Tab 关闭、事件日志按活动标签惰性挂载、Toast 单一 live region。
-
信息归并:从“模型与控制”侧栏移除
URDF 兼容处理分区,完整兼容处理明细仅保留在通知中心与事件日志。
Confirmed Decisions
- 第一批 A–H 全部纳入。
- 只采用 URDF-Studio 的专业工作台风格,保留 MuJoCo 品牌、中文界面和当前左右栏布局。
- 允许引入
lucide-react,不引入@floating-ui/react。 - select/joint/force 工具组停靠在 Header 中央。
- 右侧默认展开模型信息、当前选择和关节;其他低频分区折叠,警告出现时自动展开。
- 第一批不新增编辑、导出、快照、AI、测量、绘制、撤销/重做等产品能力。
- 后续任何超出 A–H 的新组件都需再次向用户确认。