From f859ffe4cdb96b755da5888453ac1ab35f23879e Mon Sep 17 00:00:00 2001 From: gaoziman <2942894660@qq.com> Date: Sat, 27 Dec 2025 23:56:19 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E7=BB=84=E4=BB=B6):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=BF=AB=E6=8D=B7=E9=94=AE=E5=B8=AE=E5=8A=A9=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现快捷键帮助弹窗界面 - 按分类(导航、编辑、通用)分组显示 - 支持 Mac/Windows 快捷键格式切换 - 预置常用快捷键说明 - 按 Esc 关闭面板 --- src/components/ui/HotkeysHelper.tsx | 207 ++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 src/components/ui/HotkeysHelper.tsx diff --git a/src/components/ui/HotkeysHelper.tsx b/src/components/ui/HotkeysHelper.tsx new file mode 100644 index 0000000..9e960b2 --- /dev/null +++ b/src/components/ui/HotkeysHelper.tsx @@ -0,0 +1,207 @@ +'use client'; + +import { useEffect, useState, useMemo } from 'react'; +import { X, Keyboard } from 'lucide-react'; +import { cn } from '@/lib/utils'; +import type { RegisteredHotkey, HotkeyCategory } from '@/types/hotkeys'; +import { formatHotkey } from '@/types/hotkeys'; + +interface HotkeysHelperProps { + isOpen: boolean; + onClose: () => void; + registeredHotkeys?: RegisteredHotkey[]; +} + +// 预定义的快捷键列表(包括系统内置的) +const BUILTIN_HOTKEYS: RegisteredHotkey[] = [ + { + id: 'new-chat', + config: { + key: 'n', + description: '新建对话', + category: '导航', + action: () => {}, + }, + }, + { + id: 'open-search', + config: { + key: 'k', + modifiers: ['meta'], + description: '打开搜索', + category: '导航', + action: () => {}, + }, + }, + { + id: 'help', + config: { + key: '?', + description: '显示快捷键帮助', + category: '通用', + action: () => {}, + }, + }, + { + id: 'close-modal', + config: { + key: 'Escape', + description: '关闭弹窗', + category: '通用', + action: () => {}, + }, + }, +]; + +/** + * 快捷键帮助面板 + */ +export function HotkeysHelper({ isOpen, onClose, registeredHotkeys = [] }: HotkeysHelperProps) { + // 检测是否为 Mac 系统 + const [isMac, setIsMac] = useState(true); + + useEffect(() => { + setIsMac(navigator.platform.toLowerCase().includes('mac')); + }, []); + + // 合并内置和动态快捷键,按分类分组 + const groupedHotkeys = useMemo(() => { + const allHotkeys = [...BUILTIN_HOTKEYS, ...registeredHotkeys]; + + // 去重(以 id 为准,优先保留 BUILTIN) + const uniqueHotkeys = allHotkeys.reduce((acc, hotkey) => { + if (!acc.find((h) => h.id === hotkey.id)) { + acc.push(hotkey); + } + return acc; + }, [] as RegisteredHotkey[]); + + // 按分类分组 + const groups: Record = { + 导航: [], + 编辑: [], + 通用: [], + }; + + uniqueHotkeys.forEach((hotkey) => { + const category = hotkey.config.category || '通用'; + if (groups[category]) { + groups[category].push(hotkey); + } else { + groups['通用'].push(hotkey); + } + }); + + // 过滤空分类 + return Object.entries(groups).filter(([, items]) => items.length > 0); + }, [registeredHotkeys]); + + if (!isOpen) return null; + + return ( + <> + {/* 遮罩层 */} +
+ + {/* 帮助面板 */} +
+
+ {/* 头部 */} +
+
+
+ +
+
+

+ 键盘快捷键 +

+

+ 使用快捷键提高效率 +

+
+
+ +
+ + {/* 快捷键列表 */} +
+ {groupedHotkeys.map(([category, hotkeys], groupIndex) => ( +
0 && 'mt-6')} + > + {/* 分类标题 */} +

+ {category} +

+ + {/* 快捷键项 */} +
+ {hotkeys.map((hotkey) => ( +
+ + {hotkey.config.description} + + +
+ ))} +
+
+ ))} +
+ + {/* 底部提示 */} +
+
+ Esc 关闭 + {isMac ? 'macOS' : 'Windows/Linux'} +
+
+
+
+ + ); +} + +/** + * 快捷键徽章组件 + */ +function HotkeyBadge({ + config, + isMac, +}: { + config: RegisteredHotkey['config']; + isMac: boolean; +}) { + const keys = formatHotkey(config, isMac).split(isMac ? ' ' : '+'); + + return ( +
+ {keys.map((key, index) => ( + + {key} + + ))} +
+ ); +}