Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/github/hotkey

Trigger an action on an element with a keyboard shortcut.
https://github.com/github/hotkey

decorator shortcuts

Last synced: 2 days ago
JSON representation

Trigger an action on an element with a keyboard shortcut.

Awesome Lists containing this project

README

        

# Hotkey Behavior

```html
Show help dialog
```

Trigger an action on a target element when the hotkey (key or sequence of keys) is pressed
on the keyboard. This triggers a focus event on form fields, or a click event on
other elements.

The hotkey can be scoped to a form field:

```html

press meta+d in text area to click this button

text area
```

By default, hotkeys are extracted from a target element's `data-hotkey`
attribute, but this can be overridden by passing the hotkey to the registering
function (`install`) as a parameter.

## How is this used on GitHub?

All shortcuts (for example `g i`, `.`, `Meta+k`) within GitHub use hotkey to declare shortcuts in server side templates. This is used on almost every page on GitHub.

## Installation

```
$ npm install @github/hotkey
```

## Usage

### HTML

```html

Next

Search

Code

Help

Search
```

See [the list of `KeyboardEvent` key values](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values) for a list of supported key values.

### JS

```js
import {install} from '@github/hotkey'

// Install all the hotkeys on the page
for (const el of document.querySelectorAll('[data-hotkey]')) {
install(el)
}
```

Alternatively, the hotkey(s) can be passed to the `install` function as a parameter e.g.:

```js
for (const el of document.querySelectorAll('[data-shortcut]')) {
install(el, el.dataset.shortcut)
}
```

To unregister a hotkey from an element, use `uninstall`:

```js
import {uninstall} from '@github/hotkey'

for (const el of document.querySelectorAll('[data-hotkey]')) {
uninstall(el)
}
```

By default form elements (such as `input`,`textarea`,`select`) or elements with `contenteditable` will call `focus()` when the hotkey is triggered. All other elements trigger a `click()`. All elements, regardless of type, will emit a cancellable `hotkey-fire` event, so you can customize the behaviour, if you so choose:

```js
for (const el of document.querySelectorAll('[data-shortcut]')) {
install(el, el.dataset.shortcut)

if (el.matches('.frobber')) {
el.addEventListener('hotkey-fire', event => {
// ensure the default `focus()`/`click()` is prevented:
event.preventDefault()

// Use a custom behaviour instead
frobulateFrobber(event.target)
})
}
}
```

## Hotkey string format

1. Hotkey matches against the `event.key`, and uses standard W3C key names for keys and modifiers as documented in [UI Events KeyboardEvent key Values](https://www.w3.org/TR/uievents-key/).
2. At minimum a hotkey string must specify one bare key.
3. Multiple hotkeys (aliases) are separated by a `,`. For example the hotkey `a,b` would activate if the user typed `a` or `b`.
4. Multiple keys separated by a blank space represent a key sequence. For example the hotkey `g n` would activate when a user types the `g` key followed by the `n` key.
5. Modifier key combos are separated with a `+` and are prepended to a key in a consistent order as follows: `"Control+Alt+Meta+Shift+KEY"`.
6. `"Mod"` is a special modifier that localizes to `Meta` on MacOS/iOS, and `Control` on Windows/Linux.
1. `"Mod+"` can appear in any order in a hotkey string. For example: `"Mod+Alt+Shift+KEY"`
2. Neither the `Control` or `Meta` modifiers should appear in a hotkey string with `Mod`.
7. `"Plus"` and `"Space"` are special key names to represent the `+` and ` ` keys respectively, because these symbols cannot be represented in the normal hotkey string syntax.
8. You can use the comma key `,` as a hotkey, e.g. `a,,` would activate if the user typed `a` or `,`. `Control+,,x` would activate for `Control+,` or `x`.
9. `"Shift"` should be included if it would be held and the key is uppercase: ie, `Shift+A` not `A`
1. MacOS outputs lowercase key names when `Meta+Shift` is held (ie, `Meta+Shift+a`). In an attempt to normalize this, `hotkey` will automatically map these key names to uppercase, so the uppercase keys should still be used (ie, `"Meta+Shift+A"` or `"Mod+Shift+A"`). **However**, this normalization only works on US keyboard layouts.

### Example

The following hotkey would match if the user typed the key sequence `a` and then `b`, OR if the user held down the `Control`, `Alt` and `/` keys at the same time.

```js
'a b,Control+Alt+/'
```

🔬 **Hotkey Mapper** is a tool to help you determine the correct hotkey string for your key combination:

#### Key-sequence considerations

Two-key-sequences such as `g c` and `g i` are stored
under the 'g' key in a nested object with 'c' and 'i' keys.

```
mappings =
'c' : New Issue
'g' :
'c' : Code
'i' : Issues
```

In this example, both `g c` and `c` could be available as hotkeys on the
same page, but `g c` and `g` can't coexist. If the user presses
`g`, the `c` hotkey will be unavailable for 1500 ms while we
wait for either `g c` or `g i`.

## Accessibility considerations

### Character Key Shortcuts

Please note that adding this functionality to your site can be a drawback for
certain users. Providing a way in your system to disable hotkeys or remap
them makes sure that those users can still use your site (given that it's
accessible to those users).

See ["Understanding Success Criterion 2.1.4: Character Key Shortcuts"](https://www.w3.org/WAI/WCAG21/Understanding/character-key-shortcuts.html)
for further reading on this topic.

### Interactive Elements

Wherever possible, hotkeys should be add to [interactive and focusable elements](https://html.spec.whatwg.org/#interactive-content). If a static element must be used, please follow the guideline in ["Adding keyboard-accessible actions to static HTML elements"](https://www.w3.org/WAI/WCAG21/Techniques/client-side-script/SCR29.html).

## Development

```
npm install
npm test
```

## License

Distributed under the MIT license. See LICENSE for details.