Code Monkey home page Code Monkey logo

keyux's Introduction

KeyUX

JS library to improve keyboard UI of web apps. It was designed not only for a11y but also to create professions tools where users prefer using keyboard.

  • Add hotkeys by aria-keyshortcuts.
  • Show a button’s :active state when a hotkey is pressed.
  • Enable navigation with keyboard arrows in role="menu" lists.
  • Jump to the next section according to aria-controls and back with Esc.
  • Show and hide submenus of role="menu".
  • Allows users to override hotkeys.
  • 1 KB (minified and brotlied). No dependencies.
  • Vanilla JS and works with any framework including React, Vue, Svelte.
export const Button = ({ hokey, children }) => {
  return <button aria-keyshortcuts={hotkey}>
    {children}
    {likelyWithKeyboard(window) && <kbd>{getHotKeyHint(window, hotkey)}</kbd>}
  </button>
}

See demo page and example.


Made in Evil Martians, product consulting for developer tools.


Install

npm install keyux

Then add startKeyUX call with necessary features to main JS file.

import {
  hiddenKeyUX,
  hotkeyKeyUX,
  jumpKeyUX,
  menuKeyUX,
  pressKeyUX,
  startKeyUX
} from 'keyux'

const overrides = {}

startKeyUX(window, [
  hotkeyKeyUX(overrides),
  menuKeyUX(),
  pressKeyUX('is-pressed'),
  jumpKeyUX(),
  hiddenKeyUX()
])

Features

Hotkeys

If user will press hotkey, KeyUX will click on button or link with aria-keyshortcuts with the same hotkey.

For instance, KeyUX will click on this button if user press Alt+B or +B.

<button aria-keyshortcuts="alt+b">Bold</button>

The hotkey pattern should modifiers like meta+ctrl+shift+alt+b in exact order.

To enable this feature, you need to call hotkeyKeyUX:

import { hotkeyKeyUX, startKeyUX } from 'keyux'

startKeyUX(window, [
  hotkeyKeyUX()
])

Hotkeys Hint

You can render hotkey hint from aria-keyshortcuts pattern in a prettier way:

import { likelyWithKeyboard, getHotKeyHint } from 'keyux'

export const Button = ({ hokey, children }) => {
  return <button aria-keyshortcuts={hotkey}>
    {children}
    {likelyWithKeyboard(window) && <kbd>{getHotKeyHint(window, hotkey)}</kbd>}
  </button>
}

likelyWithKeyboard() returns false on mobile devices where user likely will not be able to use hotkeys (but it is still possible by connecting external keyboard).

getHotKeyHint() will replace modifiers for Mac and make text more pretty. For instance, for alt+b it will return Alt + B on Windows/Linux or ⌥ + B on Mac.

Pressed State

KeyUX can set class to show pressed state for button when user will press hotkey. It will make UI more responsible.

import { hotkeyKeyUX, startKeyUX, pressKeyUX } from 'keyux'

startKeyUX(window, [
  pressKeyUX('is-pressed'),
  hotkeyKeyUX()
])
button {
  &:active,
  &.is-pressed {
    transform: scale(0.95);
  }
}

You can use postcss-pseudo-classes to automatically add class for every :active state in your CSS.

Hotkeys Override

Many users want to override hotkeys because your hotkeys can conflict with browser’s extensions, system, or screen reader.

KeyUX allows to override hotkeys by overrides object. Both hotkeyKeyUX() and getHotKeyHint() accepts it as argument.

You will need to create some UI for user to fill this object like:

const overrides = {
  'alt+b': 'b' // Override B to Alt + B
}

Then KeyUX will click on aria-keyshortcuts="b" on Alt+B press and getHotKeyHint(window, 'b', overrides) will return Alt + B/⌥ + B.

Menu

Using only Tab for navigation is not very useful. User may need to press it to many to get their button (also non-screen-reader users don’t have quick navigation).

To reduce Tab-list you can group some related things (tabs or website’s menu) into role="menu" with arrows navigation.

<nav role="menu">
  <a href="/" role="menuitem">Home</a>
  <a href="/catalog" role="menuitem">Catalog</a>
  <a href="/contacts" role="menuitem">Contacts</a>
</nav>

Users will use Tab to go inside menu and will use either arrows and Home, End or a name of some item to navigate inside.

To enable this feature call menuKeyUX.

import { menuKeyUX } from 'keyux'

startKeyUX(window, [
  menuKeyUX()
])

Jumps

After finishing in one section, you can move user’s focus on next step to save time. For instance, you can move cursor to the page after user select it in the menu. Or you can move focus to item’s form after user select item in the list.

You can control where to move focus next by aria-controls.

<div role="menu">
  {products.map(({ id, name }) =>
    <button role="menuitem" aria-controls="product_form">{name}</button>
  )}
</div>

<div id="product_form">
  
</div>

On Esc focus will jump back.

You can add aria-controls to <input> to jump focus on Enter.

<input type="search" aria-controls="search_results" />

To enable this feature call jumpKeyUX.

import { menuKeyUX, jumpKeyUX } from 'keyux'

startKeyUX(window, [
  menuKeyUX(),
  jumpKeyUX()
])

Nested Menu

You can make nested menus with KeyUX by aria-controls and aria-hidden="true".

<button aria-controls="edit" aria-haspopup="menu">Edit</button>

<div id="edit" hidden aria-hidden="true" role="menu">
  <button role="menuitem">Undo</button>
  <button role="menuitem" aria-controls="find" aria-haspopup="menu">Find</button>
</div>

<div id="find" hidden aria-hidden="true" role="menu">
  <button role="menuitem">Find…</button>
  <button role="menuitem">Replace…</button>
</div>

You can make visible nested menu by avoiding setting hidden, but you will need to set tabindex="-1" manually.

To enable this feature call hiddenKeyUX.

import { menuKeyUX, jumpKeyUX, hiddenKeyUX } from 'keyux'

startKeyUX(window, [
  menuKeyUX(),
  jumpKeyUX(),
  hiddenKeyUX()
])

keyux's People

Contributors

ai avatar vladbrok avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.