diff --git a/apps/client/utils/keyboardShortcuts.ts b/apps/client/utils/keyboardShortcuts.ts index 66b1920d8..9ef5c1173 100644 --- a/apps/client/utils/keyboardShortcuts.ts +++ b/apps/client/utils/keyboardShortcuts.ts @@ -63,20 +63,31 @@ export function registerShortcut(key: string, command: Shortcut["command"]) { export function cancelShortcut(key: string, command: Shortcut["command"]): void; export function cancelShortcut(shortcut: Shortcut): void; +export function cancelShortcut(key: string): void; export function cancelShortcut(keyOrShortcut: string | Shortcut, command?: Shortcut["command"]) { - function normalizeShortcut() { - let normalShortcut: Shortcut; - if (typeof keyOrShortcut === "string" && command) { - normalShortcut = createShortcut(keyOrShortcut, command); - } else { - normalShortcut = keyOrShortcut as Shortcut; + function normalizeShortcut(): Shortcut | Partial { + if (typeof keyOrShortcut === "object") { + return keyOrShortcut; } - - return normalShortcut; + return command ? createShortcut(keyOrShortcut, command) : parseKey(keyOrShortcut); } let normalShortcut = normalizeShortcut(); + if (typeof keyOrShortcut === "string" && !command) { + // 如果只传了 key,删除所有匹配的快捷键 + for (let i = shortcuts.length - 1; i >= 0; i--) { + if ( + shortcuts[i].key === normalShortcut!.key && + shortcuts[i].ctrlKey === normalShortcut!.ctrlKey && + shortcuts[i].metaKey === normalShortcut!.metaKey + ) { + shortcuts.splice(i, 1); + } + } + return; + } + const index = shortcuts.findIndex(({ key, command, ctrlKey, metaKey }) => { // 精准匹配对应快捷键对象 return ( diff --git a/apps/client/utils/tests/keyboardShortcuts.spec.ts b/apps/client/utils/tests/keyboardShortcuts.spec.ts index dbd75513f..eccf23c71 100644 --- a/apps/client/utils/tests/keyboardShortcuts.spec.ts +++ b/apps/client/utils/tests/keyboardShortcuts.spec.ts @@ -148,6 +148,58 @@ describe("keyboardShortcuts", () => { expect(command).not.toBeCalled(); }); + + it("should remove all commands when only key is provided", () => { + let commandA = vi.fn(); + let commandB = vi.fn(); + registerShortcut("enter", commandA); + registerShortcut("enter", commandB); + + // 只传递 key,删除所有匹配的快捷键 + cancelShortcut("enter"); + + // 触发 + fireEvent.keyDown({ + key: "enter", + }); + + expect(commandA).not.toBeCalled(); + expect(commandB).not.toBeCalled(); + }); + + it("should remove all ctrl when only key is provided", () => { + let commandA = vi.fn(); + let commandB = vi.fn(); + registerShortcut("ctrl+A", commandA); + registerShortcut("ctrl+a", commandB); + + cancelShortcut("ctrl+a"); + + fireEvent.keyDown({ + ctrlKey: true, + key: "a", + }); + + expect(commandA).not.toBeCalled(); + expect(commandB).not.toBeCalled(); + }); + + it("should remove all commands when only key is provided", () => { + let commandA = vi.fn(); + let commandB = vi.fn(); + registerShortcut("command+A", commandA); + registerShortcut("command+a", commandB); + + cancelShortcut("command+a"); + + fireEvent.keyDown({ + metaKey: true, + key: "a", + }); + + expect(commandA).not.toBeCalled(); + expect(commandB).not.toBeCalled(); + }); }); describe("utils function", () => {