/* ============================================================================= * A00_Common/design/design_pick_escape.ts * 풀기 한 길 — Esc = 고름 한 칸 비움 (233-3 · 조사 AF (나)). * * 값을 비우면 구독한 화면이 모두 따라 풂 — 종단(측점선 · 알약) · 3D(띠 · 핀 · 부재) · 배수유역도 · * 좌측 폼 · 횡단 카드 · 범위 테두리 · 포장층 · 형상. 입력 칸 · 창(모달) · 메뉴 · 종단 도구가 먼저 * 받은 Esc(입력 취소 · 창 닫기 · 도구 끝)는 그쪽 몫이라 건드리지 않음. * ========================================================================== */ import { NO_SELECTION, selectDesign } from "./design_selection"; /** Esc 로 푼 고름의 출처 이름 — 구독자가 폼까지 닫을지 가르는 데 씀. */ export const ESCAPE_FROM = "esc"; const OWN_ESCAPE = "input, select, textarea, [contenteditable='true'], [role='dialog'], .ui-modal__backdrop"; /** 보기마다 건다 — 보이는 보기 하나만 받음 · 보기를 떠나면 뗌. */ export function bindEscapeRelease( projectId: string | null, host: { visible: () => boolean; onDispose: (fn: () => void) => void }, ): void { const onKey = (event: KeyboardEvent): void => { if (event.key !== "Escape" || event.defaultPrevented || !host.visible()) return; const target = event.target as HTMLElement | null; if (target?.closest?.(OWN_ESCAPE) || document.querySelector(".ui-modal__backdrop")) return; selectDesign(projectId, NO_SELECTION, { from: ESCAPE_FROM }); }; window.addEventListener("keydown", onKey); host.onDispose(() => window.removeEventListener("keydown", onKey)); }