{"id":13422382,"url":"https://github.com/avocode/react-shortcuts","last_synced_at":"2025-04-08T04:14:53.754Z","repository":{"id":36839787,"uuid":"41146702","full_name":"avocode/react-shortcuts","owner":"avocode","description":"Manage keyboard shortcuts from one place","archived":false,"fork":false,"pushed_at":"2022-12-07T04:15:54.000Z","size":797,"stargazers_count":329,"open_issues_count":52,"forks_count":37,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-01T03:35:25.652Z","etag":null,"topics":["mousetrap","react-components","react-shortcuts","reactjs"],"latest_commit_sha":null,"homepage":"https://codesandbox.io/s/l40jjo48nl","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/avocode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-21T09:09:16.000Z","updated_at":"2025-02-04T20:05:01.000Z","dependencies_parsed_at":"2023-01-17T05:46:08.387Z","dependency_job_id":null,"html_url":"https://github.com/avocode/react-shortcuts","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avocode%2Freact-shortcuts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avocode%2Freact-shortcuts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avocode%2Freact-shortcuts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avocode%2Freact-shortcuts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avocode","download_url":"https://codeload.github.com/avocode/react-shortcuts/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247773719,"owners_count":20993639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mousetrap","react-components","react-shortcuts","reactjs"],"created_at":"2024-07-30T23:00:43.311Z","updated_at":"2025-04-08T04:14:53.727Z","avatar_url":"https://github.com/avocode.png","language":"JavaScript","readme":"React Shortcuts\n=========\n\n**Manage keyboard shortcuts from one place.**\n\n[![Build Status](https://travis-ci.org/avocode/react-shortcuts.svg)][travis]\n\n\nIntro\n------\n\n\nManaging keyboard shortcuts can sometimes get messy. Or always, if not implemented the right way.\n\nReal problems:\n\n- You can't easily tell which shortcut is bound to which component\n- You have to write a lot of boilerplate code (`addEventListeners`, `removeEventListeners`, ...)\n- Memory leaks are a real problem if components don’t remove their listeners properly\n- Platform specific shortcuts is another headache\n- It's more difficult to implement feature like user-defined shortcuts\n- You can't easily get allthe application shortcuts and display it (e.g. in settings)\n\n\n**React shortcuts to the rescue!**\n-----------\n\nWith `react-shortcuts` you can declaratively manage shortcuts for each one of your React components.\n\n**Important parts of React Shortcuts:**\n\n- Your `keymap` definition\n- `ShortcutManager` which handles `keymap`\n- `\u003cShortcut\u003e` component for handling shortcuts\n\n\nTry online demo\n-------\n\n[![Edit l40jjo48nl](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/l40jjo48nl)\n\n\nQuick tour\n----------\n\n\n#### 1. `npm install react-shortcuts`\n\n\n#### 2. **Define application shortcuts**\n\nCreate 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.\n\n**Keymap definition**\n\n```json\n{\n \"Namespace\": {\n   \"Action\": \"Shortcut\",\n   \"Action_2\": [\"Shortcut\", \"Shortcut\"],\n   \"Action_3\": {\n     \"osx\": \"Shortcut\",\n     \"windows\": [\"Shortcut\", \"Shortcut\"],\n     \"linux\": \"Shortcut\",\n     \"other\": \"Shortcut\"\n   }\n }\n}\n```\n\n- `Namespace` should ideally be the component’s `displayName`.\n- `Action` describes what will be happening. For example `MODAL_CLOSE`.\n- `Keyboard shortcut` can be a string, array of strings or an object which\n  specifies platform differences (Windows, OSX, Linux, other). The\n  shortcut may be composed of single keys (`a`, `6`,…), combinations\n  (`command+shift+k`) or sequences (`up up down down left right left right B A`).\n\n\u003e **Combokeys** is used under the\n  hood for handling the shortcuts. [Read more][mousetrap] about how you can\n  specify keys.\n\n\n##### Example `keymap` definition:\n\n\n```javascript\nexport default {\n  TODO_ITEM: {\n    MOVE_LEFT: 'left',\n    MOVE_RIGHT: 'right',\n    MOVE_UP: ['up', 'w'],\n    DELETE: {\n      osx: ['command+backspace', 'k'],\n      windows: 'delete',\n      linux: 'delete',\n    },\n  },\n}\n\n```\n\nSave this file as `keymap.[js|coffee|json|cson]` and require it into your main\nfile.\n\n```javascript\nimport keymap from './keymap'\n```\n\n#### 3. Rise of the ShortcutsManager\n\nDefine your keymap in whichever supported format but in the end it must be an\nobject. `ShortcutsManager` can’t parse JSON and will certainly not be happy\nabout the situation.\n\n```javascript\nimport keymap from './keymap'\nimport { ShortcutManager } from 'react-shortcuts'\n\nconst shortcutManager = new ShortcutManager(keymap)\n\n// Or like this\n\nconst shortcutManager = new ShortcutManager()\nshortcutManager.setKeymap(keymap)\n```\n\n#### 4. Include `shortcutManager` into getChildContext of some parent component. So that `\u003cshortcuts\u003e` can receive it.\n\n```javascript\nclass App extends React.Component {\n  getChildContext() {\n    return { shortcuts: shortcutManager }\n  }\n}\n\nApp.childContextTypes = {\n  shortcuts: PropTypes.object.isRequired\n}\n```\n\n#### 5. Require the \u003cshortcuts\u003e component\n\nYou need to require the component in the file you want to use shortcuts in.\nFor example `\u003cTodoItem\u003e`.\n\n```javascript\nimport { Shortcuts } from `react-shortcuts`\n\nclass TodoItem extends React.Component {\n  _handleShortcuts = (action, event) =\u003e {\n    switch (action) {\n      case 'MOVE_LEFT':\n        console.log('moving left')\n        break\n      case 'MOVE_RIGHT':\n        console.log('moving right')\n        break\n      case 'MOVE_UP':\n        console.log('moving up')\n        break\n      case 'COPY':\n        console.log('copying stuff')\n        break\n    }\n  }\n\n  render() {\n    return (\n      \u003cShortcuts\n        name='TODO_ITEM'\n        handler={this._handleShortcuts}\n      \u003e\n        \u003cdiv\u003eMake something amazing today\u003c/div\u003e\n      \u003c/Shortcuts\u003e\n    )\n  }\n}\n```\n\n\u003e The `\u003cShortcuts\u003e` component creates a `\u003cshortcuts\u003e` element in HTML, binds\n  listeners and adds tabIndex to the element so that it’s focusable.\n  `_handleShortcuts` is invoked when some of the defined shortcuts fire.\n\n## Custom props for `\u003cShortcuts\u003e` component\n\n- `handler`: func\n  - callback function that will fire when a shortcut occurs\n- `name`: string\n  - The name of the namespace specified in keymap file\n- `tabIndex`: number\n  - Default is `-1`\n- `className`: string\n- `eventType`: string\n  - Just for gourmets (keyup, keydown, keypress)\n- `stopPropagation`: bool\n- `preventDefault`: bool\n- `targetNodeSelector`: DOM Node Selector like `body` or `.my-class`\n  - Use this one with caution. It binds listeners to the provided string instead\n  of the component.\n- `global`: bool\n  - Use this when you have some global app wide shortcuts like `CMD+Q`.\n- `isolate`: bool\n  - 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.\n- `alwaysFireHandler`: bool\n  - Use this when you want events keep firing on the focused input elements. \n\n\n## Thanks, Atom\n\n\nThis library is inspired by [Atom Keymap].\n\n\n[Atom Keymap]: https://github.com/atom/atom-keymap/\n[travis]: https://travis-ci.org/avocode/react-shortcuts\n[mousetrap]: https://craig.is/killing/mice\n[keymaps]: https://github.com/atom/atom-keymap/\n","funding_links":[],"categories":["UI Utilities","UI Components","UI Utilites"],"sub_categories":["Device Input","Device Input/User Action"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favocode%2Freact-shortcuts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favocode%2Freact-shortcuts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favocode%2Freact-shortcuts/lists"}