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

shosho

v1.4.3

Published

A modern and powerful shortcuts management library.

Downloads

310

Readme

ShoSho

A modern and powerful shortcuts management library.

Features

  • It is largely built on top of KeyboardEvent#code and KeyboardEvent#key, for great compatibility across browsers, platforms, languages and layouts.
  • It is fast. Almost always this library will do O(1) registrations, O(1) disposals, O(1) lookups and O(1) resetting.
  • It supports ~100 keyboard keys, including function keys and numpad keys.
  • It supports mouse buttons too, which can be mixed in shortcts with keyboard keys, like Ctrl+ClickLeft.
  • It supports simple shortcuts, like Ctrl+F, and shortcuts sequences, like Ctrl+K Ctrl+F.
  • It supports detecting which exact modifier key was pressed, like ControlLeft or ControlRight.
  • It supports common aliases for keys, like Alt/Option, or Esc/Escape.
  • It supports some character-based shortcuts, like Shift+#, rather than the equivalent key-based shortcut, which might be Shift+3.
  • It supports automatically using Command under macOS and Control elsewhere, by writing for example CommandOrControl+F.
  • It supports multi-trigger shortcuts, like Up+Right or Down+Left, except when the Meta key is pressed, which is buggy in browsers.
  • It supports Konami codes, a.k.a. cheatcode shortcuts, like Up Up Down Down Left Right Left Right B A.
  • It supports formatting shortcuts in 10 different styles, including formatting for Electron and as symbols for hints/tooltips.
  • It supports recording a shortcut, for customizing shortcuts easily.

Shortcut Syntax

The following keys can be used when defining a shortcut:

  • Modifiers: Alt/Option, Cmd/Command/Meta, Ctrl/Control, Shift, CmdOrCtrl/CommandOrControl.
  • Left modifiers: AltLeft/OptionLeft, CmdLeft/CommandLeft/MetaLeft, CtrlLeft/ControLeft, CmdLeftOrCtrlLeft/CommandLeftOrControlLeft.
  • Right modifiers: AltRight/OptionRight, CmdRight/CommandRight/MetaRight, CtrlRight/ControRight, CmdRightOrCtrlRight/CommandRightOrControlRight.
  • Digits: 0-9.
  • Alphabet letters: A-Z.
  • Function keys: F1-F24.
  • Numpad digits: Numpad0-Numpad9.
  • Numpad operators: NumpadAdd, NumpadComma, NumpadDecimal, NumpadDivide, NumpadEnter, NumpadEqual, NumpadMultiply, NumpadSubtract.
  • Special keys: Backspace, Capslock, Del/Delete, Down, End, Enter/Return, Esc/Escape, Home, Insert, Left, PageDown, PageUp, Right, Space/Spacebar, Tab, Up, NumLock, ScrollLock.
  • Punctuation keys: !, @, #, $, %, ^, &, *, ( , ), _, {, }, |, :, ", <, >, ?, ~.
  • Mouse buttons: ClickLeft/MouseLeft, ClickMiddle/MouseMiddle, ClickRight/MouseRight, Mouse0-Mouse9.

Please note that:

  • ℹ️ Other keys are not supported.
  • ℹ️ Shortcuts are case insensitive.
  • ℹ️ Keys in a single shortcut must be joined by a plus sign (e.g. Ctrl+A).
  • ℹ️ Sequences of shortcuts must be joined by a space (e.g. Ctrl+K Ctrl+B).
  • ⚠️ Punctuation keys should be avoided when possible, especially when used in combination with Shift/Alt, as they may lead to somewhat different results across different layouts.

Install

npm install --save shosho

Usage

import ShoSho from 'shosho';

// Let's create a shortcuts manager

const shortcuts = new ShoSho ({
  capture: true,
  target: document,
  shouldHandleEvent ( event ) {
    // Return "true" if this event should be handled
    return true;
  }
});

// Let's register some shortcuts. Shortcuts handlers must return "true" if they actually handled the shortcut

shortcuts.register ( 'A', event => { // Single-key shortcut
  console.log ( 'Handling A' );
  return true;
});

shortcuts.register ( 'Ctrl+F', event => { // Simple modifier+trigger shortcut
  console.log ( 'Handling Ctrl+F' );
  return true;
});

shortcuts.register ( 'Ctrl+K Ctrl+F', event => { // Advanced sequence shortcut
  console.log ( 'Handling Ctrl+K Ctrl+F' );
  return true;
});

shortcuts.register ( 'ClickMiddle', event => { // Single-mouse-button shortcut
  console.log ( 'Skipping ClickMiddle actually' );
  return false; // Returning "false" tells the library to try other potential handlers for this shortcut
});

shortcuts.register ( 'CmdOrCtrl+ClickRight', event => { // Advanced mixed keyboard/mouse shortcut
  console.log ( 'Handling CmdOrCtrl+ClickRight' );
  return true;
});

// Let's register a Konami code, which basically is not affected by other registered shortcuts

shortcuts.register ( 'Up Up Down Down Left Right Left Right B A', event => { // A Konami code
  console.log ( 'Secret shortcut triggered 🚀' );
}, { konami: true } ); // Registering it as a Konami code

// Let's register a shortcut but then dispose of it

const dispose = shortcuts.register ( 'Shift+1', event => {
  console.log ( 'Handling Shift+1' );
  return true;
});

dispose (); // Unregistering that shortcut with that handler

// Let's trigger a shortcut programmatically, perhaps for debugging purposes

const handled = shortcuts.trigger ( 'Ctrl+F' );

console.log ( handled ); // => true

// Let's actually start listening for shortcuts

shortcuts.start ();

// Let's stop listening for shortcuts

shortcuts.stop ();

// Let's dispose of all registered shortcuts

shortcuts.reset ();

// Let's format a shortcut, with every supported format

ShoSho.format ( 'ControlLeft+A', 'electron' ); // => 'Ctrl+A'
ShoSho.format ( 'ControlLeft+A', 'symbols' ); // => '⌃A'
ShoSho.format ( 'ControlLeft+A', 'long-flexible-directional' ); // => 'CommandOrControlLeft+A'
ShoSho.format ( 'ControlLeft+A', 'long-flexible-nondirectional' ); // => 'CommandOrControl+A'
ShoSho.format ( 'ControlLeft+A', 'long-inflexible-directional' ); // => 'ControlLeft+A'
ShoSho.format ( 'ControlLeft+A', 'long-inflexible-nondirectional' ); // => 'Control+A'
ShoSho.format ( 'ControlLeft+A', 'short-flexible-directional' ); // => 'CmdOrCtrlLeft+A'
ShoSho.format ( 'ControlLeft+A', 'short-flexible-nondirectional' ); // => 'CmdOrCtrl+A'
ShoSho.format ( 'ControlLeft+A', 'short-inflexible-directional' ); // => 'CtrlLeft+A'
ShoSho.format ( 'ControlLeft+A', 'short-inflexible-nondirectional' ); // => 'Ctrl+A'

// Let's check if something is a valid shortcut

ShoSho.isShortcut ( 'Control+A' ); // => true
ShoSho.isShortcut ( 'ControlA' ); // => false

// Let's record a shortcut, which will require manual trimming and formatting

const dispose = ShoSho.record ( shortcut => {

  console.log ( shortcut ); // => It could be 'A', 'CtrlLeft+A', 'CtrlLeft+A CtrlRight', 'CtrlLeft+A CtrlRight+B' and so on...

  const trimmed = shortcut.replace ( /(^.*?)((?:Control(?:Left|Right)\+K )*\S+$)/, '$2' ); // Allowing only 'ControlLeft+K' and 'ControlRight+K' to not be the last shortcut in the sequence
  const formatted = ShoSho.format ( trimmed, 'long-inflexible-nondirectional' ); // Ensuring the final shortcut is formatted exactly how we want it

  console.log ( formatted ); // => It could be 'K', 'CtrlLeft+K', 'CtrlLeft+K CtrlRight', 'Ctrlleft+K CtrlRight+A' and so on...

});

// Let's stop recording

dispose ();

License

MIT © Fabio Spampinato