feat: 重新设计现代化图标系统
新增 Icons.tsx 统一图标组件(25 个图标): - AppIcon: 渐变蓝色圆角矩形 + M↓ 符号 - 工具栏: FolderOpen, Save, SplitView, EditMode, PreviewMode, Moon, Sun - 标签栏: Close, Plus - 侧边栏: Folder, File, ChevronRight, FolderPlus - 搜索栏: ChevronUp, ChevronDown, X - 拖拽: UploadCloud - 导航: ArrowUp, ArrowDown - 欢迎: WelcomeFile, WelcomeNew 设计风格: - 线性图标(stroke-based),统一 1.75px 线宽 - 圆角风格,现代科技感 - 蓝色主色调渐变应用图标 - 部分图标添加微妙的填充细节(opacity 0.3-0.4) 更新组件: - Toolbar: 使用 FolderOpen/Save/SplitView/EditMode/PreviewMode/Moon/Sun - TabBar: 使用 Close/Plus - Sidebar: 使用 FolderPlus/File/Folder/ChevronRight - SearchBar: 使用 ChevronUp/ChevronDown/X - WelcomeScreen: 使用 AppIcon/WelcomeFile/WelcomeNew - DropOverlay: 使用 UploadCloud
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import React, { useCallback, useState, useEffect, useRef } from 'react'
|
||||
import { useTabStore } from '../../stores/tabStore'
|
||||
import { getFileName } from '../../lib/fileUtils'
|
||||
import { Close, Plus } from '../Icons'
|
||||
|
||||
interface ContextMenuState {
|
||||
visible: boolean
|
||||
@@ -22,7 +23,6 @@ export function TabBar() {
|
||||
const [menu, setMenu] = useState<ContextMenuState>({ visible: false, x: 0, y: 0, tabId: '' })
|
||||
const menuRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
// 关闭标签(带未保存确认)
|
||||
const handleClose = useCallback((e: React.MouseEvent, tabId: string) => {
|
||||
e.stopPropagation()
|
||||
const tab = tabs.find(t => t.id === tabId)
|
||||
@@ -44,7 +44,6 @@ export function TabBar() {
|
||||
setMenu({ visible: true, x: Math.max(0, x), y: Math.max(0, y), tabId })
|
||||
}, [])
|
||||
|
||||
// 点击空白处关闭菜单
|
||||
useEffect(() => {
|
||||
if (!menu.visible) return
|
||||
const handleClick = () => setMenu(prev => ({ ...prev, visible: false }))
|
||||
@@ -52,7 +51,6 @@ export function TabBar() {
|
||||
return () => document.removeEventListener('click', handleClick)
|
||||
}, [menu.visible])
|
||||
|
||||
// 菜单操作
|
||||
const handleMenuClose = useCallback(() => {
|
||||
const tab = tabs.find(t => t.id === menu.tabId)
|
||||
if (tab?.isModified) {
|
||||
@@ -64,7 +62,6 @@ export function TabBar() {
|
||||
}, [tabs, menu.tabId, closeTab])
|
||||
|
||||
const handleMenuCloseOthers = useCallback(() => {
|
||||
// 检查其他标签是否有未保存
|
||||
const otherModified = tabs.filter(t => t.id !== menu.tabId && t.isModified)
|
||||
if (otherModified.length > 0) {
|
||||
const names = otherModified.map(t => t.filePath ? getFileName(t.filePath) : '未命名').join('、')
|
||||
@@ -96,7 +93,6 @@ export function TabBar() {
|
||||
setMenu(prev => ({ ...prev, visible: false }))
|
||||
}, [tabs, menu.tabId, closeTabsToRight])
|
||||
|
||||
// 判断右侧是否还有标签
|
||||
const hasRightTabs = menu.visible && (() => {
|
||||
const index = tabs.findIndex(t => t.id === menu.tabId)
|
||||
return index < tabs.length - 1
|
||||
@@ -121,10 +117,7 @@ export function TabBar() {
|
||||
className="tab-close"
|
||||
onClick={(e) => handleClose(e, tab.id)}
|
||||
>
|
||||
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<line x1="18" y1="6" x2="6" y2="18" />
|
||||
<line x1="6" y1="6" x2="18" y2="18" />
|
||||
</svg>
|
||||
<Close size={10} />
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
@@ -134,10 +127,7 @@ export function TabBar() {
|
||||
onClick={() => createTab(null, '')}
|
||||
title="新建标签页 (Ctrl+T)"
|
||||
>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<line x1="12" y1="5" x2="12" y2="19" />
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
</svg>
|
||||
<Plus size={14} />
|
||||
</button>
|
||||
|
||||
{/* 右键菜单 */}
|
||||
@@ -151,7 +141,6 @@ export function TabBar() {
|
||||
<div className="tab-context-item" onClick={handleMenuClose}>
|
||||
关闭
|
||||
</div>
|
||||
{/* M-03: 单标签时隐藏"关闭其他标签" */}
|
||||
{tabs.length > 1 && (
|
||||
<div className="tab-context-item" onClick={handleMenuCloseOthers}>
|
||||
关闭其他标签
|
||||
|
||||
Reference in New Issue
Block a user