Gathering detailed insights and metrics for reakeys
Gathering detailed insights and metrics for reakeys
Gathering detailed insights and metrics for reakeys
Gathering detailed insights and metrics for reakeys
npm install reakeys
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
66 Stars
131 Commits
11 Forks
5 Watching
7 Branches
7 Contributors
Updated on 13 Nov 2024
Minified
Minified + Gzipped
TypeScript (96.44%)
JavaScript (3.18%)
Shell (0.38%)
Cumulative downloads
Total Downloads
Last day
9.2%
3,666
Compared to previous day
Last week
1.9%
18,955
Compared to previous week
Last month
9.9%
87,175
Compared to previous month
Last year
13.4%
770,446
Compared to previous year
1
38
Install via NPM:
yarn add reakeys
Then in your component, just add the useHotkeys
hook
and specify your keys like:
1import React, { FC } from 'react'; 2import { useHotkeys } from 'reakeys'; 3 4export const YourComponent: FC = () => { 5 useHotkeys([ 6 { 7 name: 'Dashboard', 8 keys: 'mod+shift+d', 9 category: 'Navigation', 10 callback: event => { 11 event.preventDefault(); 12 history.push('/dashboard'); 13 } 14 } 15 ]); 16};
Below are the options you can set in the hook array:
1type HotkeyShortcuts = { 2 name: string; 3 category?: string; 4 description?: string; 5 keys: string | string[]; 6 ref?: any; 7 hidden?: boolean; 8 disabled?: boolean; 9 callback: (e: ExtendedKeyboardEvent, combo: string) => void; 10 action?: 'keypress'| 'keydown'| 'keyup'; 11};
You can also get all the hotkeys that are registered by just
calling the useHotkeys
hook and it will return the current
hotkeys.
1const hotkeys = useHotkeys();
This is useful for creating a dialog to present the user with all the options. Below is an example of how to make a dialog using reablocks:
1import React, { useState, FC, useCallback, useMemo } from 'react'; 2import { Dialog } from 'reablocks'; 3import { useHotkeys, getHotkeyText } from 'reakeys'; 4import groupBy from 'lodash/groupBy'; 5import sortBy from 'lodash/sortBy'; 6 7export const HotkeyCombos: FC = () => { 8 // useHotkeys returns the same object if the hotkeys haven't changed, meaning 9 // that you can use useMemo to avoid expensive recalculation in that case. 10 // 11 // Note that the object will change if another component passes a different 12 // object to their useHotkeys, even if that component doesn't actually change 13 // anything. In React <18, it will cause two re-renders in a row. 14 // 15 // There is another long comment at the bottom of this example explaining why 16 // useMemo is important. 17 18 const hotkeys = useHotkeys(); 19 const categories = useMemo(() => groupBy(hotkeys, 'category'), [hotkeys]); 20 21 const sorted = useMemo(() => Object.keys(categories).reduce((prev, cur) => { 22 const category = sortBy(categories[cur], 'name'); 23 const label = cur === 'undefined' ? 'General' : cur; 24 25 return { 26 ...prev, 27 [label]: category.filter(k => !k.hidden) 28 }; 29 }, {}), [categories]); 30 31 const { General, ...rest } = sorted as any; 32 const others = sortBy(Object.keys(rest || {})); 33 34 const renderKeyCode = useCallback(keyCode => { 35 const wrapped = Array.isArray(keyCode) ? keyCode : [keyCode]; 36 const formatted = wrapped.map(k => getHotkeyText(k)); 37 38 return ( 39 <div className={css.keyComboContainer}> 40 {formatted.map((k, i) => ( 41 <kbd key={i} className={css.keyCombo}> 42 {k} 43 </kbd> 44 ))} 45 </div> 46 ); 47 }, []); 48 49 const renderGroups = useCallback( 50 group => { 51 if (!sorted[group]) { 52 return null; 53 } 54 55 return ( 56 <div key={group}> 57 <h3>{group}</h3> 58 <ul className={css.list}> 59 {sorted[group].map(kk => ( 60 <li key={kk.name} className={css.listItem}> 61 <label>{kk.name}</label> 62 {renderKeyCode(kk.keys)} 63 {kk.description && <p>{kk.description}</p>} 64 </li> 65 ))} 66 </ul> 67 </div> 68 ); 69 }, 70 [renderKeyCode, sorted] 71 ); 72 73 return ( 74 <div className={css.groups}> 75 {renderGroups('General')} 76 {others.map(renderGroups)} 77 </div> 78 ); 79}; 80 81export const HotkeyDialog: FC = () => { 82 const [visible, setVisible] = useState<boolean>(false); 83 const openDialog = useCallback(() => setVisible(true), [setVisible]); 84 const closeDialog = useCallback(() => setVisible(false), [setVisible]); 85 86 // If your hotkeys haven't changed, it's important to provide the same object 87 // to useHotkeys, or else it will remove and replace your hotkeys. 88 // 89 // That isn't always a bad thing, and works perfectly fine, but it would cause 90 // unnecessary updates if other components also call useHotkeys() to retrieve 91 // the list of hotkeys, because this component would update it every render. 92 // 93 // Ideally, you should only change the object passed to useHotkeys when the 94 // actual hotkeys have changed (name for instance, when using i18n). 95 // useMemo is good for this. 96 97 useHotkeys(useMemo(() => [ 98 { 99 name: 'Hotkey Dialog', 100 keys: 'SHIFT+?', 101 hidden: true, 102 callback: openDialog 103 } 104 ], [openDialog])); 105 106 const combosRenderer = useCallback(() => <HotkeyCombos />, [HotkeyCombos]); 107 108 return ( 109 <Dialog 110 size="800px" 111 header="Hotkeys" 112 open={visible} 113 onClose={closeDialog} 114 > 115 {combosRenderer} 116 </Dialog> 117 ); 118};
You can also get a formatted version of the hotkey combo text:
1import { getHotkeyText } from 'reakeys'; 2 3getHotkeyText('mod+shift+a'); //=> '⌘+⇧+a'
If you want to run reakeys locally, its super easy!
yarn install
yarn start
Thanks to all our contributors!
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
Found 2/15 approved changesets -- score normalized to 1
Reason
dependency not pinned by hash detected -- score normalized to 1
Details
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
29 existing vulnerabilities detected
Details
Score
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More