/* ============================================================================= * key_shortcut.ts — Ctrl(⌘)+글자 단축키 판정 공용(PLAN 214-2) * 한글 자판은 `key` 가 「ㅋ」·「ㅛ」로 와 글자로는 안 맞음 — 영문 글자·숫자면 그 글자 · * 아니면 자판 자리(`code`: KeyZ · Digit1)로 판정. Shift 의 대문자도 소문자로 맞춤. * 쓰는 곳 — 페이지(B05 · M02 · 시트 키) + CAD(`B07_DesignDetail/openwebcad` 의 `input-shortcut.ts` 가 다시 내보냄). * 시험 = `resources/tester/cad/ctrl-shortcut-hangul.test.ts` * ========================================================================== */ type KeyLike = Pick & Partial>; /** 누른 글자·숫자(소문자) — 글자·숫자 자리가 아니면 빈 글 */ export function keyLetter(evt: KeyLike): string { const key = evt.key ?? ""; if (/^[a-zA-Z0-9]$/.test(key)) return key.toLowerCase(); const m = /^(?:Key([A-Z])|Digit([0-9]))$/.exec(evt.code ?? ""); return m ? (m[1] ?? m[2]).toLowerCase() : ""; } /** Ctrl(Mac ⌘)과 함께 누른 `letter`(소문자 글자·숫자)인가 — Shift · Alt 는 보지 않음 */ export function isCtrlKey( evt: KeyLike & Pick, letter: string, ): boolean { return (evt.ctrlKey || evt.metaKey) && keyLetter(evt) === letter; } /** Ctrl 단축키 이름 */ export type CtrlShortcut = "undo" | "redo" | "save" | "selectAll"; /** 공용 Ctrl 단축키 — Z · Shift+Z · Y · S · A (Alt 함께는 아님 · Shift 는 Z 만) */ export function ctrlShortcut( evt: KeyLike & Pick & Partial>, ): CtrlShortcut | null { if (!(evt.ctrlKey || evt.metaKey) || evt.altKey) return null; switch (keyLetter(evt)) { case "z": return evt.shiftKey ? "redo" : "undo"; case "y": return evt.shiftKey ? null : "redo"; case "s": return evt.shiftKey ? null : "save"; case "a": return evt.shiftKey ? null : "selectAll"; default: return null; } }