# Quickstart: 统一左侧工具栏容器 **Feature**: 001-unified-toolbar | **Date**: 2025-12-01 ## 开发前准备 ### 1. 环境要求 ```bash # Node.js 18+ (项目要求) node --version # 应该显示 v18.x 或更高 # 检查依赖 npm install # 验证TypeScript编译 nx typecheck drawnix ``` ### 2. 理解现有架构 **阅读以下文件** (约15分钟): ```bash # 现有工具栏实现 packages/drawnix/src/components/toolbar/app-toolbar/app-toolbar.tsx packages/drawnix/src/components/toolbar/creation-toolbar.tsx packages/drawnix/src/components/toolbar/zoom-toolbar.tsx packages/drawnix/src/components/toolbar/theme-toolbar.tsx # 主应用入口 packages/drawnix/src/drawnix.tsx # 现有样式 packages/drawnix/src/styles/index.scss # 查找 .app-toolbar, .draw-toolbar等 ``` **关键点**: - 四个工具栏当前使用绝对定位(`position: absolute`) - 移动端通过 `@include isMobile` mixin应用不同样式 - 所有工具栏使用 `Island` 组件包裹 - 工具栏组件通过 `DrawnixContext` 访问 board 和 appState --- ## 开发流程 ### Phase 1: 创建UnifiedToolbar组件骨架 (30分钟) #### 1.1 创建组件文件 ```bash # 在正确的目录创建文件 touch packages/drawnix/src/components/toolbar/unified-toolbar.tsx ``` **unified-toolbar.tsx** 初始结构: ```typescript import React, { useState, useCallback, useEffect, useRef } from 'react'; import classNames from 'classnames'; import { ATTACHED_ELEMENT_CLASS_NAME } from '@plait/core'; import { Island } from '../island'; import { AppToolbar } from './app-toolbar/app-toolbar'; import { CreationToolbar } from './creation-toolbar'; import { ZoomToolbar } from './zoom-toolbar'; import { ThemeToolbar } from './theme-toolbar'; interface UnifiedToolbarProps { className?: string; } export const UnifiedToolbar: React.FC = ({ className }) => { const [isIconMode, setIsIconMode] = useState(false); const containerRef = useRef(null); // TODO: 添加ResizeObserver监听高度变化 return (
{/* TODO: 添加工具栏分区 */}
); }; ``` #### 1.2 添加基础样式 在 `packages/drawnix/src/styles/index.scss` 添加: ```scss .unified-toolbar { position: absolute; left: 36px; top: 36px; display: flex; flex-direction: column; gap: 0; // 分割线通过border实现,不需要gap // 仅桌面端显示 @include isMobile { display: none; } &__section { &:not(:first-child) { border-top: 1px solid var(--color-border); padding-top: 8px; } } &--icon-only { // 图标模式修饰符,后续添加子元素样式 } } ``` --- ### Phase 2: 修改现有工具栏组件 (45分钟) #### 2.1 添加embedded prop支持 以 `AppToolbar` 为例: ```typescript // app-toolbar.tsx interface AppToolbarProps { embedded?: boolean; // [NEW] 是否嵌入统一容器 iconMode?: boolean; // [NEW] 是否图标模式 } export const AppToolbar: React.FC = ({ embedded = false, iconMode = false }) => { // ...现有逻辑 return ( {/* 现有工具栏内容保持不变 */} ); }; ``` **重复以上修改** 对所有4个工具栏组件: - `creation-toolbar.tsx` - `zoom-toolbar.tsx` - `theme-toolbar.tsx` #### 2.2 更新样式禁用独立定位 ```scss // index.scss .app-toolbar { position: absolute; top: 36px; left: 36px; // [NEW] 嵌入模式禁用定位 &--embedded { position: static; top: auto; left: auto; } @include isMobile { // 移动端样式保持不变 } } // 对 .draw-toolbar, .zoom-toolbar, .theme-toolbar 重复相同模式 ``` --- ### Phase 3: 集成到主应用 (20分钟) #### 3.1 修改drawnix.tsx ```typescript // drawnix.tsx import { UnifiedToolbar } from './components/toolbar/unified-toolbar'; // 在渲染部分替换工具栏 {/* [MODIFIED] 桌面端使用统一工具栏,移动端保持不变 */} {!appState.isMobile ? ( ) : ( <> )} {/* 其他组件保持不变 */} {/* ... */} ``` --- ### Phase 4: 实现响应式图标模式 (40分钟) #### 4.1 添加ResizeObserver 在 `unified-toolbar.tsx`: ```typescript // 计算阈值 const TOOLBAR_MIN_HEIGHT = 460; // 基于四个分区最小高度 useEffect(() => { const container = containerRef.current; if (!container) return; const observer = new ResizeObserver((entries) => { const height = entries[0].contentRect.height; setIsIconMode(height < TOOLBAR_MIN_HEIGHT); }); observer.observe(container); return () => observer.disconnect(); }, []); ``` #### 4.2 传递iconMode prop ```typescript return (
); ``` #### 4.3 添加图标模式样式 ```scss .tool-button__label { display: inline-block; margin-left: 8px; transition: opacity 0.2s ease-out; // 图标模式隐藏文本 .app-toolbar--icon-only &, .draw-toolbar--icon-only &, .zoom-toolbar--icon-only &, .theme-toolbar--icon-only & { display: none; } } ``` --- ### Phase 5: 测试 (30分钟) #### 5.1 手动测试清单 ```bash # 启动开发服务器 npm start ``` **桌面端测试** (打开 http://localhost:7200): - [ ] 工具栏是否在左侧垂直排列? - [ ] 四个分区之间是否有1px分割线? - [ ] 缩小浏览器高度,工具栏是否切换到图标模式? - [ ] 恢复高度,是否恢复正常模式? - [ ] 所有工具按钮是否仍然可点击? - [ ] 撤销/重做快捷键(Cmd+Z/Cmd+Shift+Z)是否有效? **移动端测试** (Chrome DevTools切换到移动设备): - [ ] 工具栏是否保持原有位置(应用工具在底部,创作工具在顶部)? - [ ] 布局是否与改动前完全一致? #### 5.2 编写组件测试 ```typescript // packages/drawnix/tests/components/toolbar/unified-toolbar.test.tsx import { render } from '@testing-library/react'; import { UnifiedToolbar } from '../../../src/components/toolbar/unified-toolbar'; describe('UnifiedToolbar', () => { it('should render all four toolbar sections', () => { const { container } = render(); expect(container.querySelector('.app-toolbar')).toBeInTheDocument(); expect(container.querySelector('.draw-toolbar')).toBeInTheDocument(); expect(container.querySelector('.zoom-toolbar')).toBeInTheDocument(); expect(container.querySelector('.theme-toolbar')).toBeInTheDocument(); }); it('should have vertical layout', () => { const { container } = render(); const toolbar = container.querySelector('.unified-toolbar'); expect(toolbar).toHaveStyle({ flexDirection: 'column' }); }); // TODO: 添加响应式测试 }); ``` 运行测试: ```bash nx test drawnix ``` --- ## 常见问题排查 ### 问题1: 工具栏不显示 **检查**: - [ ] 是否在桌面端?(移动端不显示UnifiedToolbar) - [ ] CSS文件是否正确导入? - [ ] 是否存在样式冲突? **Debug**: ```javascript // 在drawnix.tsx添加日志 console.log('isMobile:', appState.isMobile); ``` ### 问题2: 工具栏位置不对 **检查**: - [ ] `.unified-toolbar` 是否有 `position: absolute`? - [ ] `left: 36px; top: 36px;` 是否正确应用? - [ ] 是否有其他样式覆盖了定位? ### 问题3: 图标模式不工作 **检查**: - [ ] ResizeObserver是否成功创建? - [ ] isIconMode状态是否正确更新? - [ ] iconMode prop是否传递给子组件? **Debug**: ```javascript // 在unified-toolbar.tsx添加日志 console.log('Container height:', height, 'Icon mode:', isIconMode); ``` ### 问题4: 移动端布局被破坏 **检查**: - [ ] 条件渲染逻辑是否正确?(`!appState.isMobile`) - [ ] 移动端样式是否仍然应用?(`@include isMobile`) - [ ] 是否意外修改了移动端特有的样式? --- ## 性能优化检查 运行完成后验证: ```bash # TypeScript类型检查 nx typecheck drawnix # Lint检查 nx lint drawnix # 构建检查 nx build drawnix ``` **性能基准** (Chrome DevTools Performance tab): - [ ] 工具栏首次渲染 < 16ms - [ ] 响应式切换延迟 < 100ms - [ ] 无Layout Shift警告 --- ## 提交前清单 - [ ] 所有文件 < 500行 - [ ] TypeScript严格模式通过 - [ ] ESLint无错误 - [ ] 所有测试通过 - [ ] 手动测试通过(桌面 + 移动) - [ ] 无console.log残留 - [ ] Git commit message符合规范: ``` feat(toolbar): 实现统一左侧工具栏容器 - 创建UnifiedToolbar组件整合四个工具栏 - 添加1px水平分割线分隔分区 - 实现响应式图标模式 - 保持移动端布局不变 - 所有功能和快捷键正常工作 Closes #[issue-number] ``` --- ## 下一步 实现完成后: 1. 运行完整测试套件: `nx test drawnix && nx e2e web` 2. 创建Pull Request 3. 请求代码审查 4. 部署到预发布环境验证 --- ## 参考文档 - [宪章](/.specify/memory/constitution.md) - 编码标准和约束 - [CLAUDE.md](/CLAUDE.md) - 项目架构概览 - [技术规范](./spec.md) - 功能需求 - [研究文档](./research.md) - 技术决策 - [数据模型](./data-model.md) - 类型定义 预计总开发时间: **3-4小时** (包括测试)