0.2.4 • Published 5 years ago

keyboard-events v0.2.4

Weekly downloads
1
License
MIT
Repository
github
Last release
5 years ago

Keyboard Events

CAUTION: This library is not considered production ready and currently has no published tests.

A module to wrap keyboard events on the DOM that

  • exposes key combinations as user friendly names
  • allows you to bind these combinations to functions
  • allows you to attach data to events
  • allows creation of reusable custom action modules (see Action Modules below)

The goal is to provide a means to add keyboard accessibility that is easily extensible.

Written as an ES module with no dependencies.

Usage

$ npm i keyboard-events --save
import Keyboard from 'keyboard-events';
<script type='text/javascript' src='/dist/keyboard-events.js'></script>
<script type='text/javascript' src='/dist/keyboard-events.min.js'></script>

Example

For elements that aren't focusable by default you will need to make them focusable e.g. by adding tabindex='0'

<form>
  <input type='text' id='input'>
</form>

<ul>
  <li tabindex='0'></li>
</ul>
Keyboard({
  elm: document.querySelector('#input'), // listen to the '#input' element
  props: {},                             // pass props to all actions
  actions: [                             // define your actions
    ['enter', {                          // the key name to listen to (see commands below)
      fn: process,                       // calls the 'process' function below
      data: {}                           // pass data to this action only
      once: true                         // automatically unsubscribe this listener after one event
    }],
    ['esc', {                            // define as many actions as you like
      fn: data => data.element.blur()
    }]
  ]
});

function process(data) {
  data.event.preventDefault(); // stop the form from submitting
  // ...                       // do processing
}

// the data arg will have this structure:
{
    command     // the key name listened to e.g. 'enter'
  , element     // the element listened to e.g. '#input'
  , target      // the event target e.g. '#input' but could be a child element 
  , event       // the actual event object itself 
                // (target above is for convenience and is event.target from this property)
  , props       // the props passed to all actions
  , data        // the data passed to this action
}

// keep a reference to unsubscribe with
const k = Keyboard(
  // ...
);
k.unsubscribe();

// cancel all keyboard subscriptions
// (it's unlikely you will want this)
Keyboard.clear();

NOTE: It is possible to have nested listeners as the module will map over any elements that are subscribed. So you can set global listeners on the body that will still execute if another registered element has focus. In the case where two elements are registered for the same action e.g. enter, then the action for both will be executed.

Action Modules

Action modules can be useful if you want to define a set of reusable keyboard modules. There is a module provided with this library in src/actions/keyboard-tarverse.js that implements traversing a list.

Example

// my-actions.js
// ----------------
const actions = [
  ['arrow-up', {fn: prev}],
  ['arrow-left', {fn: prev}],
  ['arrow-down', {fn: next}],
  ['arrow-right', {fn: next}]
];

function prev(data) {
  // ...
}

function next(data) {
  // ...
}

export default actions

// app.js
// ----------------
import Keyboard from 'keyboard';
import MyActions from 'my-actions.js';

Keyboard({
  elm: document.querySelector('#input'),
  props: {},                             
  use: MyActions,    // import the actions from my-actions.js
  actions: [            // extend/overwrite the imported actions with your own              
    ['enter', {                          
      fn: process
    }]
  ]
});

Commands

These are the user friendly commands exposed by Keyboard (and purely for reference the key codes being used to trigger them).

Use them like this:

Keyboard({
  actions: [
    ['backspace', {}],
    ['ctrl+alt+backspace', {}]
  ]
});

Special Keys

cmd

ctrl (on a mac the cmd key will be translated to ctrl)

shift

alt

You can create combinations like so:

ctrl+b  

ctrl+shift+arrow-right 

ctrl+shift+alt+backspace

Order Matters !!

The order in which the user presses the keys DOES NOT matter but the order in which you write your actions does.

// correct order
cmd ctrl shift alt
// yes 
Keyboard({
  actions: [
    ['cmd+ctrl+shift+alt+b', {}]
  ]
});

// no (any other order)
Keyboard({
  actions: [
    ['ctrl+cmd+shift+alt+b', {}],
    ['cmd+ctrl+alt+shift+b', {}]
  ]
});

The Cmd Key

There is an option to pass that allows for using the cmd key. If you don't set it, the cmd key gets converted to the ctrl key. It will depend on what you are doing but you may or may not wish to us this option. If you do, you may need to assign both cmd and ctrl to the same function.

// in this example, if cmd+b were not defined then pressing cmd+b would have no effect
Keyboard({
  useCmd: true,
  actions: [
    ['cmd+b', {}],
    ['ctrl+b', {}]
  ]
});

// in this case cmd+b and ctrl+b both work and are mapped to ctrl+b
Keyboard({
  actions: [
    ['ctrl+b', {}]
  ]
});

License

MIT - see LICENSE.md