@solid-primitives/keyboard 1.3.4 → 2.0.0-next.0
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 +31 -9
- package/dist/index.d.ts +30 -7
- package/dist/index.js +145 -70
- package/package.json +12 -8
package/README.md
CHANGED
|
@@ -5,18 +5,20 @@
|
|
|
5
5
|
# @solid-primitives/keyboard
|
|
6
6
|
|
|
7
7
|
[](https://lerna.js.org/)
|
|
8
|
-
[](https://bundlephobia.com/package/@solid-primitives/keyboard)
|
|
9
9
|
[](https://www.npmjs.com/package/@solid-primitives/keyboard)
|
|
10
10
|
[](https://github.com/solidjs-community/solid-primitives#contribution-process)
|
|
11
|
+
[](https://vitest.dev)
|
|
11
12
|
|
|
12
|
-
A library of reactive
|
|
13
|
+
A library of reactive primitives for handling user keyboard input.
|
|
13
14
|
|
|
14
15
|
- [`useKeyDownEvent`](#usekeydownevent) — Provides a signal with the last keydown event.
|
|
15
|
-
- [`useKeyDownList`](#usekeydownlist) — Provides a signal with the list of currently held keys
|
|
16
|
+
- [`useKeyDownList`](#usekeydownlist) — Provides a signal with the list of currently held keys.
|
|
16
17
|
- [`useCurrentlyHeldKey`](#usecurrentlyheldkey) — Provides a signal with the currently held single key.
|
|
17
18
|
- [`useKeyDownSequence`](#usekeydownsequence) — Provides a signal with a sequence of currently held keys, as they were pressed down and up.
|
|
18
19
|
- [`createKeyHold`](#createkeyhold) — Provides a signal indicating if provided key is currently being held down.
|
|
19
|
-
- [`createShortcut`](#createshortcut) — Creates a keyboard
|
|
20
|
+
- [`createShortcut`](#createshortcut) — Creates a keyboard shortcut observer.
|
|
21
|
+
- [`createKeyDown`](#createkeydown) — Listens for a keydown event for a specific key on a document.
|
|
20
22
|
|
|
21
23
|
## Installation
|
|
22
24
|
|
|
@@ -62,7 +64,7 @@ This is a [singleton root](https://github.com/solidjs-community/solid-primitives
|
|
|
62
64
|
|
|
63
65
|
### How to use it
|
|
64
66
|
|
|
65
|
-
`useKeyDownList` takes no arguments
|
|
67
|
+
`useKeyDownList` takes no arguments and returns a signal with the list of currently held keys.
|
|
66
68
|
|
|
67
69
|
```tsx
|
|
68
70
|
import { useKeyDownList } from "@solid-primitives/keyboard";
|
|
@@ -143,7 +145,7 @@ const pressing = createKeyHold("Alt", { preventDefault: false });
|
|
|
143
145
|
|
|
144
146
|
## `createShortcut`
|
|
145
147
|
|
|
146
|
-
Creates a keyboard
|
|
148
|
+
Creates a keyboard shortcut observer. The provided callback will be called when the specified keys are pressed.
|
|
147
149
|
|
|
148
150
|
### How to use it
|
|
149
151
|
|
|
@@ -173,11 +175,31 @@ When `preventDefault` is `true`, `e.preventDefault()` will be called not only on
|
|
|
173
175
|
|
|
174
176
|
E.g. when listening for `Control + Shift + A`, all three keydown events will be prevented.
|
|
175
177
|
|
|
176
|
-
##
|
|
178
|
+
## `createKeyDown`
|
|
177
179
|
|
|
178
|
-
|
|
180
|
+
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.
|
|
179
181
|
|
|
180
|
-
|
|
182
|
+
### How to use it
|
|
183
|
+
|
|
184
|
+
`createKeyDown` takes three arguments:
|
|
185
|
+
|
|
186
|
+
- `key` — the key to listen for (matched against `event.key`)
|
|
187
|
+
- `callback` — handler called when the key is pressed, receives the `KeyboardEvent`
|
|
188
|
+
- `options` — additional configuration:
|
|
189
|
+
- `disabled` — a `boolean` or accessor; when `true` the listener is inactive. Reactive — the listener is added/removed as the value changes.
|
|
190
|
+
- `ownerDocument` — accessor returning the `Document` to attach the listener to. Defaults to `window.document`. Useful for iframes and portals.
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import { createKeyDown } from "@solid-primitives/keyboard";
|
|
194
|
+
|
|
195
|
+
createKeyDown("Escape", e => close());
|
|
196
|
+
|
|
197
|
+
// with options
|
|
198
|
+
createKeyDown("Escape", e => close(), {
|
|
199
|
+
disabled: () => !isOpen(),
|
|
200
|
+
ownerDocument: () => iframeEl.contentDocument ?? document,
|
|
201
|
+
});
|
|
202
|
+
```
|
|
181
203
|
|
|
182
204
|
## Changelog
|
|
183
205
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type MaybeAccessor } from "@solid-primitives/utils";
|
|
1
2
|
import { type Accessor } from "solid-js";
|
|
2
3
|
export type ModifierKey = "Alt" | "Control" | "Meta" | "Shift";
|
|
3
4
|
export type KbdKey = ModifierKey | (string & {});
|
|
@@ -23,8 +24,8 @@ export type KbdKey = ModifierKey | (string & {});
|
|
|
23
24
|
* console.log(e) // => KeyboardEvent | null
|
|
24
25
|
*
|
|
25
26
|
* if (e) {
|
|
26
|
-
* console.log(e.key) // => "Q" | "ALT" | ...
|
|
27
|
-
* e.preventDefault();
|
|
27
|
+
* console.log(e.key) // => "Q" | "ALT" | ...
|
|
28
|
+
* e.preventDefault();
|
|
28
29
|
* }
|
|
29
30
|
* })
|
|
30
31
|
* ```
|
|
@@ -102,8 +103,8 @@ export declare const useKeyDownSequence: () => Accessor<string[][]>;
|
|
|
102
103
|
* @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/keyboard#createKeyHold
|
|
103
104
|
*
|
|
104
105
|
* @param key The key to check for.
|
|
105
|
-
* @options The options for the key hold.
|
|
106
|
-
* - `preventDefault` —
|
|
106
|
+
* @param options The options for the key hold.
|
|
107
|
+
* - `preventDefault` — Controls if the keydown event should have its default action prevented. Enabled by default.
|
|
107
108
|
* @returns
|
|
108
109
|
* ```ts
|
|
109
110
|
* Accessor<boolean>
|
|
@@ -121,14 +122,14 @@ export declare function createKeyHold(key: KbdKey, options?: {
|
|
|
121
122
|
preventDefault?: boolean;
|
|
122
123
|
}): Accessor<boolean>;
|
|
123
124
|
/**
|
|
124
|
-
* Creates a keyboard
|
|
125
|
+
* Creates a keyboard shortcut observer. The provided {@link callback} will be called when the specified {@link keys} are pressed.
|
|
125
126
|
*
|
|
126
127
|
* @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/keyboard#createShortcut
|
|
127
128
|
*
|
|
128
129
|
* @param keys The sequence of keys to watch for.
|
|
129
130
|
* @param callback The callback to call when the keys are pressed.
|
|
130
|
-
* @options The options for the shortcut.
|
|
131
|
-
* - `preventDefault` —
|
|
131
|
+
* @param options The options for the shortcut.
|
|
132
|
+
* - `preventDefault` — Controls if the keydown event should have its default action prevented. Enabled by default.
|
|
132
133
|
* - `requireReset` — If `true`, the shortcut will only be triggered once until all of the keys stop being pressed. Disabled by default.
|
|
133
134
|
*
|
|
134
135
|
* @example
|
|
@@ -142,3 +143,25 @@ export declare function createShortcut(keys: KbdKey[], callback: (event: Keyboar
|
|
|
142
143
|
preventDefault?: boolean;
|
|
143
144
|
requireReset?: boolean;
|
|
144
145
|
}): void;
|
|
146
|
+
export interface CreateKeyDownOptions {
|
|
147
|
+
/** Whether the listener should be inactive. */
|
|
148
|
+
disabled?: MaybeAccessor<boolean | undefined>;
|
|
149
|
+
/** The document to attach the listener to. Defaults to `window.document`. Useful for iframes. */
|
|
150
|
+
ownerDocument?: Accessor<Document | undefined>;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Listens for a keydown event for a specific key on a document.
|
|
154
|
+
* Supports a custom `ownerDocument` for use in iframes and portals.
|
|
155
|
+
*
|
|
156
|
+
* @param key The key to listen for (matched against `event.key`).
|
|
157
|
+
* @param callback Handler called when the key is pressed.
|
|
158
|
+
* @param options `disabled` and `ownerDocument` accessors.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```ts
|
|
162
|
+
* createKeyDown("Escape", e => close(), {
|
|
163
|
+
* ownerDocument: () => iframeEl.contentDocument ?? document,
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
export declare function createKeyDown(key: KbdKey, callback: (event: KeyboardEvent) => void, options?: CreateKeyDownOptions): void;
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { makeEventListener } from "@solid-primitives/event-listener";
|
|
2
2
|
import { createSingletonRoot } from "@solid-primitives/rootless";
|
|
3
|
-
import { arrayEquals } from "@solid-primitives/utils";
|
|
4
|
-
import { createEffect, createMemo, createSignal,
|
|
5
|
-
import { isServer } from "
|
|
3
|
+
import { arrayEquals, INTERNAL_OPTIONS, access } from "@solid-primitives/utils";
|
|
4
|
+
import { createEffect, createMemo, createSignal, untrack } from "solid-js";
|
|
5
|
+
import { isServer } from "@solidjs/web";
|
|
6
6
|
function equalsKeyHoldSequence(sequence, model) {
|
|
7
7
|
for (let i = sequence.length - 1; i >= 0; i--) {
|
|
8
8
|
const _model = model.slice(0, i + 1);
|
|
@@ -33,8 +33,8 @@ function equalsKeyHoldSequence(sequence, model) {
|
|
|
33
33
|
* console.log(e) // => KeyboardEvent | null
|
|
34
34
|
*
|
|
35
35
|
* if (e) {
|
|
36
|
-
* console.log(e.key) // => "Q" | "ALT" | ...
|
|
37
|
-
* e.preventDefault();
|
|
36
|
+
* console.log(e.key) // => "Q" | "ALT" | ...
|
|
37
|
+
* e.preventDefault();
|
|
38
38
|
* }
|
|
39
39
|
* })
|
|
40
40
|
* ```
|
|
@@ -43,7 +43,7 @@ export const useKeyDownEvent = /*#__PURE__*/ createSingletonRoot(() => {
|
|
|
43
43
|
if (isServer) {
|
|
44
44
|
return () => null;
|
|
45
45
|
}
|
|
46
|
-
const [event, setEvent] = createSignal(null);
|
|
46
|
+
const [event, setEvent] = createSignal(null, INTERNAL_OPTIONS);
|
|
47
47
|
makeEventListener(window, "keydown", e => {
|
|
48
48
|
setEvent(e);
|
|
49
49
|
setTimeout(() => setEvent(null));
|
|
@@ -73,18 +73,10 @@ export const useKeyDownEvent = /*#__PURE__*/ createSingletonRoot(() => {
|
|
|
73
73
|
*/
|
|
74
74
|
export const useKeyDownList = /*#__PURE__*/ createSingletonRoot(() => {
|
|
75
75
|
if (isServer) {
|
|
76
|
-
|
|
77
|
-
// this is for backwards compatibility
|
|
78
|
-
// TODO remove in the next major version
|
|
79
|
-
keys[0] = keys;
|
|
80
|
-
keys[1] = { event: () => null };
|
|
81
|
-
keys[Symbol.iterator] = function* () {
|
|
82
|
-
yield keys[0];
|
|
83
|
-
yield keys[1];
|
|
84
|
-
};
|
|
85
|
-
return keys;
|
|
76
|
+
return () => [];
|
|
86
77
|
}
|
|
87
|
-
const [pressedKeys, setPressedKeys] = createSignal([]
|
|
78
|
+
const [pressedKeys, setPressedKeys] = createSignal([], INTERNAL_OPTIONS);
|
|
79
|
+
const reset = () => setPressedKeys([]);
|
|
88
80
|
makeEventListener(window, "keydown", e => {
|
|
89
81
|
// e.key may be undefined when used with <datalist> el
|
|
90
82
|
// gh issue: https://github.com/solidjs-community/solid-primitives/issues/246
|
|
@@ -122,14 +114,6 @@ export const useKeyDownList = /*#__PURE__*/ createSingletonRoot(() => {
|
|
|
122
114
|
makeEventListener(window, "contextmenu", e => {
|
|
123
115
|
e.defaultPrevented || reset();
|
|
124
116
|
});
|
|
125
|
-
// this is for backwards compatibility
|
|
126
|
-
// TODO remove in the next major version
|
|
127
|
-
pressedKeys[0] = pressedKeys;
|
|
128
|
-
pressedKeys[1] = { event };
|
|
129
|
-
pressedKeys[Symbol.iterator] = function* () {
|
|
130
|
-
yield pressedKeys[0];
|
|
131
|
-
yield pressedKeys[1];
|
|
132
|
-
};
|
|
133
117
|
return pressedKeys;
|
|
134
118
|
});
|
|
135
119
|
/**
|
|
@@ -193,11 +177,13 @@ export const useKeyDownSequence = /*#__PURE__*/ createSingletonRoot(() => {
|
|
|
193
177
|
return () => [];
|
|
194
178
|
}
|
|
195
179
|
const keys = useKeyDownList();
|
|
196
|
-
|
|
180
|
+
// createMemo's second arg is options (not initialValue). The prev
|
|
181
|
+
// parameter starts as undefined; handle it with a fallback.
|
|
182
|
+
return createMemo((prev) => {
|
|
197
183
|
if (keys().length === 0)
|
|
198
184
|
return [];
|
|
199
|
-
return [...prev, keys()];
|
|
200
|
-
}
|
|
185
|
+
return [...(prev ?? []), keys()];
|
|
186
|
+
});
|
|
201
187
|
});
|
|
202
188
|
/**
|
|
203
189
|
* Provides a `boolean` signal indicating if provided {@link key} is currently being held down.
|
|
@@ -206,8 +192,8 @@ export const useKeyDownSequence = /*#__PURE__*/ createSingletonRoot(() => {
|
|
|
206
192
|
* @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/keyboard#createKeyHold
|
|
207
193
|
*
|
|
208
194
|
* @param key The key to check for.
|
|
209
|
-
* @options The options for the key hold.
|
|
210
|
-
* - `preventDefault` —
|
|
195
|
+
* @param options The options for the key hold.
|
|
196
|
+
* - `preventDefault` — Controls if the keydown event should have its default action prevented. Enabled by default.
|
|
211
197
|
* @returns
|
|
212
198
|
* ```ts
|
|
213
199
|
* Accessor<boolean>
|
|
@@ -226,18 +212,28 @@ export function createKeyHold(key, options = {}) {
|
|
|
226
212
|
return () => false;
|
|
227
213
|
}
|
|
228
214
|
key = key.toUpperCase();
|
|
229
|
-
const { preventDefault = true } = options
|
|
230
|
-
|
|
215
|
+
const { preventDefault = true } = options;
|
|
216
|
+
const heldKey = useCurrentlyHeldKey();
|
|
217
|
+
if (preventDefault) {
|
|
218
|
+
// Use a direct event listener for synchronous preventDefault — signal reads in event
|
|
219
|
+
// listeners return the pre-batch committed value, so we check e.key directly.
|
|
220
|
+
makeEventListener(window, "keydown", (e) => {
|
|
221
|
+
if (e.key.toUpperCase() === key) {
|
|
222
|
+
e.preventDefault();
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
return createMemo(() => heldKey() === key);
|
|
231
227
|
}
|
|
232
228
|
/**
|
|
233
|
-
* Creates a keyboard
|
|
229
|
+
* Creates a keyboard shortcut observer. The provided {@link callback} will be called when the specified {@link keys} are pressed.
|
|
234
230
|
*
|
|
235
231
|
* @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/keyboard#createShortcut
|
|
236
232
|
*
|
|
237
233
|
* @param keys The sequence of keys to watch for.
|
|
238
234
|
* @param callback The callback to call when the keys are pressed.
|
|
239
|
-
* @options The options for the shortcut.
|
|
240
|
-
* - `preventDefault` —
|
|
235
|
+
* @param options The options for the shortcut.
|
|
236
|
+
* - `preventDefault` — Controls if the keydown event should have its default action prevented. Enabled by default.
|
|
241
237
|
* - `requireReset` — If `true`, the shortcut will only be triggered once until all of the keys stop being pressed. Disabled by default.
|
|
242
238
|
*
|
|
243
239
|
* @example
|
|
@@ -252,52 +248,131 @@ export function createShortcut(keys, callback, options = {}) {
|
|
|
252
248
|
return;
|
|
253
249
|
}
|
|
254
250
|
keys = keys.map(key => key.toUpperCase());
|
|
255
|
-
const { preventDefault = true
|
|
251
|
+
const { preventDefault = true, requireReset = false } = options;
|
|
252
|
+
// Track pressed keys and sequence locally with plain JS state rather than
|
|
253
|
+
// reactive signals. A signal reads from event listeners return
|
|
254
|
+
// the pre-batch committed value, so synchronous shortcut checking requires
|
|
255
|
+
// imperative state that's updated in the same event listener tick.
|
|
256
|
+
let pressedKeys = [];
|
|
257
|
+
let sequence = [];
|
|
256
258
|
let reset = false;
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
259
|
+
const resetAll = () => {
|
|
260
|
+
pressedKeys = [];
|
|
261
|
+
sequence = [];
|
|
262
|
+
reset = false;
|
|
263
|
+
};
|
|
264
|
+
makeEventListener(window, "keydown", (e) => {
|
|
265
|
+
if (e.repeat || typeof e.key !== "string")
|
|
262
266
|
return;
|
|
263
|
-
const
|
|
264
|
-
if (
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
267
|
+
const key = e.key.toUpperCase();
|
|
268
|
+
if (!pressedKeys.includes(key)) {
|
|
269
|
+
const newKeys = [...pressedKeys];
|
|
270
|
+
// Detect modifiers pressed before listener attached
|
|
271
|
+
if (pressedKeys.length === 0 &&
|
|
272
|
+
key !== "ALT" &&
|
|
273
|
+
key !== "CONTROL" &&
|
|
274
|
+
key !== "META" &&
|
|
275
|
+
key !== "SHIFT") {
|
|
276
|
+
if (e.shiftKey && !newKeys.includes("SHIFT"))
|
|
277
|
+
newKeys.unshift("SHIFT");
|
|
278
|
+
if (e.altKey && !newKeys.includes("ALT"))
|
|
279
|
+
newKeys.unshift("ALT");
|
|
280
|
+
if (e.ctrlKey && !newKeys.includes("CONTROL"))
|
|
281
|
+
newKeys.unshift("CONTROL");
|
|
282
|
+
if (e.metaKey && !newKeys.includes("META"))
|
|
283
|
+
newKeys.unshift("META");
|
|
284
|
+
}
|
|
285
|
+
newKeys.push(key);
|
|
286
|
+
pressedKeys = newKeys;
|
|
287
|
+
sequence = [...sequence, [...pressedKeys]];
|
|
288
|
+
}
|
|
289
|
+
if (requireReset) {
|
|
290
|
+
if (reset)
|
|
291
|
+
return;
|
|
292
|
+
if (sequence.length < keys.length) {
|
|
293
|
+
if (equalsKeyHoldSequence(sequence, keys.slice(0, sequence.length))) {
|
|
294
|
+
preventDefault && e.preventDefault();
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
reset = true;
|
|
298
|
+
}
|
|
268
299
|
}
|
|
269
300
|
else {
|
|
270
301
|
reset = true;
|
|
302
|
+
if (equalsKeyHoldSequence(sequence, keys)) {
|
|
303
|
+
preventDefault && e.preventDefault();
|
|
304
|
+
callback(e);
|
|
305
|
+
}
|
|
271
306
|
}
|
|
272
307
|
}
|
|
273
308
|
else {
|
|
274
|
-
|
|
275
|
-
if (
|
|
276
|
-
|
|
277
|
-
|
|
309
|
+
const last = sequence.at(-1);
|
|
310
|
+
if (!last)
|
|
311
|
+
return;
|
|
312
|
+
if (preventDefault && last.length < keys.length) {
|
|
313
|
+
if (arrayEquals(last, keys.slice(0, keys.length - 1))) {
|
|
314
|
+
e.preventDefault();
|
|
315
|
+
}
|
|
316
|
+
return;
|
|
278
317
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
return;
|
|
286
|
-
const e = event();
|
|
287
|
-
// optimistically preventDefault behavior if we yet don't have enough keys
|
|
288
|
-
if (preventDefault && last.length < keys.length) {
|
|
289
|
-
if (arrayEquals(last, keys.slice(0, keys.length - 1))) {
|
|
290
|
-
e && e.preventDefault();
|
|
318
|
+
if (arrayEquals(last, keys)) {
|
|
319
|
+
const prev = sequence.at(-2);
|
|
320
|
+
if (!prev || arrayEquals(prev, keys.slice(0, keys.length - 1))) {
|
|
321
|
+
preventDefault && e.preventDefault();
|
|
322
|
+
callback(e);
|
|
323
|
+
}
|
|
291
324
|
}
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
makeEventListener(window, "keyup", (e) => {
|
|
328
|
+
if (typeof e.key !== "string")
|
|
292
329
|
return;
|
|
330
|
+
const key = e.key.toUpperCase();
|
|
331
|
+
pressedKeys = pressedKeys.filter(k => k !== key);
|
|
332
|
+
if (pressedKeys.length === 0) {
|
|
333
|
+
sequence = [];
|
|
334
|
+
reset = false;
|
|
293
335
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
callback(e);
|
|
299
|
-
}
|
|
336
|
+
else {
|
|
337
|
+
// Reset sequence to remaining held keys so repeated presses of the last
|
|
338
|
+
// key can re-trigger the shortcut while modifier keys stay held.
|
|
339
|
+
sequence = [[...pressedKeys]];
|
|
300
340
|
}
|
|
301
|
-
};
|
|
302
|
-
|
|
341
|
+
});
|
|
342
|
+
makeEventListener(window, "blur", resetAll);
|
|
343
|
+
makeEventListener(window, "contextmenu", (e) => {
|
|
344
|
+
e.defaultPrevented || resetAll();
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Listens for a keydown event for a specific key on a document.
|
|
349
|
+
* Supports a custom `ownerDocument` for use in iframes and portals.
|
|
350
|
+
*
|
|
351
|
+
* @param key The key to listen for (matched against `event.key`).
|
|
352
|
+
* @param callback Handler called when the key is pressed.
|
|
353
|
+
* @param options `disabled` and `ownerDocument` accessors.
|
|
354
|
+
*
|
|
355
|
+
* @example
|
|
356
|
+
* ```ts
|
|
357
|
+
* createKeyDown("Escape", e => close(), {
|
|
358
|
+
* ownerDocument: () => iframeEl.contentDocument ?? document,
|
|
359
|
+
* });
|
|
360
|
+
* ```
|
|
361
|
+
*/
|
|
362
|
+
export function createKeyDown(key, callback, options) {
|
|
363
|
+
if (isServer)
|
|
364
|
+
return;
|
|
365
|
+
createEffect(() => ({
|
|
366
|
+
disabled: !!access(options?.disabled),
|
|
367
|
+
document: options?.ownerDocument?.() ?? window.document,
|
|
368
|
+
}), ({ disabled, document }) => {
|
|
369
|
+
if (disabled)
|
|
370
|
+
return;
|
|
371
|
+
const handler = (e) => {
|
|
372
|
+
if (e.key === key)
|
|
373
|
+
callback(e);
|
|
374
|
+
};
|
|
375
|
+
document.addEventListener("keydown", handler);
|
|
376
|
+
return () => document.removeEventListener("keydown", handler);
|
|
377
|
+
});
|
|
303
378
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solid-primitives/keyboard",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-next.0",
|
|
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": [],
|
|
@@ -15,15 +15,17 @@
|
|
|
15
15
|
},
|
|
16
16
|
"primitive": {
|
|
17
17
|
"name": "keyboard",
|
|
18
|
-
"stage":
|
|
18
|
+
"stage": 3,
|
|
19
19
|
"list": [
|
|
20
|
+
"useKeyDownEvent",
|
|
20
21
|
"useKeyDownList",
|
|
21
22
|
"useCurrentlyHeldKey",
|
|
22
23
|
"useKeyDownSequence",
|
|
23
24
|
"createKeyHold",
|
|
24
25
|
"createShortcut"
|
|
25
26
|
],
|
|
26
|
-
"category": "Inputs"
|
|
27
|
+
"category": "Inputs",
|
|
28
|
+
"gzip": 1348
|
|
27
29
|
},
|
|
28
30
|
"keywords": [
|
|
29
31
|
"solid",
|
|
@@ -49,15 +51,17 @@
|
|
|
49
51
|
}
|
|
50
52
|
},
|
|
51
53
|
"dependencies": {
|
|
52
|
-
"@solid-primitives/event-listener": "^
|
|
53
|
-
"@solid-primitives/rootless": "^
|
|
54
|
-
"@solid-primitives/utils": "^
|
|
54
|
+
"@solid-primitives/event-listener": "^3.0.0-next.0",
|
|
55
|
+
"@solid-primitives/rootless": "^2.0.0-next.0",
|
|
56
|
+
"@solid-primitives/utils": "^7.0.0-next.0"
|
|
55
57
|
},
|
|
56
58
|
"peerDependencies": {
|
|
57
|
-
"
|
|
59
|
+
"@solidjs/web": "^2.0.0-beta.15",
|
|
60
|
+
"solid-js": "^2.0.0-beta.15"
|
|
58
61
|
},
|
|
59
62
|
"devDependencies": {
|
|
60
|
-
"
|
|
63
|
+
"@solidjs/web": "2.0.0-beta.15",
|
|
64
|
+
"solid-js": "2.0.0-beta.15"
|
|
61
65
|
},
|
|
62
66
|
"typesVersions": {},
|
|
63
67
|
"scripts": {
|