@solid-primitives/keyboard 2.0.0-next.1 → 2.0.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +23 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -156,6 +156,7 @@ Creates a keyboard shortcut observer. The provided callback will be called when
|
|
|
156
156
|
- `options` — additional configuration:
|
|
157
157
|
- `preventDefault` — call `e.preventDefault()` on the keyboard event, when the specified key is pressed. _(Defaults to `true`)_
|
|
158
158
|
- `requireReset` — If `true`, the shortcut will only be triggered once until all of the keys stop being pressed. Disabled by default.
|
|
159
|
+
- `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.
|
|
159
160
|
|
|
160
161
|
```tsx
|
|
161
162
|
import { createShortcut } from "@solid-primitives/keyboard";
|
|
@@ -175,6 +176,17 @@ When `preventDefault` is `true`, `e.preventDefault()` will be called not only on
|
|
|
175
176
|
|
|
176
177
|
E.g. when listening for `Control + Shift + A`, all three keydown events will be prevented.
|
|
177
178
|
|
|
179
|
+
### Ignoring shortcuts while typing
|
|
180
|
+
|
|
181
|
+
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:
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
// won't fire while the user is typing in a text field
|
|
185
|
+
createShortcut(["S"], () => console.log("S was pressed"), { ignoreWithinInputs: true });
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
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.
|
|
189
|
+
|
|
178
190
|
## `createKeyDown`
|
|
179
191
|
|
|
180
192
|
Listens for a `keydown` event for a specific key on a document. Useful for global keyboard handlers that need to respond to a single key without setting up a full shortcut.
|
package/dist/index.d.ts
CHANGED
|
@@ -131,17 +131,25 @@ export declare function createKeyHold(key: KbdKey, options?: {
|
|
|
131
131
|
* @param options The options for the shortcut.
|
|
132
132
|
* - `preventDefault` — Controls if the keydown event should have its default action prevented. Enabled by default.
|
|
133
133
|
* - `requireReset` — If `true`, the shortcut will only be triggered once until all of the keys stop being pressed. Disabled by default.
|
|
134
|
+
* - `ignoreWithinInputs` — If `true`, the shortcut is ignored while focus is on an `input`, `textarea`, `select`,
|
|
135
|
+
* or `contenteditable` element, so typing isn't interrupted. Disabled by default — enable it for shortcuts
|
|
136
|
+
* made of plain, unmodified keys (e.g. a single letter); combos like `Control+S` are usually fine either way,
|
|
137
|
+
* since the modifier prevents a character from being typed.
|
|
134
138
|
*
|
|
135
139
|
* @example
|
|
136
140
|
* ```ts
|
|
137
141
|
* createShortcut(["CONTROL", "SHIFT", "C"], () => {
|
|
138
142
|
* console.log("Ctrl+Shift+C was pressed");
|
|
139
143
|
* });
|
|
144
|
+
*
|
|
145
|
+
* // won't fire while typing in a text field
|
|
146
|
+
* createShortcut(["S"], () => console.log("S was pressed"), { ignoreWithinInputs: true });
|
|
140
147
|
* ```
|
|
141
148
|
*/
|
|
142
149
|
export declare function createShortcut(keys: KbdKey[], callback: (event: KeyboardEvent | null) => void, options?: {
|
|
143
150
|
preventDefault?: boolean;
|
|
144
151
|
requireReset?: boolean;
|
|
152
|
+
ignoreWithinInputs?: boolean;
|
|
145
153
|
}): void;
|
|
146
154
|
export interface CreateKeyDownOptions {
|
|
147
155
|
/** Whether the listener should be inactive. */
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,19 @@ function equalsKeyHoldSequence(sequence, model) {
|
|
|
11
11
|
}
|
|
12
12
|
return true;
|
|
13
13
|
}
|
|
14
|
+
/** Is the event target an editable form control, or inside a `contenteditable` element? */
|
|
15
|
+
function isEditableTarget(target) {
|
|
16
|
+
if (!(target instanceof HTMLElement))
|
|
17
|
+
return false;
|
|
18
|
+
switch (target.tagName) {
|
|
19
|
+
case "INPUT":
|
|
20
|
+
case "TEXTAREA":
|
|
21
|
+
case "SELECT":
|
|
22
|
+
return true;
|
|
23
|
+
default:
|
|
24
|
+
return target.isContentEditable;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
14
27
|
/**
|
|
15
28
|
* Provides a signal with the last keydown event.
|
|
16
29
|
*
|
|
@@ -244,12 +257,19 @@ export function createKeyHold(key, options = {}) {
|
|
|
244
257
|
* @param options The options for the shortcut.
|
|
245
258
|
* - `preventDefault` — Controls if the keydown event should have its default action prevented. Enabled by default.
|
|
246
259
|
* - `requireReset` — If `true`, the shortcut will only be triggered once until all of the keys stop being pressed. Disabled by default.
|
|
260
|
+
* - `ignoreWithinInputs` — If `true`, the shortcut is ignored while focus is on an `input`, `textarea`, `select`,
|
|
261
|
+
* or `contenteditable` element, so typing isn't interrupted. Disabled by default — enable it for shortcuts
|
|
262
|
+
* made of plain, unmodified keys (e.g. a single letter); combos like `Control+S` are usually fine either way,
|
|
263
|
+
* since the modifier prevents a character from being typed.
|
|
247
264
|
*
|
|
248
265
|
* @example
|
|
249
266
|
* ```ts
|
|
250
267
|
* createShortcut(["CONTROL", "SHIFT", "C"], () => {
|
|
251
268
|
* console.log("Ctrl+Shift+C was pressed");
|
|
252
269
|
* });
|
|
270
|
+
*
|
|
271
|
+
* // won't fire while typing in a text field
|
|
272
|
+
* createShortcut(["S"], () => console.log("S was pressed"), { ignoreWithinInputs: true });
|
|
253
273
|
* ```
|
|
254
274
|
*/
|
|
255
275
|
export function createShortcut(keys, callback, options = {}) {
|
|
@@ -257,7 +277,7 @@ export function createShortcut(keys, callback, options = {}) {
|
|
|
257
277
|
return;
|
|
258
278
|
}
|
|
259
279
|
keys = keys.map(key => key.toUpperCase());
|
|
260
|
-
const { preventDefault = true, requireReset = false } = options;
|
|
280
|
+
const { preventDefault = true, requireReset = false, ignoreWithinInputs = false } = options;
|
|
261
281
|
// Track pressed keys and sequence locally with plain JS state rather than
|
|
262
282
|
// reactive signals. A signal reads from event listeners return
|
|
263
283
|
// the pre-batch committed value, so synchronous shortcut checking requires
|
|
@@ -273,6 +293,8 @@ export function createShortcut(keys, callback, options = {}) {
|
|
|
273
293
|
makeEventListener(window, "keydown", (e) => {
|
|
274
294
|
if (e.repeat || typeof e.key !== "string")
|
|
275
295
|
return;
|
|
296
|
+
if (ignoreWithinInputs && isEditableTarget(e.target))
|
|
297
|
+
return;
|
|
276
298
|
const key = e.key.toUpperCase();
|
|
277
299
|
if (!pressedKeys.includes(key)) {
|
|
278
300
|
const newKeys = [...pressedKeys];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solid-primitives/keyboard",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.2",
|
|
4
4
|
"description": "A library of reactive promitives helping handling user's keyboard input.",
|
|
5
5
|
"author": "Damian Tarnwski <gthetarnav@gmail.com>",
|
|
6
6
|
"contributors": [],
|