@solid-primitives/keyboard
Advanced tools
+8
-0
@@ -134,2 +134,6 @@ import { type MaybeAccessor } from "@solid-primitives/utils"; | ||
| * - `requireReset` — If `true`, the shortcut will only be triggered once until all of the keys stop being pressed. Disabled by default. | ||
| * - `ignoreWithinInputs` — If `true`, the shortcut is ignored while focus is on an `input`, `textarea`, `select`, | ||
| * or `contenteditable` element, so typing isn't interrupted. Disabled by default — enable it for shortcuts | ||
| * made of plain, unmodified keys (e.g. a single letter); combos like `Control+S` are usually fine either way, | ||
| * since the modifier prevents a character from being typed. | ||
| * | ||
@@ -141,2 +145,5 @@ * @example | ||
| * }); | ||
| * | ||
| * // won't fire while typing in a text field | ||
| * createShortcut(["S"], () => console.log("S was pressed"), { ignoreWithinInputs: true }); | ||
| * ``` | ||
@@ -147,2 +154,3 @@ */ | ||
| requireReset?: boolean; | ||
| ignoreWithinInputs?: boolean; | ||
| }): void; | ||
@@ -149,0 +157,0 @@ export interface CreateKeyDownOptions { |
+23
-1
@@ -14,2 +14,15 @@ import { makeEventListener } from "@solid-primitives/event-listener"; | ||
| } | ||
| /** Is the event target an editable form control, or inside a `contenteditable` element? */ | ||
| function isEditableTarget(target) { | ||
| if (!(target instanceof HTMLElement)) | ||
| return false; | ||
| switch (target.tagName) { | ||
| case "INPUT": | ||
| case "TEXTAREA": | ||
| case "SELECT": | ||
| return true; | ||
| default: | ||
| return target.isContentEditable; | ||
| } | ||
| } | ||
| /** | ||
@@ -248,2 +261,6 @@ * Provides a signal with the last keydown event. | ||
| * - `requireReset` — If `true`, the shortcut will only be triggered once until all of the keys stop being pressed. Disabled by default. | ||
| * - `ignoreWithinInputs` — If `true`, the shortcut is ignored while focus is on an `input`, `textarea`, `select`, | ||
| * or `contenteditable` element, so typing isn't interrupted. Disabled by default — enable it for shortcuts | ||
| * made of plain, unmodified keys (e.g. a single letter); combos like `Control+S` are usually fine either way, | ||
| * since the modifier prevents a character from being typed. | ||
| * | ||
@@ -255,2 +272,5 @@ * @example | ||
| * }); | ||
| * | ||
| * // won't fire while typing in a text field | ||
| * createShortcut(["S"], () => console.log("S was pressed"), { ignoreWithinInputs: true }); | ||
| * ``` | ||
@@ -263,3 +283,3 @@ */ | ||
| keys = keys.map(key => key.toUpperCase()); | ||
| const { preventDefault = true, requireReset = false } = options; | ||
| const { preventDefault = true, requireReset = false, ignoreWithinInputs = false } = options; | ||
| // Track pressed keys and sequence locally with plain JS state rather than | ||
@@ -280,2 +300,4 @@ // reactive signals. A signal reads from event listeners return | ||
| return; | ||
| if (ignoreWithinInputs && isEditableTarget(e.target)) | ||
| return; | ||
| const key = e.key.toUpperCase(); | ||
@@ -282,0 +304,0 @@ if (!pressedKeys.includes(key)) { |
+1
-1
| { | ||
| "name": "@solid-primitives/keyboard", | ||
| "version": "2.0.0-next.1", | ||
| "version": "2.0.0-next.2", | ||
| "description": "A library of reactive promitives helping handling user's keyboard input.", | ||
@@ -5,0 +5,0 @@ "author": "Damian Tarnwski <gthetarnav@gmail.com>", |
+12
-0
@@ -159,2 +159,3 @@ <p> | ||
| - `requireReset` — If `true`, the shortcut will only be triggered once until all of the keys stop being pressed. Disabled by default. | ||
| - `ignoreWithinInputs` — If `true`, the shortcut is ignored while focus is on an `input`, `textarea`, `select`, or `contenteditable` element, so it doesn't interrupt typing. Disabled by default. | ||
@@ -179,2 +180,13 @@ ```tsx | ||
| ### Ignoring shortcuts while typing | ||
| Single, unmodified-key shortcuts (e.g. `["S"]`) conflict with typing — pressing "s" in a text field would both type the character and trigger the shortcut. Set `ignoreWithinInputs: true` to skip the shortcut entirely while focus is on a form control or `contenteditable` element: | ||
| ```tsx | ||
| // won't fire while the user is typing in a text field | ||
| createShortcut(["S"], () => console.log("S was pressed"), { ignoreWithinInputs: true }); | ||
| ``` | ||
| Combos that include a modifier (e.g. `Control + S`) don't have this problem, since the modifier itself prevents a character from being typed — `ignoreWithinInputs` is usually unnecessary for those. | ||
| ## `createKeyDown` | ||
@@ -181,0 +193,0 @@ |
33195
8.14%592
5.34%219
5.8%