npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-kbs

v2.1.1

Published

React library to manage your application's keyboard shortcuts

Downloads

2,271

Readme

react-kbs

React library to manage your application's keyboard shortcuts.

NPM version build status npm download

Installation

npm i react-kbs

Demo

https://zakodium-oss.github.io/react-kbs/

Documentation

Shortcut definition

A shortcut is defined using an object with at least two fields: shortcut and handler.

  • shortcut is a definition of the key combination that must be used to trigger the shortcut. It can be:
    • a string defining the keyboard's key (case-insensitive). Example: 'a'.
    • an object of the form { key: string; ctrl?: boolean; shift?: boolean; alt?: boolean }. Example: { key: 's', ctrl: true }.
    • an object of the form { code: string; ctrl?: boolean; shift?: boolean; alt?: boolean }. Example: { code: 'Digit1', shift: true }.
    • an array of such strings and/or objects. This allows to define aliases for the same handler. Example: ['/', { key: 'k', ctrl: true }]
  • handler is the function that will be called when the shortcut is triggered.
  • meta is an optional object that can be used to store any additional information about the shortcut. It will be available in the data returned by useKbsGlobalList().
  • maxFrequency is an optional number that defines the maximum number of times the shortcut can be triggered per second. This only affects repeated triggers of the same shortcut when a key is held down.

Use key when you want to refer to the character written by typing on the key and code when you want to use the physical key code (e.g. Digit1 for the 1 key).

There are some things to note about the behavior of shortcuts in react-kbs:

  • On macOS, ctrl automatically maps to the command key. This means that if a shortcut is defined with { key: 's', ctrl: true }, the Ctrl+S combination must be pressed on Linux and Windows, whereas Cmd+Smust be pressed on macOS.
  • By default, if the shift property is not specified, the state of the Shift key doesn't matter. In other words, the shortcut will be triggered with or without the Shift key being pressed. This is in order to make the shortcuts case-insensitive and to support any keyboard layout (the need to press Shift for some keys depend on the user's layout).

Global shortcuts

Global shortcuts are shortcuts that are active anywhere on the page, as long as no specific element has the focus.

To setup global shortcuts, you need to render the KbsProvider component high in your React component tree:

import { KbsProvider } from 'react-kbs';

export default function App() {
  return (
    <KbsProvider>
      <SubComponent />
    </KbsProvider>
  );
}

Then, anywhere down the tree, you can call the useKbsGlobal hook with an array of shortcut definitions to add global shortcuts to the context:

import { useKbsGlobal } from 'react-kbs';

export function MyComponent() {
  const [counter, setCounter] = useState(0);
  useKbsGlobal([
    {
      shortcut: 'i',
      handler() {
        setCounter((current) => current + 1);
      },
    },
    {
      shortcut: 'd',
      handler() {
        setCounter((current) => current - 1);
      },
    },
  ]);

  return <div>Count: {counter}</div>;
}

Local shortcuts

Local shortcuts are shortcuts that are only active when a specific element on the page, or one of its children, is focused.

It is possible to nest such elements. In that case, the first shortcut definition that matches the user input will apply.

To setup local shortcuts, call the useKbs hook with an array of shortcut definitions and pass the value it returns as props to the element for which you want to enable the shortcuts. The following attributes will be set:

  • tabIndex={0}: makes the element focusable
  • onKeyDown={handler}: event handler
function MyComponent(props) {
  const shortcutProps = useKbs([
    {
      shortcut: ['delete', 'backspace'],
      handler: props.onDelete,
    },
  ]);

  return (
    <div {...shortcutProps}>
      <SomeContent />
    </div>
  );
}

Effect of focus on keyboard shortcuts

When no particular element is focused, global shortcuts take effect.
When simple focusable elements (buttons, links, elements that have a tabindex), are focused, global or local shortcuts will usually be triggered, unless one of the following conditions applies:

  • The element is an HTML <input>, <textarea>, or <select>.
  • The element is contenteditable.
  • The element has the data-kbs-ignore attribute.

Disable global shortcuts

It may be useful in some cases to disable all global shortcuts (for example when a dialog is open). To do this, call the useKbsDisableGlobal hook:

import { useKbsDisableGlobal } from 'react-kbs';

function MyDialog({ open }) {
  useKbsDisableGlobal(open);
}

Get the list of global shortcuts

To get the list of all currently defined global shortcuts, call the useKbsGlobalList hook:

import { useKbsGlobalList } from 'react-kbs';

function MyComponent() {
  const shortcuts = useKbsGlobalList();

  return <ShortcutHelp shortcuts={shortcuts} />;
}

Shortcut metadata

It is possible to pass optional metadata with each shortcut in the meta field. The metadata will then be available in the objects returned by useKbsGlobalList().

react-kbs doesn't use the metadata object, which can have any shape. A common use case is to dynamically render a list with all shortcuts and documentation about them.

useKbsGlobal([
  {
    shortcut: 'delete',
    handler: handleDelete,
    meta: {
      description: 'Delete the selected element',
    },
  },
]);

If using TypeScript, you will have to define the shape of the meta object to suit your needs:

import 'react-kbs';

declare module 'react-kbs' {
  interface KbsMetadata {
    description: string;
  }
}