This directive, v-hotkey
, transforms hotkey keystrokes to an event on a target element or to
a function call. It offers the following features:
- When placed on a Vue component (as opposed to a plain HTML element),
v-hotkey
can also target an inner element, determined by a CSS selector. - The target element can receive an event, or a method can be called with the target element as argument.
- The hotkey mapping is maintained for the lifetime of the element on which
v-hotkey
is placed. Thus, hotkey mappings appear and disappear automatically together with the elements they are placed on. - Hotkeys can be combinations of
Ctrl
,Alt
,Shift
andMeta
with a character or a special key value. Multiple hotkeys can be mapped to the same action. - Hotkeys will override browser shortcuts if possible.
- High performance: the
keydown
event overhead is very low and practically independent of the number of hotkeys (in this example, over 800 hotkeys are defined). - The configuration can be changed dynamically.
- The directive can be disabled.
An online example demonstrating v-hotkey
for plain HTML and Vue Material components
is available here
(example source code).
As a module:
$ npm install @undecaf/vue-hotkey
or
$ yarn add @undecaf/vue-hotkey
Included as <script>
:
<script src="https://cdn.jsdelivr.net/npm/@undecaf/vue-hotkey/dist/directives.min.js"></script>
import hotkey from 'vue-hotkey'
Vue.use(hotkey)
v-hotkey
requires a configuration object, or a string or an array (sets the keys
property).
Unspecified options get default values.
The configuration object supports the following properties:
Name | Type | Description | Default |
---|---|---|---|
enabled |
Boolean |
Enables the directive if truthy. | true |
keys |
String or Array<String> |
Hotkey(s) in the format [Ctrl+][Shift+][Alt+][Meta+]key_value .Plain characters should have at least one Ctrl , Alt or Meta modifier in order to avoid conflicts with input elements (see this example for an exception). Shift is irrelevant for plain characters as they are matched case-insensitively.Hotkeys will override browser shortcuts if possible. |
none, must be specified |
action |
String or Event or Function |
An event name, an Event object, or a function to be called.The function receives the target element as argument, and this references the surrounding Vue component's vm . |
'click' |
selector |
String |
The first element matching this selector (starting with the element on which v-hotkey is placed) becomes the target for action . |
'*' |
priority |
Number |
Priority in relation to other hotkey configurations. If the same hotkey has been mapped several times then the configuration with the highest priority wins. |
0 |
Property changes after binding are taken into account.
Hotkeys that click an HTML button and a Vue Material Button:
<button v-hotkey="'alt+Enter'" @click="...">Submit</button>
<md-button v-hotkey="['ctrl+s', 'Alt+S']" @click="...">Save</md-button>
No target
is required for <md-button>
since this component resolves to the target
(a <button>
) anyway.
Toggling a checkbox value:
<div>
<input
type="checkbox"
v-model="details"
v-hotkey="{ keys: 'Ctrl+D', action: () => $nextTick(() => details = !details) }">
<label>Show details (Ctrl-D to toggle)</label>
</div>
Please note that action: details = !details
would lead to an infinite render loop, and
action: el => el.checked = !el.checked
would not toggle variable details
.
Entering search text after a leading /
(inspired by the Vuetify homepage):
<md-field v-hotkey="{ keys: '/', action: el => el.focus(), selector: 'input' }">
<label>Search ("/" to focus)</label>
<md-input type="text" />
</md-field>
Plain-character hotkeys are disabled automatically on inputs and contenteditable elements so that they can be entered in these elements.
v-hotkey
could have been placed also on <md-input>
, omitting the selector
because <md-input>
resolves to <input>
.
Multiple v-hotkey
directives can be placed on the same element if a unique argument is appended
to each directive:
<md-dialog
v-hotkey:1="{ keys: 'ctrl+s', selector: '.save-btn' }"
v-hotkey:2="{ keys: 'ctrl+x', selector: '.exit-btn' }">
...
<md-button class="save-btn">Save</md-button>
<md-button class="exit-btn">Exit</md-button>
...
</md-dialog>
Although the inner structure of the Vue Material confirms component is not exposed we can still map hotkeys to the buttons:
<md-dialog-confirm
v-hotkey:1="{ keys: 'N', selector: '.md-dialog-actions button' }"
v-hotkey:2="{ keys: 'Y', selector: '.md-dialog-actions button ~ button' }"
md-content="Press Y or N to confirm or to reject"
md-confirm-text="Yes"
md-cancel-text="No" />
If the Vue Material dialog is showing then Ctrl-S
clicks
the Save
button in the dialog; otherwise Ctrl-S
clicks the Save
button in the surrounding component:
<template>
<md-dialog>
...
<md-button v-hotkey="{ keys: 'ctrl+s', priority: 1 }">Save</md-button>
...
</md-dialog>
...
<md-button v-hotkey="'ctrl+s'">Save</md-button>
</template>
Software: MIT
Documentation: CC-BY-SA 4.0