A Stimulus controller for mapping keystrokes to behaviors
npm install stimulus-hotkeys
A Stimulus controller for mapping keystrokes to behaviors
Tiny at ~50 LOC
html
data-controller="hotkeys example"
data-hotkeys-bindings-value='{"p": "example#ping"}'
>
`js
// example_controller.js
import { Controller } from '@hotwired/stimulus'
export default class extends Controller {
ping() {
console.log('PONG')
}
}
`
Yes, that's really it.
$3
As of version 2.1, you can now pass String, Number and Boolean arguments to your Stimulus controller method. Note that it is not possible to pass Objects at this time.
`html
data-controller="hotkeys example"
`js
// example_controller.js
import { Controller } from '@hotwired/stimulus'
export default class extends Controller {
redo() {
console.log(arguments) // ['hero', 666, true, false, '/path/to']
}
}
`
$3
As of version 2.3, you can now use :prevent in your mapping to ensure that your key capture doesn't conflict with native browser behaviour.
`html
data-controller="hotkeys example"
data-hotkeys-bindings-value='{"ctrl+k": "example#ping"}'
>
Now, instead of jumping to the browser search bar, you can capture the key event.
Thanks to @norkunas for the suggestion.
$3
As of version 2.2, specifying a CSS selector to target an element containing a Stimulus controller is optional. It now defaults to assuming the hotkeys controller is on the same element as the controller receiving the mapping calls.
However, you can still use the -> syntax to send mapping calls to controllers on other elements:
`html
data-controller="hotkeys"
data-hotkeys-bindings-value='{"p": "#foo->example#ping"}'
>
$3
This package would be nothing without Hotkeys. Thank you, Kenny Wong!
Setup
Add stimulus-hotkeys to your main JS entry point or Stimulus controllers root folder:
`js
import { Application } from '@hotwired/stimulus'
import Hotkeys from 'stimulus-hotkeys'
import { definitionsFromContext } from '@hotwired/stimulus-webpack-helpers'
const application = Application.start()
const context = require.context('../controllers', true, /\.js$/)
application.load(definitionsFromContext(context))
// Manually register Hotkeys as a Stimulus controller
application.register('hotkeys', Hotkeys)
`
HTML Markup
The data-hotkeys-bindings-value attribute accepts an object in valid JSON notation. This string will be parsed using JSON.parse() so make sure to validate everything going into the expression. I usually forget that you must use " characters in JSON. 🤡
Each key/value pair corresponds to a mapping. The key is the keystroke(s) you want to capture, and the value contains a path to the function you want to call when your user hits the key.
You will want to learn about possible key combinations on the Hotkeys project page.
The value borrows syntax from the Stimulus action system, with important differences:
selector->identifier#method(params)
selector performs a CSS selector lookup and must return an element which holds a Stimulus controller. (As of v2.2, this segment is optional.)
identifier is the Stimulus controller identifier, in kebab-case.
method is the function in the target Stimulus controller.
params is optional, and supports string, numeric and boolean parameters.
Note: this library is not raising events. If you want to receive events, you'll have to emit them yourself... but at some point, it'll probably be less complicated to just include hotkeys-js` in your controller directly. This library is cool because the mapping is potentially dynamic.