Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jamiebuilds/tinykeys
A tiny (~400 B) & modern library for keybindings.
https://github.com/jamiebuilds/tinykeys
Last synced: 10 days ago
JSON representation
A tiny (~400 B) & modern library for keybindings.
- Host: GitHub
- URL: https://github.com/jamiebuilds/tinykeys
- Owner: jamiebuilds
- License: mit
- Created: 2020-07-27T23:02:08.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2024-03-08T21:07:27.000Z (8 months ago)
- Last Synced: 2024-04-04T14:05:54.491Z (7 months ago)
- Language: HTML
- Homepage: https://jamiebuilds.github.io/tinykeys/
- Size: 1.67 MB
- Stars: 3,530
- Watchers: 21
- Forks: 75
- Open Issues: 28
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- my-awesome-list - tinykeys
- awesome-web-cn - tinykeys - 一个监听用户键盘的库。(例如:同时按下 Shift+D ,依次按下 y e e t) (Uncategorized / Uncategorized)
- awesome-github-star - tinykeys
- awesome-coding-startup - tinykeys
- awesome-list - tinykeys
- awesome-web-dev - tinykeys
README
# `tinykeys`
> A tiny (~650 B) & modern library for keybindings.
> [See Demo](https://jamiebuilds.github.io/tinykeys/)## Install
```sh
npm install --save tinykeys
```Or for a CDN version, you can use it on [unpkg.com](https://unpkg.com/tinykeys)
## Usage
```js
import { tinykeys } from "tinykeys" // Or `window.tinykeys` using the CDN versiontinykeys(window, {
"Shift+D": () => {
alert("The 'Shift' and 'd' keys were pressed at the same time")
},
"y e e t": () => {
alert("The keys 'y', 'e', 'e', and 't' were pressed in order")
},
"$mod+([0-9])": event => {
event.preventDefault()
alert(`Either 'Control+${event.key}' or 'Meta+${event.key}' were pressed`)
},
})
```Alternatively, if you want to only create the keybinding handler, and register
it as an event listener yourself:```js
import { createKeybindingsHandler } from "tinykeys"let handler = createKeybindingsHandler({
"Shift+D": () => {
alert("The 'Shift' and 'd' keys were pressed at the same time")
},
"y e e t": () => {
alert("The keys 'y', 'e', 'e', and 't' were pressed in order")
},
"$mod+KeyD": event => {
event.preventDefault()
alert("Either 'Control+d' or 'Meta+d' were pressed")
},
})window.addEventListener("keydown", handler)
```### React Hooks Example
If you're using tinykeys within a component, you should also make use of the
returned `unsubscribe()` function.```js
import { useEffect } from "react"
import { tinykeys } from "tinykeys"function useKeyboardShortcuts() {
useEffect(() => {
let unsubscribe = tinykeys(window, {
// ...
})
return () => {
unsubscribe()
}
})
}
```## Commonly used `key`'s and `code`'s
Keybindings will be matched against
[`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key)
and[`KeyboardEvent.code`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values)
which may have some names you don't expect.| Windows | macOS | `key` | `code` |
| ------------- | --------------- | ------------- | ------------------------------ |
| N/A | `Command` / `⌘` | `Meta` | `MetaLeft` / `MetaRight` |
| `Alt` | `Option` / `⌥` | `Alt` | `AltLeft` / `AltRight` |
| `Control` | `Control` / `^` | `Control` | `ControlLeft` / `ControlRight` |
| `Shift` | `Shift` | `Shift` | `ShiftLeft` / `ShiftRight` |
| `Space` | `Space` | N/A | `Space` |
| `Enter` | `Return` | `Enter` | `Enter` |
| `Esc` | `Esc` | `Escape` | `Escape` |
| `1`, `2`, etc | `1`, `2`, etc | `1`, `2`, etc | `Digit1`, `Digit2`, etc |
| `a`, `b`, etc | `a`, `b`, etc | `a`, `b`, etc | `KeyA`, `KeyB`, etc |
| `-` | `-` | `-` | `Minus` |
| `=` | `=` | `=` | `Equal` |
| `+` | `+` | `+` | `Equal`\* |Something missing? Check out the key logger on the
[demo website](https://jamiebuilds.github.io/tinykeys/)> _\* Some keys will have the same code as others because they appear on the
> same key on the keyboard. Keep in mind how this is affected by international
> keyboards which may have different layouts._## Key aliases
In some instances, tinykeys will alias keys depending on the platform to
simplify cross-platform keybindings on international keyboards.### `AltGraph` (modifier)
On Windows, on many non-US standard keyboard layouts, there is a key named
`Alt Gr` or `AltGraph` in the browser, in some browsers, pressing `Control+Alt`
will report `AltGraph` as being pressed instead.Similarly on macOS, the `Alt` (`Option`) key will sometimes be reported as the
`AltGraph` key.**Note:** The purpose of the `Alt Gr` key is to type "Alternate Graphics" so you
will often want to use the `event.code` (`KeyS`) for letters instead of
`event.key` (`S`)```js
tinykeys(window, {
"Control+Alt+KeyS": event => {
// macOS: `Control+Alt+S` or `Control+AltGraph+S`
// Windows: `Control+Alt+S` or `Control+AltGraph+S` or `AltGraph+S`
},
"$mod+Alt+KeyS": event => {
// macOS: `Meta+Alt+S` or `Meta+AltGraph+S`
// Windows: `Control+Alt+S` or `Control+AltGraph+S` or `AltGraph+S`
},
})
```## Keybinding Syntax
Keybindings are made up of a **_sequence_** of **_presses_**.
A **_press_** can be as simple as a single **_key_** which matches against
[`KeyboardEvent.code`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values)
and
[`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key)
(case-insensitive).```js
// Matches `event.key`:
"d"
// Matches: `event.code`:
"KeyD"
```Presses can optionally be prefixed with **_modifiers_** which match against any
valid value to
[`KeyboardEvent.getModifierState()`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState).```js
"Control+d"
"Meta+d"
"Shift+D"
"Alt+KeyD"
"Meta+Shift+D"
```There is also a special `$mod` modifier that makes it easy to support cross
platform keybindings:- Mac: `$mod` = `Meta` (⌘)
- Windows/Linux: `$mod` = `Control````js
"$mod+D" // Meta/Control+D
"$mod+Shift+D" // Meta/Control+Shift+D
```Alternatively, you can use parenthesis to use case-sensitive regular expressions
to match multiple keys.```js
"$mod+([0-9])" // $mod+0, $mod+1, $mod+2, etc...
// equivalent regex: /^[0-9]$/
```### Keybinding Sequences
Keybindings can also consist of several key presses in a row:
```js
"g i" // i.e. "Go to Inbox"
"g a" // i.e. "Go to Archive"
"ArrowUp ArrowUp ArrowDown ArrowDown ArrowLeft ArrowRight ArrowLeft ArrowRight B A"
```Each press can optionally be prefixed with modifier keys:
```js
"$mod+K $mod+1" // i.e. "Toggle Level 1"
"$mod+K $mod+2" // i.e. "Toggle Level 2"
"$mod+K $mod+3" // i.e. "Toggle Level 3"
```Each press in the sequence must be pressed within 1000ms of the last.
### Display the keyboard sequence
You can use the `parseKeybinding` method to get a structured representation of a
keyboard shortcut. It can be useful when you want to display it in a fancier way
than a plain string.```js
import { parseKeybinding } from "tinykeys"let parsedShortcut = parseKeybinding("$mod+Shift+K $mod+1")
```Results into:
```js
[
[["Meta", "Shift"], "K"],
[["Meta"], "1"],
]
```## Additional Configuration Options
You can configure the behavior of tinykeys in a couple ways using a third
`options` parameter.```js
tinykeys(
window,
{
M: toggleMute,
},
{
event: "keyup",
capture: true,
},
)
```### `options.event`
Valid values: `"keydown"`, `"keyup"`
Key presses will listen to this event (default: `"keydown"`).
> **Note:** Do not pass `"keypress"`, it is deprecated in browsers.
### `options.timeout`
Keybinding sequences will wait this long between key presses before cancelling
(default: `1000`).> **Note:** Setting this value too low (i.e. `300`) will be too fast for many of
> your users.