Files
Aislo/A00_Common/key_shortcut.ts
T
eomsangdonandClaude Sonnet 5.5 f8fff70d56 fix(단축키): 전역 Ctrl 단축키 한글 자판 대응 · 공용 판정 함수(214-2)
- A00_Common/key_shortcut.ts 새로 — 영문이면 글자 · 아니면 자판 자리(code) · CAD 와 페이지가 같이 씀
- CAD input-shortcut.ts 는 공용을 다시 내보냄 · tsconfig.app.json 에 공용 파일 포함
- B05 종단 Ctrl+Z · 노선 편집 Ctrl+Z · Y · M02 흐름도 Ctrl+Z · 카드 Ctrl+S · 나무 Ctrl+C · V · 시트 Ctrl+글자
- 시트 키는 한글 조합 중에도 Ctrl+글자 판정
- 새 시험 ctrl-shortcut-hangul · ctrl-shortcut-sheet

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STqEqztUthVFBmEP18wBSz
2026-10-10 15:32:58 +09:00

50 lines
2.1 KiB
TypeScript

/* =============================================================================
* 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<KeyboardEvent, "code"> & Partial<Pick<KeyboardEvent, "key">>;
/** 누른 글자·숫자(소문자) — 글자·숫자 자리가 아니면 빈 글 */
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<KeyboardEvent, "ctrlKey" | "metaKey">,
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<KeyboardEvent, "ctrlKey" | "altKey" | "shiftKey"> &
Partial<Pick<KeyboardEvent, "metaKey">>,
): 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;
}
}