From 5abc73fabcc8dff3c391740280ac5ba47f07749a Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sat, 15 Jan 2022 17:47:53 -0800 Subject: [PATCH] fix: Editor shortcut conflicts (#2943) * fix: ctrl+n shortcut conflicts * Update kbar with fix for ctrl-k on macOS --- app/components/RegisterKeyDown.ts | 7 +++--- app/hooks/useKeyDown.ts | 38 +++++++++++++++++++++++-------- package.json | 2 +- yarn.lock | 8 +++---- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/app/components/RegisterKeyDown.ts b/app/components/RegisterKeyDown.ts index 197616e84..a01c5c2f5 100644 --- a/app/components/RegisterKeyDown.ts +++ b/app/components/RegisterKeyDown.ts @@ -1,8 +1,9 @@ -import useKeyDown, { KeyFilter } from "~/hooks/useKeyDown"; +import useKeyDown, { KeyFilter, Options } from "~/hooks/useKeyDown"; type Props = { trigger: KeyFilter; handler: (event: KeyboardEvent) => void; + options?: Options; }; /** @@ -10,7 +11,7 @@ type Props = { * class components that have not yet been converted to functions. Do not use * this method in functional components. */ -export default function RegisterKeyDown({ trigger, handler }: Props) { - useKeyDown(trigger, handler); +export default function RegisterKeyDown({ trigger, handler, options }: Props) { + useKeyDown(trigger, handler, options); return null; } diff --git a/app/hooks/useKeyDown.ts b/app/hooks/useKeyDown.ts index ea07bdd88..c66e9e7e9 100644 --- a/app/hooks/useKeyDown.ts +++ b/app/hooks/useKeyDown.ts @@ -1,12 +1,22 @@ import * as React from "react"; import isTextInput from "~/utils/isTextInput"; - -export type KeyFilter = ((event: KeyboardEvent) => boolean) | string; +import { isModKey } from "~/utils/keyboard"; type Callback = (event: KeyboardEvent) => void; +export type KeyFilter = ((event: KeyboardEvent) => boolean) | string; + +export type Options = { + allowInInput?: boolean; +}; + +type RegisteredCallback = { + callback: Callback; + options?: Options; +}; + // Registered keyboard event callbacks -let callbacks: Callback[] = []; +let callbacks: RegisteredCallback[] = []; // Track if IME input suggestions are open so we can ignore keydown shortcuts // in this case, they should never be triggered from mobile keyboards. @@ -25,7 +35,11 @@ const createKeyPredicate = (keyFilter: KeyFilter) => ? (_event: KeyboardEvent) => true : (_event: KeyboardEvent) => false; -export default function useKeyDown(key: KeyFilter, fn: Callback): void { +export default function useKeyDown( + key: KeyFilter, + fn: Callback, + options?: Options +): void { const predicate = createKeyPredicate(key); React.useEffect(() => { @@ -35,9 +49,13 @@ export default function useKeyDown(key: KeyFilter, fn: Callback): void { } }; - callbacks.push(handler); + callbacks.push({ + callback: handler, + options, + }); + return () => { - callbacks = callbacks.filter((cb) => cb !== handler); + callbacks = callbacks.filter((cb) => cb.callback !== handler); }; }, []); } @@ -48,17 +66,17 @@ window.addEventListener("keydown", (event) => { } // reverse so that the last registered callbacks get executed first - for (const callback of callbacks.reverse()) { + for (const registered of callbacks.reverse()) { if (event.defaultPrevented === true) { break; } if ( !isTextInput(event.target as HTMLElement) || - event.ctrlKey || - event.metaKey + registered.options?.allowInInput || + isModKey(event) ) { - callback(event); + registered.callback(event); } } }); diff --git a/package.json b/package.json index ac0c9646d..3bb7bd9d0 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "json-loader": "0.5.4", "jsonwebtoken": "^8.5.0", "jszip": "^3.7.1", - "kbar": "^0.1.0-beta.24", + "kbar": "0.1.0-beta.26", "koa": "^2.10.0", "koa-body": "^4.2.0", "koa-compress": "2.0.0", diff --git a/yarn.lock b/yarn.lock index 893fb1b2f..99b218a75 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9545,10 +9545,10 @@ jws@^3.2.2: jwa "^1.4.1" safe-buffer "^5.0.1" -kbar@^0.1.0-beta.24: - version "0.1.0-beta.24" - resolved "https://registry.yarnpkg.com/kbar/-/kbar-0.1.0-beta.24.tgz#5404c9817a0b7419b60b8378e45cffd7197970ee" - integrity sha512-frawEcCuWhI82DFxtv368vlApUkW11DfcpGt4WFxHT6t7uA1Gcz9Uqj8Pclt52iWJHRAcodqDKFZWrIg9mk8/Q== +kbar@0.1.0-beta.26: + version "0.1.0-beta.26" + resolved "https://registry.yarnpkg.com/kbar/-/kbar-0.1.0-beta.26.tgz#a91be32d4a840a758165fe8d8747f9bb2a8ca763" + integrity sha512-JI+oxADOBzxaY/7yrcYWJAXJYkfoeS04aptTXOQy3h/vAwuZuHwhoqW9mAQ/+0I+F+wO135BeVErF9jq7qE9Ig== dependencies: "@reach/portal" "^0.16.0" fast-equals "^2.0.3"