v0.2.0: 全面代码质量优化

- ESLint flat config + Prettier + EditorConfig
- Markdown处理器LRU缓存
- Zustand选择器优化减少重渲染
- CodeMirror Compartment主题热切换
- Preview防抖(150ms) + IndexedDB去抖(500ms)
- 组件拆分: App.tsx 310→104行, Sidebar.tsx 244→90行
- 统一错误处理 errorHandler.ts
- ConfirmDialog替代原生confirm
- LoadingSpinner加载状态
- Toast多条堆叠+类型区分
- 可访问性增强(ARIA属性、键盘导航)
- Vitest测试框架(78个测试用例)
- Git hooks(husky + lint-staged)
- 项目文档(README.md, CONTRIBUTING.md)
This commit is contained in:
thzxx
2026-06-03 22:13:32 +08:00
parent 3cecb0f9eb
commit 7a4e2b0a67
72 changed files with 5103 additions and 894 deletions
@@ -1,18 +1,34 @@
import React from 'react'
import { useTabStore } from '../../stores/tabStore'
import { useEditorStore } from '../../stores/editorStore'
import { getFileName } from '../../lib/fileUtils'
import { LoadingSpinner } from '../LoadingSpinner/LoadingSpinner'
export function StatusBar() {
// B-04: 直接选择数据而非函数引用,确保响应式更新
const tabs = useTabStore(s => s.tabs)
const activeTabId = useTabStore(s => s.activeTabId)
const tab = tabs.find(t => t.id === activeTabId) ?? null
export const StatusBar = React.memo(function StatusBar() {
const activeTab = useTabStore(s => s.getActiveTab())
const loadingStates = useEditorStore(s => s.loadingStates)
// 判断是否有任何加载状态激活
const hasLoading = Object.values(loadingStates).some(Boolean)
const loadingLabel = loadingStates['file-open']
? '正在打开文件...'
: loadingStates['dir-load']
? '正在加载目录...'
: loadingStates['markdown-render']
? '正在渲染...'
: ''
return (
<div id="statusbar" role="status" aria-live="polite">
<div className="status-left">
{hasLoading && (
<span className="status-loading" aria-busy="true">
<LoadingSpinner size="small" />
<span>{loadingLabel}</span>
</span>
)}
<span id="status-text">
{tab ? (tab.filePath ? getFileName(tab.filePath) : '未命名') : '就绪'}
{activeTab ? (activeTab.filePath ? getFileName(activeTab.filePath) : '未命名') : '就绪'}
</span>
</div>
<div className="status-right">
@@ -22,6 +38,6 @@ export function StatusBar() {
</div>
</div>
)
}
})
StatusBar.displayName = 'StatusBar'
StatusBar.displayName = 'StatusBar'