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:
thzxx
2026-05-27 21:44:26 +08:00
parent 70dff0cf01
commit db94ecfad0
7 changed files with 283 additions and 108 deletions
@@ -2,6 +2,7 @@ import React, { useCallback, useRef, useEffect } from 'react'
import { useSearchStore } from '../../stores/searchStore'
import { useTabStore } from '../../stores/tabStore'
import { findMatches } from '../../lib/searchEngine'
import { ChevronUp, ChevronDown, X } from '../Icons'
export function SearchBar() {
const searchInputRef = useRef<HTMLInputElement>(null)
@@ -25,7 +26,6 @@ export function SearchBar() {
const getActiveTab = useTabStore(s => s.getActiveTab)
// 执行搜索
const doSearch = useCallback((text: string) => {
const tab = getActiveTab()
if (!tab || !text) {
@@ -36,21 +36,18 @@ export function SearchBar() {
setMatches(found)
}, [getActiveTab, options, setMatches])
// 搜索文本变化
const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
const text = e.target.value
setSearchText(text)
doSearch(text)
}, [setSearchText, doSearch])
// 替换当前
const handleReplaceCurrent = useCallback(() => {
const tab = getActiveTab()
if (!tab || matches.length === 0 || currentIndex < 0) return
const m = matches[currentIndex]
const newContent = tab.content.substring(0, m.start) + replaceText + tab.content.substring(m.end)
useTabStore.getState().updateTabContent(tab.id, newContent)
// 重新搜索
doSearch(searchText)
}, [getActiveTab, matches, currentIndex, replaceText, searchText, doSearch])
@@ -67,7 +64,6 @@ export function SearchBar() {
doSearch(searchText)
}, [getActiveTab, matches, replaceText, searchText, doSearch])
// 打开时聚焦
useEffect(() => {
if (isVisible && searchInputRef.current) {
searchInputRef.current.focus()
@@ -123,16 +119,14 @@ export function SearchBar() {
.*
</button>
<button className="search-nav-btn" onClick={findPrev} title="上一个 (Shift+Enter)">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
<polyline points="18 15 12 9 6 15" />
</svg>
<ChevronUp size={12} />
</button>
<button className="search-nav-btn" onClick={findNext} title="下一个 (Enter)">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
<polyline points="6 9 12 15 18 9" />
</svg>
<ChevronDown size={12} />
</button>
<button className="search-nav-btn" onClick={close} title="关闭 (Escape)">
<X size={14} />
</button>
<button className="search-nav-btn" onClick={close} title="关闭 (Escape)"></button>
</div>
{showReplace && (