Files
Genarrative/apps/ai-game-creator-shell/src/app/dialogs.ts
T
AIGameCreator App be89296492 拆分 AI 游戏创作客户端大型模块
拆分 App 认证、壳层、运行配置与项目摘要模块
拆分 Tauri 项目能力与 Rust 测试领域模块
拆分界面测试与 Agent Runtime 真实 E2E 套件
补充源码扫描和客户端模块化文档约定
2026-07-21 22:53:29 +08:00

56 lines
1.3 KiB
TypeScript

import {
type KeyboardEvent as ReactKeyboardEvent,
type MouseEvent as ReactMouseEvent,
useLayoutEffect,
} from 'react';
function isEscapeKey(event: { key: string }) {
return event.key === 'Escape';
}
function isEditableEscapeTarget(target: EventTarget | null) {
return (
target instanceof HTMLInputElement ||
target instanceof HTMLTextAreaElement ||
target instanceof HTMLSelectElement ||
(target instanceof HTMLElement && target.isContentEditable)
);
}
export function closeDialogOnEscape(
event: ReactKeyboardEvent,
onClose: () => void,
) {
if (isEscapeKey(event) && !isEditableEscapeTarget(event.target)) {
event.preventDefault();
onClose();
}
}
export function useEscapeToClose(onClose: () => void, enabled = true) {
useLayoutEffect(() => {
if (!enabled) {
return;
}
const handleKeyDown = (event: globalThis.KeyboardEvent) => {
if (isEscapeKey(event) && !isEditableEscapeTarget(event.target)) {
event.preventDefault();
onClose();
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [enabled, onClose]);
}
export function closeDialogOnBackdropMouseDown(
event: ReactMouseEvent,
onClose: () => void,
) {
if (event.target === event.currentTarget) {
onClose();
}
}