Skip to content

Commit

Permalink
Extend API to allow event listener options
Browse files Browse the repository at this point in the history
  • Loading branch information
reecelucas committed Aug 24, 2020
1 parent feb66b0 commit ba76146
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 51 deletions.
34 changes: 25 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,36 @@ All hotkey combinations must use valid `KeyBoardEvent` `"key"` values. A full li
```jsx
// Single keys
useHotkeys('Escape', () => {
console.log('some action');
console.log('Some action');
});

useHotkeys('F7', () => {
console.log('some action');
console.log('Some action');
});

// Modifier combinations
useHotkeys('Meta+Shift+z', () => {
console.log('some action');
console.log('Some action');
});

// Key sequences
useHotkeys('w s d', () => {
console.log('some action');
console.log('Some action');
});

useHotkeys('w " " d', () => {
// space key in sequence (`w ' ' d` also works)
console.log('some action');
console.log('Some action');
});

// Multiple key combinations mapped to the same callback
useHotkeys(['Control+z', 'Meta+z'], () => {
console.log('some action');
console.log('Some action');
});

useHotkeys(['a', 'Meta+z', 'w s d'], () => {
console.log('some action');
});
console.log('Some action');
})
```

The following patterns are **not** supported:
Expand All @@ -69,6 +69,18 @@ useHotkeys('Control+z i d', () => {
});
```

You can pass `AddEventListenerOptions` if you need to listen for `keydown` events in the capturing phase:

```jsx
useHotkeys('Escape', () => {
console.log('Some action');
}, true);

useHotkeys('Escape', () => {
console.log('Some action');
}, { capture: true });
```

If you find a use case where the API is too restrictive you can use the escape hatch to perform whatever custom logic you need:

```jsx
Expand All @@ -84,7 +96,11 @@ useHotkeys('*', event => {
## Call Signature

```ts
useHotkeys(hotkeys: string | string[], callback: (event: KeyboardEvent) => void);
useHotkeys(
hotkeys: string | string[],
callback: (event: KeyboardEvent) => void,
eventListenerOptions?: boolean | AddEventListenerOptions
) => void;
```

## Tests
Expand Down
51 changes: 29 additions & 22 deletions src/__stories__/index.story.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,41 @@
import { text, withKnobs } from '@storybook/addon-knobs';
import { withKnobs } from '@storybook/addon-knobs';
import { storiesOf } from '@storybook/react';
import * as React from 'react';
import useHotkeys from '../index';
import usePrevious from './utils/hooks/usePrevious';

const Basic = ({ hotkey }: { hotkey: string }) => {
const [keyPressed, setKeyPressed] = React.useState(false);
const prevHotkey = usePrevious(hotkey);
const Basic: React.FC<{ hotkey: string }> = ({ hotkey }) => {
useHotkeys(hotkey, () => {
alert(`${hotkey} pressed!`);
});

return <div>Press {hotkey}</div>;
};

React.useEffect(() => {
if (hotkey !== prevHotkey) {
setKeyPressed(false);
}
}, [hotkey]);
const EventCapture = () => {
useHotkeys(
'Escape',
() => {
alert('Escape pressed: capturing phase');
},
true
);

useHotkeys(hotkey, event => {
event.preventDefault();
setKeyPressed(true);
return <Basic hotkey={'Escape'} />;
};

const EscapeHatch = () => {
useHotkeys('*', (event: KeyboardEvent) => {
alert(`${event.key} pressed!`);
});

return (
<div>
<span>Hotkey selected:</span> <strong>{hotkey}</strong>
<br />
<span>Hotkey pressed: {keyPressed ? 'TRUE' : 'FALSE'}</span>
</div>
);
return <p>Press any key</p>;
};

storiesOf('useHotkeys', module)
.addDecorator(withKnobs)
.add('Core API', () => <Basic hotkey={text('Hotkeys', 'Escape')} />)
.add('Escape hatch', () => <Basic hotkey={'*'} />);
.add('Basic', () => <Basic hotkey={'Escape'} />)
.add('Modifier combination', () => <Basic hotkey={'Meta+Shift+z'} />)
.add('Key sequences', () => <Basic hotkey={'j o b'} />)
.add('Space in sequence', () => <Basic hotkey={'w " " d'} />)
.add('Event listener options', () => <EventCapture />)
.add('Escape hatch', () => <EscapeHatch />);
16 changes: 0 additions & 16 deletions src/__stories__/utils/hooks/usePrevious.ts

This file was deleted.

9 changes: 5 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ const ESCAPE_HATCH_KEY = '*';

const useHotkeys = (
hotkeys: string | string[],
callback: (event: KeyboardEvent) => void
callback: (event: KeyboardEvent) => void,
eventListenerOptions?: boolean | AddEventListenerOptions
) => {
const hotkeysArray: string[][] = useMemo(
() =>
Expand Down Expand Up @@ -116,12 +117,12 @@ const useHotkeys = (
});
};

window.addEventListener('keydown', onKeydown);
window.addEventListener('keydown', onKeydown, eventListenerOptions);

return () => {
window.removeEventListener('keydown', onKeydown);
window.removeEventListener('keydown', onKeydown, eventListenerOptions);
};
}, [hotkeysArray, callback]);
}, [hotkeysArray, callback, eventListenerOptions]);
};

export default useHotkeys;

0 comments on commit ba76146

Please sign in to comment.