mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-25 13:45:03 +08:00
feat: 添加 ESC 键快捷返回功能 (#670)
* feat: 添加 ESC 键快捷返回功能 - FullScreenPanel 组件支持 ESC 键关闭 - App.tsx 主页面支持 ESC 键返回主界面 - 优化键盘事件处理,合并多个监听器 - 使用事件捕获阶段避免冲突 - 适用于所有子页面:MCP、设置、Prompts、Skills 等 - 跨平台兼容:macOS、Windows、Linux * perf: 优化 ESC 键处理逻辑 - 使用 useRef 避免闭包陷阱,提升性能 - 修复输入框中按 ESC 会关闭面板的问题 - 检测焦点元素,不干扰输入框的 ESC 行为 - 改进用户体验,避免意外关闭导致数据丢失 * fix: enhance global keyboard shortcuts and improve useModelState sync - App & FullScreenPanel: Use `isTextEditableTarget` to prevent shortcuts (ESC, etc.) from triggering while editing text. - useModelState: Prevent overwriting user input during config synchronization. - App: Add `Cmd/Ctrl + ,` shortcut to open settings. - Add `isTextEditableTarget` utility.
This commit is contained in:
@@ -4,6 +4,7 @@ import { motion, AnimatePresence } from "framer-motion";
|
||||
import { ArrowLeft } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { isWindows, isLinux } from "@/lib/platform";
|
||||
import { isTextEditableTarget } from "@/utils/domUtils";
|
||||
|
||||
interface FullScreenPanelProps {
|
||||
isOpen: boolean;
|
||||
@@ -37,6 +38,39 @@ export const FullScreenPanel: React.FC<FullScreenPanelProps> = ({
|
||||
};
|
||||
}, [isOpen]);
|
||||
|
||||
// ESC 键关闭面板
|
||||
const onCloseRef = React.useRef(onClose);
|
||||
|
||||
React.useEffect(() => {
|
||||
onCloseRef.current = onClose;
|
||||
}, [onClose]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!isOpen) return;
|
||||
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === "Escape") {
|
||||
// 子组件(例如 Radix 的 Select/Dialog/Dropdown)如果已经消费了 ESC,就不要再关闭整个面板
|
||||
if (event.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isTextEditableTarget(event.target)) {
|
||||
return; // 让输入框自己处理 ESC(比如清空、失焦等)
|
||||
}
|
||||
|
||||
event.stopPropagation(); // 阻止事件继续冒泡到 window,避免触发 App.tsx 的全局监听
|
||||
onCloseRef.current();
|
||||
}
|
||||
};
|
||||
|
||||
// 使用冒泡阶段监听,让子组件(如 Radix UI)优先处理 ESC
|
||||
window.addEventListener("keydown", handleKeyDown, false);
|
||||
return () => {
|
||||
window.removeEventListener("keydown", handleKeyDown, false);
|
||||
};
|
||||
}, [isOpen]);
|
||||
|
||||
return createPortal(
|
||||
<AnimatePresence>
|
||||
{isOpen && (
|
||||
|
||||
Reference in New Issue
Block a user