# react-shortcuts

> React shortcuts

Latest version **2.1.0** (published 2019-12-10) · MIT license · 0 weekly downloads

## Install

```sh
npm install react-shortcuts
pnpm add react-shortcuts
yarn add react-shortcuts
bun add react-shortcuts
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.1.0 |
| Published | 2019-12-10 |
| First published | 2015-08-21 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 6 |
| Unpacked size | 29.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 327 |
| Maintainers | petrbrzek |
| Keywords | react, react-component, keyboard, shortcuts, mousetrap |

## Links

- npm: https://www.npmjs.com/package/react-shortcuts
- Repository: https://github.com/avocode/react-shortcuts
- Homepage: https://github.com/avocode/react-shortcuts#readme
- Issues: http://github.com/avocode/react-shortcuts/issues
- npm.io page: https://npm.io/package/react-shortcuts

## Dependencies (6)

- [events](https://npm.io/package/events.md) ^1.0.2
- [platform](https://npm.io/package/platform.md) ^1.3.0
- [combokeys](https://npm.io/package/combokeys.md) ^3.0.1
- [invariant](https://npm.io/package/invariant.md) ^2.1.0
- [prop-types](https://npm.io/package/prop-types.md) ^15.5.8
- [just-reduce-object](https://npm.io/package/just-reduce-object.md) ^1.0.3

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 2.1.0 (latest) — 2019-12-10
- 2.0.1 — 2019-03-13
- 1.6.3 — 2019-03-13
- 1.6.2 — 2018-04-23
- 2.0.0 — 2017-10-11
- 1.6.1 — 2017-08-28
- 1.6.0 — 2017-08-17
- 1.5.0 — 2017-05-12
- 1.4.0 — 2017-03-07
- 1.3.1 — 2016-11-22
- 1.3.0 — 2016-11-22
- 1.2.0 — 2016-11-22
- 1.1.0 — 2016-10-11
- 1.0.9 — 2016-10-10
- 1.0.8 — 2016-10-03
- … 28 more at https://npm.io/package/react-shortcuts/versions

## README

React Shortcuts
=========

**Manage keyboard shortcuts from one place.**

[![Build Status](https://travis-ci.org/avocode/react-shortcuts.svg)][travis]


Intro
------


Managing keyboard shortcuts can sometimes get messy. Or always, if not implemented the right way.

Real problems:

- You can't easily tell which shortcut is bound to which component
- You have to write a lot of boilerplate code (`addEventListeners`, `removeEventListeners`, ...)
- Memory leaks are a real problem if components don’t remove their listeners properly
- Platform specific shortcuts is another headache
- It's more difficult to implement feature like user-defined shortcuts
- You can't easily get allthe application shortcuts and display it (e.g. in settings)


**React shortcuts to the rescue!**
-----------

With `react-shortcuts` you can declaratively manage shortcuts for each one of your React components.

**Important parts of React Shortcuts:**

- Your `keymap` definition
- `ShortcutManager` which handles `keymap`
- `<Shortcut>` component for handling shortcuts


Try online demo
-------

[![Edit l40jjo48nl](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/l40jjo48nl)


Quick tour
----------


#### 1. `npm install react-shortcuts`


#### 2. **Define application shortcuts**

Create a new JS, Coffee, JSON or CSON file wherever you want (which probably is your project root). And define the shortcuts for your React component.

**Keymap definition**

```json
{
 "Namespace": {
   "Action": "Shortcut",
   "Action_2": ["Shortcut", "Shortcut"],
   "Action_3": {
     "osx": "Shortcut",
     "windows": ["Shortcut", "Shortcut"],
     "linux": "Shortcut",
     "other": "Shortcut"
   }
 }
}
```

- `Namespace` should ideally be the component’s `displayName`.
- `Action` describes what will be happening. For example `MODAL_CLOSE`.
- `Keyboard shortcut` can be a string, array of strings or an object which
  specifies platform differences (Windows, OSX, Linux, other). The
  shortcut may be composed of single keys (`a`, `6`,…), combinations
  (`command+shift+k`) or sequences (`up up down down left right left right B A`).

> **Combokeys** is used under the
  hood for handling the shortcuts. [Read more][mousetrap] about how you can
  specify keys.


##### Example `keymap` definition:


```javascript
export default {
  TODO_ITEM: {
    MOVE_LEFT: 'left',
    MOVE_RIGHT: 'right',
    MOVE_UP: ['up', 'w'],
    DELETE: {
      osx: ['command+backspace', 'k'],
      windows: 'delete',
      linux: 'delete',
    },
  },
}

```

Save this file as `keymap.[js|coffee|json|cson]` and require it into your main
file.

```javascript
import keymap from './keymap'
```

#### 3. Rise of the ShortcutsManager

Define your keymap in whichever supported format but in the end it must be an
object. `ShortcutsManager` can’t parse JSON and will certainly not be happy
about the situation.

```javascript
import keymap from './keymap'
import { ShortcutManager } from 'react-shortcuts'

const shortcutManager = new ShortcutManager(keymap)

// Or like this

const shortcutManager = new ShortcutManager()
shortcutManager.setKeymap(keymap)
```

#### 4. Include `shortcutManager` into getChildContext of some parent component. So that `<shortcuts>` can receive it.

```javascript
class App extends React.Component {
  getChildContext() {
    return { shortcuts: shortcutManager }
  }
}

App.childContextTypes = {
  shortcuts: PropTypes.object.isRequired
}
```

#### 5. Require the <shortcuts> component

You need to require the component in the file you want to use shortcuts in.
For example `<TodoItem>`.

```javascript
import { Shortcuts } from `react-shortcuts`

class TodoItem extends React.Component {
  _handleShortcuts = (action, event) => {
    switch (action) {
      case 'MOVE_LEFT':
        console.log('moving left')
        break
      case 'MOVE_RIGHT':
        console.log('moving right')
        break
      case 'MOVE_UP':
        console.log('moving up')
        break
      case 'COPY':
        console.log('copying stuff')
        break
    }
  }

  render() {
    return (
      <Shortcuts
        name='TODO_ITEM'
        handler={this._handleShortcuts}
      >
        <div>Make something amazing today</div>
      </Shortcuts>
    )
  }
}
```

> The `<Shortcuts>` component creates a `<shortcuts>` element in HTML, binds
  listeners and adds tabIndex to the element so that it’s focusable.
  `_handleShortcuts` is invoked when some of the defined shortcuts fire.

## Custom props for `<Shortcuts>` component

- `handler`: func
  - callback function that will fire when a shortcut occurs
- `name`: string
  - The name of the namespace specified in keymap file
- `tabIndex`: number
  - Default is `-1`
- `className`: string
- `eventType`: string
  - Just for gourmets (keyup, keydown, keypress)
- `stopPropagation`: bool
- `preventDefault`: bool
- `targetNodeSelector`: DOM Node Selector like `body` or `.my-class`
  - Use this one with caution. It binds listeners to the provided string instead
  of the component.
- `global`: bool
  - Use this when you have some global app wide shortcuts like `CMD+Q`.
- `isolate`: bool
  - Use this when a child component has React's key handler (onKeyUp, onKeyPress, onKeyDown). Otherwise, React Shortcuts stops propagation of that event due to nature of event delegation that React uses internally.
- `alwaysFireHandler`: bool
  - Use this when you want events keep firing on the focused input elements. 


## Thanks, Atom


This library is inspired by [Atom Keymap].


[Atom Keymap]: https://github.com/atom/atom-keymap/
[travis]: https://travis-ci.org/avocode/react-shortcuts
[mousetrap]: https://craig.is/killing/mice
[keymaps]: https://github.com/atom/atom-keymap/

---
_Source: https://npm.io/package/react-shortcuts · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
