From 1969cd0651eec3db1723077e95cb610682b80cf0 Mon Sep 17 00:00:00 2001 From: Josh Kelley Date: Thu, 22 May 2025 17:40:12 -0400 Subject: [PATCH 1/3] Minor grammar fixes --- .../docs/documentation/useHotkeys/scoping-hotkeys.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/documentation/docs/documentation/useHotkeys/scoping-hotkeys.mdx b/packages/documentation/docs/documentation/useHotkeys/scoping-hotkeys.mdx index 8997b779..6466508b 100644 --- a/packages/documentation/docs/documentation/useHotkeys/scoping-hotkeys.mdx +++ b/packages/documentation/docs/documentation/useHotkeys/scoping-hotkeys.mdx @@ -39,7 +39,7 @@ render( ) ``` -Everytime we press down the `c` key, both component trigger the callback. But how can we separate those two components +Every time we press down the `c` key, both components trigger the callback. But how can we separate those two components and their assigned hotkeys? The answer is [`Refs`](https://react.dev/learn/manipulating-the-dom-with-refs). `useHotkeys` returns a [React ref callback function](https://react.dev/reference/react-dom/components/common#ref-callback) that we can attach to any component that takes a ref. This way we can tell the hook which element should receive the users focus From 8df612b87c40906b73b9eacdd4eb1ecd2f840361 Mon Sep 17 00:00:00 2001 From: Josh Kelley Date: Thu, 22 May 2025 17:40:31 -0400 Subject: [PATCH 2/3] Add missing docs for new key sequence options --- README.md | 2 ++ .../documentation/docs/api/use-hotkeys.mdx | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/README.md b/README.md index 6acb38d6..17595a2e 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,8 @@ All options are optional and have a default value which you can override to chan | `enableOnContentEditable` | `boolean` | `false` | Set this option to enable hotkeys on tags that have set the `contentEditable` prop to `true` | | `combinationKey` | `string` | `+` | Character to indicate keystrokes like `shift+c`. You might want to change this if you want to listen to the `+` character like `ctrl-+`. | | `splitKey` | `string` | `,` | Character to separate different keystrokes like `ctrl+a, ctrl+b`. | +| `sequenceSplitKey` | `string` | `>` | Character to separate different keystrokes in a sequence like `g>h`. | +| `sequenceTimeoutMs` | `number` | 1000 | Timeout in milliseconds for recognizing a keystroke sequence. | | `scopes` | `string` or `string[]` | `*` | With scopes you can group hotkeys together. The default scope is the wildcard `*` which matches all hotkeys. Use the `` component to change active scopes. | | `keyup` | `boolean` | `false` | Determines whether to listen to the browsers `keyup` event for triggering the callback. | | `keydown` | `boolean` | `true` | Determines whether to listen to the browsers `keydown` event for triggering the callback. If you set both `keyup`and `keydown` to true, the callback will trigger on both events. | diff --git a/packages/documentation/docs/api/use-hotkeys.mdx b/packages/documentation/docs/api/use-hotkeys.mdx index 741979da..659cfdb8 100644 --- a/packages/documentation/docs/api/use-hotkeys.mdx +++ b/packages/documentation/docs/api/use-hotkeys.mdx @@ -163,6 +163,8 @@ const options = { enableOnContentEditable: false, combinationKey: '+', splitKey: ',', + sequenceSplitKey: '>', + sequenceTimeoutMs: 1000, scopes: '*', keyup: undefined, keydown: true, @@ -185,6 +187,8 @@ type Options = { enableOnContentEditable?: boolean combinationKey?: string splitKey?: string + sequenceSplitKey?: string + sequenceTimeoutMs?: number scopes?: string | string[] keyup?: boolean keydown?: boolean @@ -251,6 +255,23 @@ splitKey: string // default: "+" Specifies the key that is used to combine multiple hotkeys into keystrokes. The default value is `+`, so `shift+a` triggers when the user presses the "shift" key __and__ the "a" key. +##### `sequenceSplitKey` + +```ts +sequenceSplitKey: string // default: ">" +``` + +Specifies the key that is used to separate multiple hotkeys in a [keystroke sequence](../documentation/useHotkeys/basic-usage#sequential-hotkeys). The default value is '>', so `g>h` triggers when the user presses the "g" key followed by the "h" key. + +##### `sequenceTimeoutMs` + +```ts +sequenceTimeoutMs: number // default: 1000 +``` + +Timeout in milliseconds for recognizing a [keystroke sequence](../documentation/useHotkeys/basic-usage#sequential-hotkeys). +The default value is `1000ms`, so if the user doesn't press the next key in that given time, the sequence is aborted. + ##### `scopes` To group your hotkeys into different scopes, you can pass a string or an array of strings to the `scopes` property. This From c13ccbd9db32e649ade40a34ac350d1e79ee862c Mon Sep 17 00:00:00 2001 From: Josh Kelley Date: Thu, 22 May 2025 17:40:43 -0400 Subject: [PATCH 3/3] Add a warning for potentially invalid combinations --- packages/react-hotkeys-hook/src/lib/parseHotkeys.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/react-hotkeys-hook/src/lib/parseHotkeys.ts b/packages/react-hotkeys-hook/src/lib/parseHotkeys.ts index 369e89ae..364c57c1 100644 --- a/packages/react-hotkeys-hook/src/lib/parseHotkeys.ts +++ b/packages/react-hotkeys-hook/src/lib/parseHotkeys.ts @@ -67,6 +67,12 @@ export function parseHotkey( const singleCharKeys = keys.filter((k) => !reservedModifierKeywords.includes(k)) + if (singleCharKeys.some(i => !i)) { + console.warn( + `Invalid hotkey "${hotkey}". Hotkeys should not contain empty keys. Check your delimiter, splitKey ("${splitKey}"), sequenceSplitKey ("${sequenceSplitKey}").` + ) + } + return { ...modifiers, keys: singleCharKeys,