diff --git a/README.md b/README.md index 365b425..31518a5 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,6 @@ JavaScript keyboard events to strings -This library converts the event object of a JavaScript keydown event -into a humanly readable format. -The idea is to use this for UI components that let the user choose keyboard shortcuts. - -In other words: This library provides the inverse functionality to common keyboard shortcut binding libraries like [keymaster](https://github.com/madrobby/keymaster) or [Mousetrap](https://craig.is/killing/mice). +This library converts the event object of a JavaScript keydown event into a humanly readable format. The idea is to use this for UI components that let the user choose keyboard shortcuts. It can also be used as a developer-facing tool so keyboard shortcuts have a single, canonical string name (like in a big switch statement). ## Installation @@ -16,19 +12,18 @@ $ npm install --save keyboard-event-to-string ```js import { - toString as event2String, - setOptions + toString as event2String } from 'keyboard-event-to-string' document.body.onkeydown = (e) => { var keys = event2string(e) - console.log(keys) // e.g. "Ctrl + A" + console.log(keys) // e.g. "Ctrl + KeyA" } ``` ### Options -`options` is optional and can be an object with the following properties: +`options` , if used, is an object with some or all of the following properties: | key | value | default value | |:--|:--|:--| @@ -36,9 +31,10 @@ document.body.onkeydown = (e) => { | `ctrl` | What string to display for the Ctrl modifier | `"Ctrl"` | | `alt` | What string to display for the Alt/Option modifier | `"Alt"` | | `shift` | What string to display for the Shift modifier | `"Shift"` | -| `joinWith` | The string that's displayed between all keys | `" + "` +| `joinWith` | The string that's displayed between all keys | `" + "` | +| `hideKey` | Whether to remove the "Key" from the front of key names | `"never"` | -For example this could be used to get the Mac style keyboard shortcut strings: +For example this could be used to get the Mac style keyboard shortcut strings globally: ```js import { setOptions } from 'keyboard-event-to-string' @@ -47,12 +43,15 @@ setOptions({ ctrl: "⌃", alt: "⌥", shift: "⇧", - joinWith: "" + joinWith: "", + hideKey: 'always' }) ``` The default settings are compatible with the format that common keyboard shortcut libraries, like [keymaster](https://github.com/madrobby/keymaster) or [Mousetrap](https://craig.is/killing/mice), accept. +If you're trying to make the information readable by users, the default key names are awkward. The word "Key" is prefixed to many of the key names, which is obvious or redundant. The `hideKey` option allows filtering the word out, either globally or conditionally. The permitted values are: `'never' | 'always' | 'alpha' | 'alphanumeric'`. + To restore to the defaults, use `setOptions({})`. ### Detailed information @@ -61,7 +60,7 @@ To restore to the defaults, use `setOptions({})`. import { details } from 'keyboard-event-to-string' ``` -`details` can be used to get more details. This can be useful for +`details` can be used to get more details on an event. This can be useful for validating keyboard shortcuts, e.g. for requiring a modifier and a normal key. It returns an object with this information: @@ -70,13 +69,12 @@ It returns an object with this information: - `map`: An object containing information which modifier is active and what other key is pressed - - ## Release Notes -- In Sept 2021, I renamed this from `key-` to `keyboard-` so that I could publish (my own) NPM package. -- I (Andrew Peterson) converted this library to Typescript in 2021 to suit a web project. Feel free to offer contributions. -- It now uses the `code` of the `KeyboardEvent`. This is _different_. This will not be backward - compatible. +- 2.1.0 Add configuration of "hideKey" +- 2.0.0 November 2021. First official typescript release. +- In Sept 2021, I (ndp) renamed this from `key-` to `keyboard-` so that I could publish my forked NPM package. +- In 2021, I (ndp) converted this library to Typescript to suit a web project [AmpWhat](https://www.amp-what.com). Feel free to offer contributions. +- This now uses the `code` of the `KeyboardEvent`, per general recommendations. This is _different_. This will not be backward compatible. ## Disclaimer @@ -93,12 +91,11 @@ This project depends on `yarn`. You'll need to do that before you can run `yarn This uses [Gauge](https://docs.gauge.org/overview.html) for tests. You can write tests in markdown, and avoid all the ugly nesting and async/await of most JS testing frameworks. -This should be installed automatically with your `yarn install`. -There's a bit of tweaking to get typescript/gauge to work, -which is sitting there raw, in `package.json`. Don't look at it please. 😉 To run tests, `yarn test`. +This should be installed automatically with your `yarn install`. To run tests, `yarn test`. To release, adjust the version number in `package.json` and `npm publish`. ## Credits - used a [Log Rocket blog post](https://blog.logrocket.com/publishing-node-modules-typescript-es-modules/) to create the typescript package. +- the original package included this comment, and I'm not sure it's that relevant any more: "This library provides the inverse functionality to common keyboard shortcut binding libraries like [keymaster](https://github.com/madrobby/keymaster) or [Mousetrap](https://craig.is/killing/mice)." diff --git a/package.json b/package.json index 17ef4b8..469a731 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keyboard-event-to-string", - "version": "2.0.0", + "version": "2.1.0", "description": " Converts a JavaScript keyboard event object into a humanly readable string", "main": "./dist/cjs/keyboard-event-to-string.js", "module": "./dist/esm/keyboard-event-to-string.js", diff --git a/specs/basic.spec b/specs/basic.spec index 1a57244..f924431 100644 --- a/specs/basic.spec +++ b/specs/basic.spec @@ -1,10 +1,10 @@ # KeyboardEvent to String ## Basic behavior -* an event with the "KeyA" key produces "A" -* an event with the command and "KeyA" key produces "Cmd + A" -* an event with the control and "KeyA" key produces "Ctrl + A" -* an event with the shift and "KeyA" key produces "Shift + A" +* an event with the "KeyA" key produces "KeyA" +* an event with the command and "KeyA" key produces "Cmd + KeyA" +* an event with the control and "KeyA" key produces "Ctrl + KeyA" +* an event with the shift and "KeyA" key produces "Shift + KeyA" * an event with the "ArrowLeft" key produces "ArrowLeft" * an event with the "Key$" key produces "Key$" * an event with the "Comma" key produces "Comma" @@ -14,8 +14,8 @@ * an event with the "PageUp" key produces "PageUp" ## Multiple modifiers -* an event with command and shift and "Key7" key produces "Cmd + Shift + 7" -* an event with control and shift and "KeyC" key produces "Ctrl + Shift + C" +* an event with command and shift and "Key7" key produces "Cmd + Shift + Key7" +* an event with control and shift and "KeyC" key produces "Ctrl + Shift + KeyC" ## Overriding modifier key names * Configure: @@ -27,5 +27,44 @@ |shift | ⇧ | |joinWith| | -* an event with command and shift and "Key7" key produces "⌘⇧7" +* an event with command and shift and "Key7" key produces "⌘⇧Key7" +* Restore configs to defaults + +## Overriding `hideKey` to `alpha` + +* Configure: + |Key |String | + |--------|-------| + |hideKey | alpha | +* an event with the "KeyA" key produces "A" +* an event with the "Key7" key produces "Key7" +* an event with the "PageDown" key produces "PageDown" +* an event with the "KeyPageDown" key produces "KeyPageDown" +* an event with control and shift and "KeyC" key produces "Ctrl + Shift + C" +* Restore configs to defaults + +## Overriding `hideKey` to `alphanumeric` + +* Configure: + |Key |String | + |--------|--------------| + |hideKey | alphanumeric | +* an event with the "KeyA" key produces "A" +* an event with the "Key7" key produces "7" +* an event with the "PageDown" key produces "PageDown" +* an event with the "KeyPageDown" key produces "KeyPageDown" +* an event with control and shift and "KeyC" key produces "Ctrl + Shift + C" +* Restore configs to defaults + +## Overriding `hideKey` to `always` + +* Configure: + |Key |String | + |--------|--------| + |hideKey | always | +* an event with the "KeyA" key produces "A" +* an event with the "Key7" key produces "7" +* an event with the "PageDown" key produces "PageDown" +* an event with the "KeyPageDown" key produces "PageDown" +* an event with control and shift and "KeyC" key produces "Ctrl + Shift + C" * Restore configs to defaults diff --git a/src/keyboard-event-to-string.ts b/src/keyboard-event-to-string.ts index 12c5c88..dde029e 100644 --- a/src/keyboard-event-to-string.ts +++ b/src/keyboard-event-to-string.ts @@ -7,8 +7,11 @@ type Options = { alt: string shift: string joinWith: string + hideKey: HideKeyType } +type HideKeyType = 'never' | 'always' | 'alpha' | 'alphanumeric' + type UserOptions = Partial type Modifiers = { @@ -22,20 +25,27 @@ type KeyMap = { modifiers: Modifiers } -const defaultOptions = { +const defaultOptions: Options = { alt: 'Alt', cmd: 'Cmd', ctrl: 'Ctrl', shift: 'Shift', - joinWith: ' + ' + joinWith: ' + ', + hideKey: 'never' } let gOptions: Options = defaultOptions +const hideKeyRegExp = () => ({ + 'alphanumeric': /^Key([A-Z01-9])$/, + 'alpha': /^Key([A-Z])$/, + 'always': /^Key(.*)$/, + 'never': /^(.*)$/ +})[gOptions.hideKey] -function buildKeyMap (e: KeyboardEvent): KeyMap { +function buildKeyMap(e: KeyboardEvent): KeyMap{ const isOnlyModifier = [16, 17, 18, 91, 93, 224].indexOf(e.keyCode) !== -1 - const character = isOnlyModifier ? null : e.code.replace(/^Key([A-Z01-9])/,'$1') + const character = isOnlyModifier ? null : e.code.replace(hideKeyRegExp(), '$1') return { character: character, @@ -48,7 +58,7 @@ function buildKeyMap (e: KeyboardEvent): KeyMap { } } -function buildKeyArray (e: KeyboardEvent) { +function buildKeyArray(e: KeyboardEvent){ const map = buildKeyMap(e) @@ -65,7 +75,7 @@ function buildKeyArray (e: KeyboardEvent) { return result } -export function details (e: KeyboardEvent): { hasKey: boolean, hasModifier: boolean, map: KeyMap } { +export function details(e: KeyboardEvent): { hasKey: boolean, hasModifier: boolean, map: KeyMap }{ const map = buildKeyMap(e) @@ -78,8 +88,8 @@ export function details (e: KeyboardEvent): { hasKey: boolean, hasModifier: bool } } -export function setOptions (userOptions: UserOptions): UserOptions { - return gOptions = {...defaultOptions, ...userOptions} +export function setOptions(userOptions: UserOptions): UserOptions{ + return gOptions = { ...defaultOptions, ...userOptions } } export const toString = (e: KeyboardEvent): string => buildKeyArray(e).join(gOptions.joinWith)