@rocketc/react-use-shortcuts 0.0.1-alpha.10
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/LICENSE +21 -0
- package/README.md +596 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +145 -0
- package/dist/index.js.map +1 -0
- package/package.json +37 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 heychenfq
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
# @rocketc/react-use-shortcuts
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Full React shortcut solution built on top of [`@rocketc/shortcuts`](../shortcuts/README.md).
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **React Hooks**: Use `useShortcut` hook to access shortcut APIs
|
|
10
|
+
- **Context Provider**: `ReactShortcutProvider` for React context integration
|
|
11
|
+
- **Strict/Loose mode**: Support both strict and loose matching modes
|
|
12
|
+
- **Page scoped register**: Register shortcuts scoped to specific elements
|
|
13
|
+
- **Dynamic register**: Register and unregister shortcuts at runtime
|
|
14
|
+
- **Dynamic enable/disable**: Enable or disable registered shortcuts dynamically
|
|
15
|
+
- **Flexible key combinations**: Support complex modifier and normal key combinations
|
|
16
|
+
- **Use modern browser API**: Uses modern browser APIs (`KeyboardEvent.code`)
|
|
17
|
+
- **Full TypeScript support**: Complete type definitions included
|
|
18
|
+
- **Shortcut validation**: Built-in validation for accelerator strings
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# npm
|
|
24
|
+
npm install @rocketc/react-use-shortcuts
|
|
25
|
+
|
|
26
|
+
# yarn
|
|
27
|
+
yarn add @rocketc/react-use-shortcuts
|
|
28
|
+
|
|
29
|
+
# pnpm
|
|
30
|
+
pnpm add @rocketc/react-use-shortcuts
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Note**: This package depends on [`@rocketc/shortcuts`](../shortcuts/README.md) for core functionality. It will be installed automatically.
|
|
34
|
+
|
|
35
|
+
## Supported Keys
|
|
36
|
+
|
|
37
|
+
See the [Supported Keys section](../shortcuts/README.md#supported-keys) in `@rocketc/shortcuts` documentation.
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import React, { useEffect } from 'react';
|
|
43
|
+
import {
|
|
44
|
+
ReactShortcutProvider,
|
|
45
|
+
useShortcut,
|
|
46
|
+
} from '@rocketc/react-use-shortcuts';
|
|
47
|
+
|
|
48
|
+
function App() {
|
|
49
|
+
return (
|
|
50
|
+
<ReactShortcutProvider>
|
|
51
|
+
<Main />
|
|
52
|
+
</ReactShortcutProvider>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function Main() {
|
|
57
|
+
const { registerShortcut, unregisterShortcut } = useShortcut();
|
|
58
|
+
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
registerShortcut('Ctrl+a', (event) => {
|
|
61
|
+
console.log('Ctrl+A pressed!');
|
|
62
|
+
event.preventDefault();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return () => {
|
|
66
|
+
unregisterShortcut('Ctrl+a');
|
|
67
|
+
};
|
|
68
|
+
}, []);
|
|
69
|
+
|
|
70
|
+
return <h1>Hello World!</h1>;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Examples
|
|
75
|
+
|
|
76
|
+
### 1. Register Single Key Shortcut
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
import React, { useEffect } from 'react';
|
|
80
|
+
import {
|
|
81
|
+
ReactShortcutProvider,
|
|
82
|
+
useShortcut,
|
|
83
|
+
} from '@rocketc/react-use-shortcuts';
|
|
84
|
+
|
|
85
|
+
function App() {
|
|
86
|
+
return (
|
|
87
|
+
<ReactShortcutProvider>
|
|
88
|
+
<Main />
|
|
89
|
+
</ReactShortcutProvider>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function Main() {
|
|
94
|
+
const { registerShortcut, unregisterShortcut } = useShortcut();
|
|
95
|
+
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
registerShortcut('a', (event) => {
|
|
98
|
+
event.preventDefault();
|
|
99
|
+
console.log('You pressed A');
|
|
100
|
+
});
|
|
101
|
+
return () => {
|
|
102
|
+
unregisterShortcut('a');
|
|
103
|
+
};
|
|
104
|
+
}, []);
|
|
105
|
+
|
|
106
|
+
return <h1>Hello World!</h1>;
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 2. Register Shortcut with Modifiers
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
import React, { useEffect } from 'react';
|
|
114
|
+
import {
|
|
115
|
+
ReactShortcutProvider,
|
|
116
|
+
useShortcut,
|
|
117
|
+
} from '@rocketc/react-use-shortcuts';
|
|
118
|
+
|
|
119
|
+
function App() {
|
|
120
|
+
return (
|
|
121
|
+
<ReactShortcutProvider>
|
|
122
|
+
<Main />
|
|
123
|
+
</ReactShortcutProvider>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function Main() {
|
|
128
|
+
const { registerShortcut, unregisterShortcut } = useShortcut();
|
|
129
|
+
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
registerShortcut('Ctrl+a', (event) => {
|
|
132
|
+
console.log('You pressed Ctrl and A');
|
|
133
|
+
});
|
|
134
|
+
return () => {
|
|
135
|
+
unregisterShortcut('Ctrl+a');
|
|
136
|
+
};
|
|
137
|
+
}, []);
|
|
138
|
+
|
|
139
|
+
return <h1>Hello World!</h1>;
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 3. Register Scoped Shortcut
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
import React, { useEffect, useRef } from 'react';
|
|
147
|
+
import {
|
|
148
|
+
ReactShortcutProvider,
|
|
149
|
+
useShortcut,
|
|
150
|
+
} from '@rocketc/react-use-shortcuts';
|
|
151
|
+
|
|
152
|
+
function App() {
|
|
153
|
+
return (
|
|
154
|
+
<div id="root">
|
|
155
|
+
<ReactShortcutProvider options={{ auto: false }}>
|
|
156
|
+
<Main />
|
|
157
|
+
</ReactShortcutProvider>
|
|
158
|
+
<ReactShortcutProvider options={{ auto: false }}>
|
|
159
|
+
<Main />
|
|
160
|
+
<Main />
|
|
161
|
+
</ReactShortcutProvider>
|
|
162
|
+
</div>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function Main() {
|
|
167
|
+
const { registerShortcut, unregisterShortcut, attachElement } = useShortcut();
|
|
168
|
+
|
|
169
|
+
const root = useRef<HTMLDivElement>(null);
|
|
170
|
+
|
|
171
|
+
useEffect(() => {
|
|
172
|
+
if (root.current) {
|
|
173
|
+
return attachElement(root.current);
|
|
174
|
+
}
|
|
175
|
+
}, []);
|
|
176
|
+
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
registerShortcut('Ctrl+a', (event) => {
|
|
179
|
+
console.log('You pressed Ctrl and A');
|
|
180
|
+
});
|
|
181
|
+
return () => {
|
|
182
|
+
unregisterShortcut('Ctrl+a');
|
|
183
|
+
};
|
|
184
|
+
}, []);
|
|
185
|
+
|
|
186
|
+
return (
|
|
187
|
+
<h1 ref={root} tabIndex={-1}>
|
|
188
|
+
Hello World!
|
|
189
|
+
</h1>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
‼️ **Important**: Set element `tabIndex` property to `-1` to make the element focusable. Scoped shortcuts will not work without this.
|
|
195
|
+
|
|
196
|
+
### 4. Loose Mode
|
|
197
|
+
|
|
198
|
+
`@rocketc/react-use-shortcuts` works in strict mode by default (`strict: true`). Set `strict: false` to enable loose mode. This only affects the `getCurrentKeyPressed` API.
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
import React, { useEffect } from 'react';
|
|
202
|
+
import {
|
|
203
|
+
ReactShortcutProvider,
|
|
204
|
+
useShortcut,
|
|
205
|
+
} from '@rocketc/react-use-shortcuts';
|
|
206
|
+
|
|
207
|
+
function App() {
|
|
208
|
+
return (
|
|
209
|
+
<ReactShortcutProvider options={{ strict: false }}>
|
|
210
|
+
<Main />
|
|
211
|
+
</ReactShortcutProvider>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function Main() {
|
|
216
|
+
const { onKeyPressedChanged, getCurrentKeyPressed } = useShortcut();
|
|
217
|
+
|
|
218
|
+
useEffect(() => {
|
|
219
|
+
return onKeyPressedChanged((event) => {
|
|
220
|
+
// If you pressed ControlLeft and A:
|
|
221
|
+
// - strict mode: prints 'ControlLeft+A'
|
|
222
|
+
// - loose mode: prints 'Ctrl+A'
|
|
223
|
+
console.log(getCurrentKeyPressed());
|
|
224
|
+
// event.detail indicates the event type: 'keydown' or 'keyup'
|
|
225
|
+
console.log('Event type:', event.detail);
|
|
226
|
+
});
|
|
227
|
+
}, []);
|
|
228
|
+
|
|
229
|
+
return <h1>Hello World!</h1>;
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 5. Dynamic Enable/Disable Shortcut
|
|
234
|
+
|
|
235
|
+
```tsx
|
|
236
|
+
import React, { useEffect, useCallback, useState } from 'react';
|
|
237
|
+
import {
|
|
238
|
+
ReactShortcutProvider,
|
|
239
|
+
useShortcut,
|
|
240
|
+
} from '@rocketc/react-use-shortcuts';
|
|
241
|
+
|
|
242
|
+
function App() {
|
|
243
|
+
return (
|
|
244
|
+
<ReactShortcutProvider>
|
|
245
|
+
<Main />
|
|
246
|
+
</ReactShortcutProvider>
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function Main() {
|
|
251
|
+
const {
|
|
252
|
+
registerShortcut,
|
|
253
|
+
unregisterShortcut,
|
|
254
|
+
enableShortcut,
|
|
255
|
+
disableShortcut,
|
|
256
|
+
} = useShortcut();
|
|
257
|
+
const [enable, setEnable] = useState<boolean>(true);
|
|
258
|
+
|
|
259
|
+
const handleClick = useCallback(() => {
|
|
260
|
+
setEnable((prev) => {
|
|
261
|
+
if (prev) {
|
|
262
|
+
disableShortcut('Ctrl+a');
|
|
263
|
+
} else {
|
|
264
|
+
enableShortcut('Ctrl+a');
|
|
265
|
+
}
|
|
266
|
+
return !prev;
|
|
267
|
+
});
|
|
268
|
+
}, []);
|
|
269
|
+
|
|
270
|
+
useEffect(() => {
|
|
271
|
+
registerShortcut('Ctrl+a', (event) => {
|
|
272
|
+
console.log('You pressed Control and A');
|
|
273
|
+
});
|
|
274
|
+
return () => {
|
|
275
|
+
unregisterShortcut('Ctrl+a');
|
|
276
|
+
};
|
|
277
|
+
}, []);
|
|
278
|
+
|
|
279
|
+
return <button onClick={handleClick}>{enable ? 'disable' : 'enable'}</button>;
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### 6. Multiple Callbacks for the Same Shortcut
|
|
284
|
+
|
|
285
|
+
You can register multiple callbacks for the same accelerator and manage them individually:
|
|
286
|
+
|
|
287
|
+
```tsx
|
|
288
|
+
import React, { useEffect, useCallback } from 'react';
|
|
289
|
+
import {
|
|
290
|
+
ReactShortcutProvider,
|
|
291
|
+
useShortcut,
|
|
292
|
+
} from '@rocketc/react-use-shortcuts';
|
|
293
|
+
|
|
294
|
+
function App() {
|
|
295
|
+
return (
|
|
296
|
+
<ReactShortcutProvider>
|
|
297
|
+
<Main />
|
|
298
|
+
</ReactShortcutProvider>
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function Main() {
|
|
303
|
+
const {
|
|
304
|
+
registerShortcut,
|
|
305
|
+
unregisterShortcut,
|
|
306
|
+
enableShortcut,
|
|
307
|
+
disableShortcut,
|
|
308
|
+
} = useShortcut();
|
|
309
|
+
|
|
310
|
+
useEffect(() => {
|
|
311
|
+
const handler1 = () => console.log('Handler 1');
|
|
312
|
+
const handler2 = () => console.log('Handler 2');
|
|
313
|
+
|
|
314
|
+
// Register multiple handlers for the same shortcut
|
|
315
|
+
registerShortcut('Ctrl+a', handler1);
|
|
316
|
+
registerShortcut('Ctrl+a', handler2);
|
|
317
|
+
|
|
318
|
+
// Disable only handler1
|
|
319
|
+
disableShortcut('Ctrl+a', handler1);
|
|
320
|
+
|
|
321
|
+
// Enable handler1 again
|
|
322
|
+
enableShortcut('Ctrl+a', handler1);
|
|
323
|
+
|
|
324
|
+
// Unregister only handler1
|
|
325
|
+
unregisterShortcut('Ctrl+a', handler1);
|
|
326
|
+
|
|
327
|
+
return () => {
|
|
328
|
+
// Unregister all handlers for Ctrl+a
|
|
329
|
+
unregisterShortcut('Ctrl+a');
|
|
330
|
+
};
|
|
331
|
+
}, []);
|
|
332
|
+
|
|
333
|
+
return <h1>Hello World!</h1>;
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### 7. Custom Event Filter
|
|
338
|
+
|
|
339
|
+
The default filter automatically filters out:
|
|
340
|
+
|
|
341
|
+
- `event.repeat` (key repeat events)
|
|
342
|
+
- `event.isComposing` (IME composition events, e.g., when typing Chinese/Japanese/Korean)
|
|
343
|
+
- Events from `INPUT`, `TEXTAREA`, `SELECT` elements
|
|
344
|
+
- Events from `contentEditable` elements
|
|
345
|
+
|
|
346
|
+
You can provide a custom filter to override this behavior:
|
|
347
|
+
|
|
348
|
+
```tsx
|
|
349
|
+
import React, { useEffect } from 'react';
|
|
350
|
+
import {
|
|
351
|
+
ReactShortcutProvider,
|
|
352
|
+
useShortcut,
|
|
353
|
+
} from '@rocketc/react-use-shortcuts';
|
|
354
|
+
|
|
355
|
+
function App() {
|
|
356
|
+
return (
|
|
357
|
+
<ReactShortcutProvider
|
|
358
|
+
options={{
|
|
359
|
+
filter: (event) => (event.target as HTMLElement)?.tagName !== 'INPUT',
|
|
360
|
+
}}
|
|
361
|
+
>
|
|
362
|
+
<Main />
|
|
363
|
+
</ReactShortcutProvider>
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function Main() {
|
|
368
|
+
const { registerShortcut, unregisterShortcut } = useShortcut();
|
|
369
|
+
|
|
370
|
+
useEffect(() => {
|
|
371
|
+
registerShortcut('Ctrl+a', (event) => {
|
|
372
|
+
console.log('You pressed Control and A');
|
|
373
|
+
});
|
|
374
|
+
return () => {
|
|
375
|
+
unregisterShortcut('Ctrl+a');
|
|
376
|
+
};
|
|
377
|
+
}, []);
|
|
378
|
+
|
|
379
|
+
return (
|
|
380
|
+
<div>
|
|
381
|
+
<input />
|
|
382
|
+
</div>
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### 8. Custom Key Aliases
|
|
388
|
+
|
|
389
|
+
You can define custom key name aliases to use in your shortcuts:
|
|
390
|
+
|
|
391
|
+
```tsx
|
|
392
|
+
import React, { useEffect } from 'react';
|
|
393
|
+
import {
|
|
394
|
+
ReactShortcutProvider,
|
|
395
|
+
useShortcut,
|
|
396
|
+
} from '@rocketc/react-use-shortcuts';
|
|
397
|
+
|
|
398
|
+
function App() {
|
|
399
|
+
return (
|
|
400
|
+
<ReactShortcutProvider
|
|
401
|
+
options={{
|
|
402
|
+
alias: {
|
|
403
|
+
Save: 'Ctrl',
|
|
404
|
+
I: 'i',
|
|
405
|
+
},
|
|
406
|
+
}}
|
|
407
|
+
>
|
|
408
|
+
<Main />
|
|
409
|
+
</ReactShortcutProvider>
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function Main() {
|
|
414
|
+
const { registerShortcut, unregisterShortcut } = useShortcut();
|
|
415
|
+
|
|
416
|
+
useEffect(() => {
|
|
417
|
+
// Use the custom alias 'Save' instead of 'Ctrl'
|
|
418
|
+
registerShortcut('Save+s', () => {
|
|
419
|
+
console.log('Save shortcut triggered');
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
return () => {
|
|
423
|
+
unregisterShortcut('Save+s');
|
|
424
|
+
};
|
|
425
|
+
}, []);
|
|
426
|
+
|
|
427
|
+
return <h1>Hello World!</h1>;
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### 9. Custom Debug Function
|
|
432
|
+
|
|
433
|
+
You can provide a custom debug function instead of using the default debug logger:
|
|
434
|
+
|
|
435
|
+
```tsx
|
|
436
|
+
import React, { useEffect } from 'react';
|
|
437
|
+
import {
|
|
438
|
+
ReactShortcutProvider,
|
|
439
|
+
useShortcut,
|
|
440
|
+
} from '@rocketc/react-use-shortcuts';
|
|
441
|
+
|
|
442
|
+
function App() {
|
|
443
|
+
return (
|
|
444
|
+
<ReactShortcutProvider
|
|
445
|
+
options={{
|
|
446
|
+
debug: (...args) => {
|
|
447
|
+
console.log('[Shortcut Debug]', ...args);
|
|
448
|
+
},
|
|
449
|
+
}}
|
|
450
|
+
>
|
|
451
|
+
<Main />
|
|
452
|
+
</ReactShortcutProvider>
|
|
453
|
+
);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
function Main() {
|
|
457
|
+
const { registerShortcut, unregisterShortcut } = useShortcut();
|
|
458
|
+
|
|
459
|
+
useEffect(() => {
|
|
460
|
+
registerShortcut('Ctrl+a', () => {
|
|
461
|
+
console.log('You pressed Control and A');
|
|
462
|
+
});
|
|
463
|
+
return () => {
|
|
464
|
+
unregisterShortcut('Ctrl+a');
|
|
465
|
+
};
|
|
466
|
+
}, []);
|
|
467
|
+
|
|
468
|
+
return <h1>Hello World!</h1>;
|
|
469
|
+
}
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
## API Reference
|
|
473
|
+
|
|
474
|
+
### `ReactShortcutProvider`
|
|
475
|
+
|
|
476
|
+
React Context Provider component. Wrap your app or component tree with this provider.
|
|
477
|
+
|
|
478
|
+
**Props:**
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
interface ReactShortcutProviderProps {
|
|
482
|
+
options?: ReactShortcutOptions;
|
|
483
|
+
children?: ReactNode;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
interface ReactShortcutOptions {
|
|
487
|
+
strict?: boolean; // Default: false (strict mode by default)
|
|
488
|
+
debug?: boolean | ((...args: any[]) => void); // Default: false
|
|
489
|
+
auto?: boolean; // Default: true
|
|
490
|
+
filter?: Filter;
|
|
491
|
+
alias?: Record<string, string>;
|
|
492
|
+
separator?: string; // Default: '+'
|
|
493
|
+
}
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### `useShortcut`
|
|
497
|
+
|
|
498
|
+
React Hook to access shortcut APIs.
|
|
499
|
+
|
|
500
|
+
**Returns:**
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
interface ReactShortcutContextValue {
|
|
504
|
+
registerShortcut(
|
|
505
|
+
accelerator: Accelerator,
|
|
506
|
+
callback: KeyboardEventListener,
|
|
507
|
+
): boolean;
|
|
508
|
+
unregisterShortcut(
|
|
509
|
+
accelerator: Accelerator,
|
|
510
|
+
cb?: KeyboardEventListener,
|
|
511
|
+
): boolean;
|
|
512
|
+
enableShortcut(accelerator: Accelerator, cb?: KeyboardEventListener): boolean;
|
|
513
|
+
disableShortcut(
|
|
514
|
+
accelerator: Accelerator,
|
|
515
|
+
cb?: KeyboardEventListener,
|
|
516
|
+
): boolean;
|
|
517
|
+
isShortcutRegistered(accelerator: Accelerator): boolean;
|
|
518
|
+
getCurrentKeyPressed(): Accelerator;
|
|
519
|
+
onKeyPressedChanged(listener: KeyPressedChangedEventListener): Dispose;
|
|
520
|
+
attachElement(ele: Window | HTMLElement): Dispose;
|
|
521
|
+
getOptions(): ReactShortcutOptions;
|
|
522
|
+
getShortcutRegisters(accelerator?: Accelerator): Array<ShortcutRegister>;
|
|
523
|
+
}
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### `acceleratorParser`
|
|
527
|
+
|
|
528
|
+
Utility object for parsing and validating accelerator strings. Re-exported from `@rocketc/shortcuts`.
|
|
529
|
+
|
|
530
|
+
```tsx
|
|
531
|
+
import { acceleratorParser } from '@rocketc/react-use-shortcuts';
|
|
532
|
+
|
|
533
|
+
// Validate accelerator
|
|
534
|
+
const isValid = acceleratorParser.validate('Ctrl+a');
|
|
535
|
+
|
|
536
|
+
// Convert to loose mode
|
|
537
|
+
const loose = acceleratorParser.convertAcceleratorToLooseMode('ControlLeft+a');
|
|
538
|
+
|
|
539
|
+
// Parse accelerator
|
|
540
|
+
const parsed = acceleratorParser.parse('Ctrl+Shift+a');
|
|
541
|
+
console.log(parsed); // ['Ctrl', 'Shift', 'a']
|
|
542
|
+
|
|
543
|
+
// Check if key code name is supported
|
|
544
|
+
const isSupported = acceleratorParser.isKeyCodeNameSupported('Ctrl');
|
|
545
|
+
console.log(isSupported); // true
|
|
546
|
+
|
|
547
|
+
// Check if accelerators match
|
|
548
|
+
const isMatched = acceleratorParser.isAcceleratorMatched(
|
|
549
|
+
'Ctrl+a',
|
|
550
|
+
'ControlLeft+KeyA',
|
|
551
|
+
);
|
|
552
|
+
console.log(isMatched); // true
|
|
553
|
+
|
|
554
|
+
// Get default separator
|
|
555
|
+
const separator = acceleratorParser.defaultSeparator;
|
|
556
|
+
console.log(separator); // '+'
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
For complete API documentation, see [`@rocketc/shortcuts`](../shortcuts/README.md#api-reference).
|
|
560
|
+
|
|
561
|
+
## Shortcut Match Rules
|
|
562
|
+
|
|
563
|
+
See the [Shortcut Match Rules section](../shortcuts/README.md#shortcut-match-rules) in `@rocketc/shortcuts` documentation.
|
|
564
|
+
|
|
565
|
+
## Browser Compatibility
|
|
566
|
+
|
|
567
|
+
- Chrome ≥ 48
|
|
568
|
+
- Firefox ≥ 38
|
|
569
|
+
- Safari ≥ 10.1
|
|
570
|
+
- Edge ≥ 79
|
|
571
|
+
|
|
572
|
+
## Core Library
|
|
573
|
+
|
|
574
|
+
This package is built on top of [`@rocketc/shortcuts`](../shortcuts/README.md), which provides the core shortcut functionality without React dependencies. If you need to use shortcuts in a non-React environment, use `@rocketc/shortcuts` directly.
|
|
575
|
+
|
|
576
|
+
## Alternatives
|
|
577
|
+
|
|
578
|
+
- [react-hotkeys-hook](https://www.npmjs.com/package/react-hotkeys-hook)
|
|
579
|
+
- [react-hot-keys](https://www.npmjs.com/package/react-hot-keys)
|
|
580
|
+
|
|
581
|
+
## Comparisons
|
|
582
|
+
|
|
583
|
+
| **Features** | **@rocketc/react-use-shortcuts** | **react-hotkeys-hook** | **react-hot-keys** |
|
|
584
|
+
| ------------------------------------------ | -------------------------------- | ---------------------- | ------------------ |
|
|
585
|
+
| Dynamic register | ✅ | ❌ | ❌ |
|
|
586
|
+
| Page scoped register | ✅ | ✅ | ❌ |
|
|
587
|
+
| Strict/Loose mode | ✅ | ❌ | ❌ |
|
|
588
|
+
| Dynamic enable/disable shortcut registered | ✅ | ✅ | ❌ |
|
|
589
|
+
| Normal key combinations | ❌ | ✅ | ✅ |
|
|
590
|
+
| Namespace | ❌ | ❌ | ✅ |
|
|
591
|
+
| Shortcuts validation | ✅ | ❌ | ❌ |
|
|
592
|
+
| Used React ≤ 18.0.0 | ❌ | ❌ | ✅ |
|
|
593
|
+
|
|
594
|
+
## License
|
|
595
|
+
|
|
596
|
+
Distributed under the MIT License. See `LICENSE` for more information.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Accelerator } from '@rocketc/shortcuts';
|
|
2
|
+
import { default as default_2 } from 'react';
|
|
3
|
+
import { Dispose } from '@rocketc/shortcuts';
|
|
4
|
+
import { Filter } from '@rocketc/shortcuts';
|
|
5
|
+
import { KeyboardEventListener } from '@rocketc/shortcuts';
|
|
6
|
+
import { KeyPressedChangedEventListener } from '@rocketc/shortcuts';
|
|
7
|
+
import { PropsWithChildren } from 'react';
|
|
8
|
+
import { ShortcutRegister } from '@rocketc/shortcuts';
|
|
9
|
+
|
|
10
|
+
declare interface ReactShortcutContextValue {
|
|
11
|
+
registerShortcut(accelerator: Accelerator, callback: KeyboardEventListener): boolean;
|
|
12
|
+
unregisterShortcut(accelerator: Accelerator, cb?: KeyboardEventListener): boolean;
|
|
13
|
+
enableShortcut(accelerator: Accelerator, cb?: KeyboardEventListener): boolean;
|
|
14
|
+
disableShortcut(accelerator: Accelerator, cb?: KeyboardEventListener): boolean;
|
|
15
|
+
isShortcutRegistered(accelerator: Accelerator): boolean;
|
|
16
|
+
getCurrentKeyPressed(): Accelerator;
|
|
17
|
+
onKeyPressedChanged(listener: KeyPressedChangedEventListener): Dispose;
|
|
18
|
+
attachElement(ele: Window | HTMLElement): Dispose;
|
|
19
|
+
getOptions(): ReactShortcutOptions;
|
|
20
|
+
getShortcutRegisters(accelerator?: Accelerator): Array<ShortcutRegister>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export declare interface ReactShortcutOptions {
|
|
24
|
+
separator?: string;
|
|
25
|
+
strict?: boolean;
|
|
26
|
+
debug?: boolean | ((...args: any[]) => void);
|
|
27
|
+
auto?: boolean;
|
|
28
|
+
filter?: Filter;
|
|
29
|
+
alias?: Record<string, string>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export declare const ReactShortcutProvider: {
|
|
33
|
+
(props: ReactShortcutProviderProps): default_2.JSX.Element;
|
|
34
|
+
displayName: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export declare type ReactShortcutProviderProps = PropsWithChildren<{
|
|
38
|
+
options?: ReactShortcutOptions;
|
|
39
|
+
}>;
|
|
40
|
+
|
|
41
|
+
export declare const useShortcut: () => ReactShortcutContextValue;
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
export * from "@rocketc/shortcuts";
|
|
45
|
+
|
|
46
|
+
export { }
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import React, { createContext, useRef, useMemo, useCallback, useEffect, useContext } from "react";
|
|
2
|
+
import { ShortcutRegistry } from "@rocketc/shortcuts";
|
|
3
|
+
export * from "@rocketc/shortcuts";
|
|
4
|
+
const defaultShortcutRegistry = new ShortcutRegistry({
|
|
5
|
+
strict: false,
|
|
6
|
+
// Default to loose mode
|
|
7
|
+
debug: false
|
|
8
|
+
});
|
|
9
|
+
let autoWindowDispose = null;
|
|
10
|
+
if (typeof window !== "undefined") {
|
|
11
|
+
autoWindowDispose = defaultShortcutRegistry.attachElement(window);
|
|
12
|
+
}
|
|
13
|
+
const createDefaultContextValue = () => {
|
|
14
|
+
return {
|
|
15
|
+
registerShortcut: defaultShortcutRegistry.registerShortcut.bind(
|
|
16
|
+
defaultShortcutRegistry
|
|
17
|
+
),
|
|
18
|
+
unregisterShortcut: defaultShortcutRegistry.unregisterShortcut.bind(
|
|
19
|
+
defaultShortcutRegistry
|
|
20
|
+
),
|
|
21
|
+
enableShortcut: defaultShortcutRegistry.enableShortcut.bind(
|
|
22
|
+
defaultShortcutRegistry
|
|
23
|
+
),
|
|
24
|
+
disableShortcut: defaultShortcutRegistry.disableShortcut.bind(
|
|
25
|
+
defaultShortcutRegistry
|
|
26
|
+
),
|
|
27
|
+
isShortcutRegistered: defaultShortcutRegistry.isShortcutRegistered.bind(
|
|
28
|
+
defaultShortcutRegistry
|
|
29
|
+
),
|
|
30
|
+
getCurrentKeyPressed: defaultShortcutRegistry.getCurrentKeyPressed.bind(
|
|
31
|
+
defaultShortcutRegistry
|
|
32
|
+
),
|
|
33
|
+
onKeyPressedChanged: defaultShortcutRegistry.onKeyPressedChanged.bind(
|
|
34
|
+
defaultShortcutRegistry
|
|
35
|
+
),
|
|
36
|
+
attachElement: (ele) => {
|
|
37
|
+
return defaultShortcutRegistry.attachElement(ele);
|
|
38
|
+
},
|
|
39
|
+
getOptions: () => {
|
|
40
|
+
const options = defaultShortcutRegistry.getOptions();
|
|
41
|
+
return {
|
|
42
|
+
strict: options.strict ?? false,
|
|
43
|
+
debug: options.debug ?? false,
|
|
44
|
+
auto: autoWindowDispose !== null,
|
|
45
|
+
filter: options.filter,
|
|
46
|
+
alias: options.alias,
|
|
47
|
+
separator: options.separator
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
getShortcutRegisters: defaultShortcutRegistry.getShortcutRegisters.bind(
|
|
51
|
+
defaultShortcutRegistry
|
|
52
|
+
)
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
const ReactShortcutContext = createContext(
|
|
56
|
+
createDefaultContextValue()
|
|
57
|
+
);
|
|
58
|
+
const ReactShortcutProvider = function ReactShortcutProvider2(props) {
|
|
59
|
+
const {
|
|
60
|
+
children,
|
|
61
|
+
options: {
|
|
62
|
+
strict = false,
|
|
63
|
+
debug = false,
|
|
64
|
+
auto = true,
|
|
65
|
+
filter,
|
|
66
|
+
separator,
|
|
67
|
+
alias
|
|
68
|
+
} = {}
|
|
69
|
+
} = props;
|
|
70
|
+
const autoRef = useRef(auto);
|
|
71
|
+
autoRef.current = auto;
|
|
72
|
+
const shortcutRegistry = useRef(
|
|
73
|
+
new ShortcutRegistry({ strict, debug, filter, alias })
|
|
74
|
+
);
|
|
75
|
+
const staticsContextValue = useMemo(() => {
|
|
76
|
+
return {
|
|
77
|
+
getOptions: shortcutRegistry.current.getOptions.bind(
|
|
78
|
+
shortcutRegistry.current
|
|
79
|
+
),
|
|
80
|
+
getShortcutRegisters: shortcutRegistry.current.getShortcutRegisters.bind(
|
|
81
|
+
shortcutRegistry.current
|
|
82
|
+
),
|
|
83
|
+
registerShortcut: shortcutRegistry.current.registerShortcut.bind(
|
|
84
|
+
shortcutRegistry.current
|
|
85
|
+
),
|
|
86
|
+
unregisterShortcut: shortcutRegistry.current.unregisterShortcut.bind(
|
|
87
|
+
shortcutRegistry.current
|
|
88
|
+
),
|
|
89
|
+
enableShortcut: shortcutRegistry.current.enableShortcut.bind(
|
|
90
|
+
shortcutRegistry.current
|
|
91
|
+
),
|
|
92
|
+
disableShortcut: shortcutRegistry.current.disableShortcut.bind(
|
|
93
|
+
shortcutRegistry.current
|
|
94
|
+
),
|
|
95
|
+
isShortcutRegistered: shortcutRegistry.current.isShortcutRegistered.bind(
|
|
96
|
+
shortcutRegistry.current
|
|
97
|
+
),
|
|
98
|
+
getCurrentKeyPressed: shortcutRegistry.current.getCurrentKeyPressed.bind(
|
|
99
|
+
shortcutRegistry.current
|
|
100
|
+
),
|
|
101
|
+
onKeyPressedChanged: shortcutRegistry.current.onKeyPressedChanged.bind(
|
|
102
|
+
shortcutRegistry.current
|
|
103
|
+
)
|
|
104
|
+
};
|
|
105
|
+
}, []);
|
|
106
|
+
const attachElement = useCallback((ele) => {
|
|
107
|
+
if (autoRef.current) {
|
|
108
|
+
throw new Error("attachElement is not supported when auto is true");
|
|
109
|
+
}
|
|
110
|
+
return shortcutRegistry.current.attachElement(ele);
|
|
111
|
+
}, []);
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (auto) {
|
|
114
|
+
return shortcutRegistry.current.attachElement(window);
|
|
115
|
+
}
|
|
116
|
+
}, [auto]);
|
|
117
|
+
useEffect(() => {
|
|
118
|
+
shortcutRegistry.current.setOptions({
|
|
119
|
+
strict,
|
|
120
|
+
debug,
|
|
121
|
+
filter,
|
|
122
|
+
separator,
|
|
123
|
+
alias
|
|
124
|
+
});
|
|
125
|
+
}, [strict, debug, filter, separator, alias]);
|
|
126
|
+
return /* @__PURE__ */ React.createElement(
|
|
127
|
+
ReactShortcutContext.Provider,
|
|
128
|
+
{
|
|
129
|
+
value: {
|
|
130
|
+
...staticsContextValue,
|
|
131
|
+
attachElement
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
children
|
|
135
|
+
);
|
|
136
|
+
};
|
|
137
|
+
ReactShortcutProvider.displayName = "ReactShortcutProvider";
|
|
138
|
+
const useShortcut = () => {
|
|
139
|
+
return useContext(ReactShortcutContext);
|
|
140
|
+
};
|
|
141
|
+
export {
|
|
142
|
+
ReactShortcutProvider,
|
|
143
|
+
useShortcut
|
|
144
|
+
};
|
|
145
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/shortcut-context.ts","../src/shortcut-provider.tsx","../src/use-shortcut.ts"],"sourcesContent":["import { createContext } from 'react';\nimport { ShortcutRegistry } from '@rocketc/shortcuts';\nimport type { ReactShortcutOptions } from './shortcut-provider';\nimport type {\n Accelerator,\n ShortcutRegister,\n KeyboardEventListener,\n Dispose,\n KeyPressedChangedEventListener,\n} from '@rocketc/shortcuts';\n\nexport interface ReactShortcutContextValue {\n registerShortcut(\n accelerator: Accelerator,\n callback: KeyboardEventListener,\n ): boolean;\n unregisterShortcut(\n accelerator: Accelerator,\n cb?: KeyboardEventListener,\n ): boolean;\n enableShortcut(accelerator: Accelerator, cb?: KeyboardEventListener): boolean;\n disableShortcut(\n accelerator: Accelerator,\n cb?: KeyboardEventListener,\n ): boolean;\n isShortcutRegistered(accelerator: Accelerator): boolean;\n getCurrentKeyPressed(): Accelerator;\n onKeyPressedChanged(listener: KeyPressedChangedEventListener): Dispose;\n attachElement(ele: Window | HTMLElement): Dispose;\n getOptions(): ReactShortcutOptions;\n getShortcutRegisters(accelerator?: Accelerator): Array<ShortcutRegister>;\n}\n\n// Create a default ShortcutRegistry instance for use without Provider\nconst defaultShortcutRegistry = new ShortcutRegistry({\n strict: false, // Default to loose mode\n debug: false,\n});\n\n// Track the dispose function for auto-attached window\n// Since attachElement returns different dispose functions each time,\n// we only track the one created by auto option\nlet autoWindowDispose: Dispose | null = null;\n\n// Auto-attach to window by default\nif (typeof window !== 'undefined') {\n autoWindowDispose = defaultShortcutRegistry.attachElement(window);\n}\n\n// Create default context value\nconst createDefaultContextValue = (): ReactShortcutContextValue => {\n return {\n registerShortcut: defaultShortcutRegistry.registerShortcut.bind(\n defaultShortcutRegistry,\n ),\n unregisterShortcut: defaultShortcutRegistry.unregisterShortcut.bind(\n defaultShortcutRegistry,\n ),\n enableShortcut: defaultShortcutRegistry.enableShortcut.bind(\n defaultShortcutRegistry,\n ),\n disableShortcut: defaultShortcutRegistry.disableShortcut.bind(\n defaultShortcutRegistry,\n ),\n isShortcutRegistered: defaultShortcutRegistry.isShortcutRegistered.bind(\n defaultShortcutRegistry,\n ),\n getCurrentKeyPressed: defaultShortcutRegistry.getCurrentKeyPressed.bind(\n defaultShortcutRegistry,\n ),\n onKeyPressedChanged: defaultShortcutRegistry.onKeyPressedChanged.bind(\n defaultShortcutRegistry,\n ),\n attachElement: (ele: Window | HTMLElement) => {\n // Simply delegate to the registry\n // The registry handles reference counting internally\n return defaultShortcutRegistry.attachElement(ele);\n },\n getOptions: () => {\n const options = defaultShortcutRegistry.getOptions();\n return {\n strict: options.strict ?? false,\n debug: options.debug ?? false,\n auto: autoWindowDispose !== null,\n filter: options.filter,\n alias: options.alias,\n separator: options.separator,\n };\n },\n getShortcutRegisters: defaultShortcutRegistry.getShortcutRegisters.bind(\n defaultShortcutRegistry,\n ),\n };\n};\n\nexport const ReactShortcutContext = createContext<ReactShortcutContextValue>(\n createDefaultContextValue(),\n);\n","/* eslint-disable react-hooks/refs */\nimport React, {\n useEffect,\n useMemo,\n useRef,\n useCallback,\n type PropsWithChildren,\n} from 'react';\nimport {\n ReactShortcutContext,\n type ReactShortcutContextValue,\n} from './shortcut-context';\nimport { ShortcutRegistry, type Filter } from '@rocketc/shortcuts';\n\nexport interface ReactShortcutOptions {\n separator?: string;\n strict?: boolean;\n debug?: boolean | ((...args: any[]) => void);\n auto?: boolean;\n filter?: Filter;\n alias?: Record<string, string>;\n}\n\nexport type ReactShortcutProviderProps = PropsWithChildren<{\n options?: ReactShortcutOptions;\n}>;\n\nconst ReactShortcutProvider = function ReactShortcutProvider(\n props: ReactShortcutProviderProps,\n) {\n const {\n children,\n options: {\n strict = false,\n debug = false,\n auto = true,\n filter,\n separator,\n alias,\n } = {},\n } = props;\n\n const autoRef = useRef(auto);\n autoRef.current = auto;\n\n const shortcutRegistry = useRef<ShortcutRegistry>(\n new ShortcutRegistry({ strict, debug, filter, alias }),\n );\n\n const staticsContextValue = useMemo<\n Omit<ReactShortcutContextValue, 'attachElement'>\n >(() => {\n return {\n getOptions: shortcutRegistry.current.getOptions.bind(\n shortcutRegistry.current,\n ),\n getShortcutRegisters: shortcutRegistry.current.getShortcutRegisters.bind(\n shortcutRegistry.current,\n ),\n registerShortcut: shortcutRegistry.current.registerShortcut.bind(\n shortcutRegistry.current,\n ),\n unregisterShortcut: shortcutRegistry.current.unregisterShortcut.bind(\n shortcutRegistry.current,\n ),\n enableShortcut: shortcutRegistry.current.enableShortcut.bind(\n shortcutRegistry.current,\n ),\n disableShortcut: shortcutRegistry.current.disableShortcut.bind(\n shortcutRegistry.current,\n ),\n isShortcutRegistered: shortcutRegistry.current.isShortcutRegistered.bind(\n shortcutRegistry.current,\n ),\n getCurrentKeyPressed: shortcutRegistry.current.getCurrentKeyPressed.bind(\n shortcutRegistry.current,\n ),\n onKeyPressedChanged: shortcutRegistry.current.onKeyPressedChanged.bind(\n shortcutRegistry.current,\n ),\n };\n }, []);\n\n const attachElement = useCallback((ele: Window | HTMLElement) => {\n if (autoRef.current) {\n throw new Error('attachElement is not supported when auto is true');\n }\n return shortcutRegistry.current.attachElement(ele);\n }, []);\n\n useEffect(() => {\n if (auto) {\n return shortcutRegistry.current.attachElement(window);\n }\n }, [auto]);\n\n useEffect(() => {\n shortcutRegistry.current.setOptions({\n strict,\n debug,\n filter,\n separator,\n alias,\n });\n }, [strict, debug, filter, separator, alias]);\n\n return (\n <ReactShortcutContext.Provider\n value={{\n ...staticsContextValue,\n attachElement,\n }}\n >\n {children}\n </ReactShortcutContext.Provider>\n );\n};\n\nReactShortcutProvider.displayName = 'ReactShortcutProvider';\n\nexport default ReactShortcutProvider;\n","import { useContext } from 'react';\nimport {\n ReactShortcutContext,\n type ReactShortcutContextValue,\n} from './shortcut-context';\n\nconst useShortcut = () => {\n return useContext<ReactShortcutContextValue>(ReactShortcutContext);\n};\n\nexport default useShortcut;\n"],"names":["ReactShortcutProvider"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rocketc/react-use-shortcuts",
|
|
3
|
+
"version": "0.0.1-alpha.10",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "a full react shortcut solution",
|
|
6
|
+
"files": [
|
|
7
|
+
"LICENSE",
|
|
8
|
+
"README.md",
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/chenfq95/rocketc.git",
|
|
21
|
+
"directory": "packages/libs/react-use-shortcuts"
|
|
22
|
+
},
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"keywords": [
|
|
25
|
+
"react",
|
|
26
|
+
"shortcut"
|
|
27
|
+
],
|
|
28
|
+
"author": "chenfq95 <chenfq95@foxmail.com>",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
32
|
+
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@rocketc/shortcuts": "0.0.1-alpha.4"
|
|
36
|
+
}
|
|
37
|
+
}
|