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

electron-shortcuts

v0.4.0

Published

Type Safe Electron Shortcuts

Downloads

154

Readme

Electron Shortcuts

Type Safe Electron shortcuts

Overview

electron-shortcuts is a tiny, dependency-free library for writing type-safe Electron shortcuts.

Under the hood, Template Literal Types are used to ensure that the shortcuts you write are valid Electron Accelerators, and event listeners are used to act on shortcuts at runtime.

The main focus of the library is to provide a small set of APIs that are expressive, orthogonal, and safe to use at compile time.

Documentation is automatically generated via Typedoc and can be found here.

Note that Typescript 4.1.0 or greater is required for Template Literal Types.

Usage

import { BrowserWindow } from "electron"
import { register } from "electron-shortcuts"

const mainWindow = new BrowserWindow()

register("Command+a",    () => {}, mainWindow) // OK
register("Cmd+Shift+a",  () => {}, mainWindow) // OK
register("CmdOrCtrl+Up", () => {}, mainWindow) // OK
register("Alt+;",        () => {}, mainWindow) // OK
register("Alt",          () => {}, mainWindow) // Not OK, key code missing
register("F10",          () => {}, mainWindow) // Not OK, modifier missing
register("Comand+F1",    () => {}, mainWindow) // Not OK, "Command" is mispelled
register("Shift+a+b",    () => {}, mainWindow) // Not OK, you can't use two key codes ("a" and "b")
register("CmdOrCtrl+aa", () => {}, mainWindow) // Not OK, "aa" is not a valid key code

Validation rules

The same validation rules used for Electron Accelerators are used here. In essence, for a string to be a valid Accelerator it needs:

Platform specific behavior

From the official Electron Accelerator docs

On Linux and Windows, the Command key does not have any effect so use CommandOrControl which represents Command on macOS and Control on Linux and Windows to define some accelerators.

Use Alt instead of Option. The Option key only exists on macOS, whereas the Alt key is available on all platforms.

The Super key is mapped to the Windows key on Windows and Linux and Cmd on macOS.

Because of the second point, we decided to remove Option as a valid Modifier. Just use Alt and avoid any unwanted behaviour on different platforms.

APIs

The library exposed the following APIs

export declare const isRegisteredLocal: <S extends string>(accelerator: Accelerator<S>, window: BrowserWindow) => boolean
export declare const isRegisteredOnAll: <S extends string>(accelerator: Accelerator<S>) => boolean
export declare const isRegisteredGlobal: <S extends string>(accelerator: Accelerator<S>) => boolean

export declare const register: <S extends string>(accelerator: Accelerator<S>, f: () => void, window: BrowserWindow, options?: RegisterOptions) => void
export declare const unregister: <S extends string>(accelerator: Accelerator<S>, window: BrowserWindow) => void

export declare const registerOnAll: <S extends string>(accelerator: Accelerator<S>, f: () => void, options?: RegisterOptions) => void
export declare const unregisterOnAll: <S extends string>(accelerator: Accelerator<S>) => void

export declare const registerGlobal: <S extends string>(accelerator: Accelerator<S>, f: () => void) => void
export declare const unregisterGlobal: <S extends string>(accelerator: Accelerator<S>) => void

Usage

  • Local Shortcuts. In this case, local means that the shortcut will only be executed when the relevant key presses are made when the window is focused
const mainWindow = new BrowserWindow()
const anotherWindow = new BrowserWindow()

isRegisteredLocal("Cmd+a", mainWindow) // false

register("Cmd+a", () => console.log("a"), mainWindow)

isRegisteredLocal("Cmd+a", mainWindow) // true
isRegisteredLocal("Cmd+a", anotherWindow) // false

register("Cmd+a", () => console.log("b"), mainWindow) // override the previous one

unregister("Cmd+a", mainWindow) // remove shortcut from mainWindow
  • Local Shortcuts on all windows (current and future ones)
const mainWindow = new BrowserWindow()

isRegisteredOnAll("Cmd+a") // false

registerOnAll("Cmd+a", () => console.log("a"))

isRegisteredOnAll("Cmd+a") // true

const anotherWindow = new BrowserWindow() // this window will also have the shortcut enabled

registerOnAll("Cmd+a", () => console.log("b")) // override the previous one on all current and future windows

unregisterOnAll("Cmd+a") // remove shortcut from all current and future windows
  • Global Shortcuts. These functions are simply type-safe wrappers around the standard globalShortcut object exposed by Electron, note that shortcuts defined like this will be executed even when the application is not focused by the user
isRegisteredGlobal("Cmd+a") // false

registerGlobal("Cmd+a", () => console.log("a"))

isRegisteredGlobal("Cmd+a") // true

const anotherWindow = new BrowserWindow() // this window will also have the shortcut enabled

registerGlobal("Cmd+a", () => console.log("b")) // override the previous one
  • RegisterOptions

    • strict (default to false)
const mainWindow = new BrowserWindow()

register("Cmd+a", () => console.log("a"), mainWindow, { strict: false }) // will execute for Cmd+Shift+a
register("Cmd+a", () => console.log("b"), mainWindow, { strict: true }) // will not execute for Cmd+Shift+a

Contributing

Contributions of any kind are much appreciated!

Tests

Unit tests

npm run test:unit

End to end tests

npm run test:e2e