CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-hotkeys-js

A simple micro-library for defining and dispatching keyboard shortcuts with no dependencies

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

Hotkeys-js

Hotkeys-js is a simple micro-library for defining and dispatching keyboard shortcuts in web applications. It provides a comprehensive API for capturing keyboard events with support for modifier keys, key combinations, scopes for context-specific shortcuts, and flexible filtering options.

Package Information

  • Package Name: hotkeys-js
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install hotkeys-js

Core Imports

ES Modules:

import hotkeys from 'hotkeys-js';

CommonJS:

const hotkeys = require('hotkeys-js');

Browser (CDN):

<script src="https://unpkg.com/hotkeys-js/dist/hotkeys.min.js"></script>

Basic Usage

import hotkeys from 'hotkeys-js';

// Simple shortcut
hotkeys('ctrl+a', function (event, handler) {
  console.log('Select all triggered');
});

// Multiple key combinations
hotkeys('ctrl+s, command+s', function (event, handler) {
  event.preventDefault();
  console.log('Save triggered');
});

// With scope for context-specific shortcuts
hotkeys('enter', 'editing', function (event, handler) {
  console.log('Enter pressed in editing mode');
});

// Set active scope
hotkeys.setScope('editing');

Architecture

Hotkeys-js is built around several key architectural components:

  • Event System: Global keyboard event listeners with element-specific binding support
  • Key Mapping Engine: Comprehensive key code translation supporting special keys, modifiers, and cross-browser compatibility
  • Scope Management: Context-aware shortcut system allowing the same keys to perform different actions in different application states
  • Handler Registry: Efficient storage and lookup system for registered keyboard shortcuts with support for key combinations and modifier keys
  • Filtering System: Customizable event filtering to control when shortcuts are active (e.g., excluding form inputs by default)
  • State Tracking: Real-time tracking of pressed keys and modifier states for advanced use cases

Capabilities

Main Hotkey Function

Define keyboard shortcuts with flexible options for key combinations, scopes, and handler functions.

/**
 * Register a keyboard shortcut with a handler function
 * @param key - Key combination string (e.g., 'ctrl+s', 'f1', 'ctrl+shift+a')
 * @param method - Handler function called when shortcut is triggered
 */
hotkeys(key: string, method: KeyHandler): void;

/**
 * Register a keyboard shortcut with a specific scope
 * @param key - Key combination string
 * @param scope - Scope name for context-specific shortcuts
 * @param method - Handler function called when shortcut is triggered
 */
hotkeys(key: string, scope: string, method: KeyHandler): void;

/**
 * Register a keyboard shortcut with advanced options
 * @param key - Key combination string
 * @param options - Configuration options for the shortcut
 * @param method - Handler function called when shortcut is triggered
 */
hotkeys(key: string, options: Options, method: KeyHandler): void;

Scope Management

Manage different contexts for keyboard shortcuts, allowing the same keys to perform different actions in different application states.

/**
 * Set the current active scope. Only shortcuts in 'all' and active scope will trigger
 * @param scopeName - Name of the scope to activate
 */
setScope(scopeName: string): void;

/**
 * Get the current active scope name
 * @returns The current scope name (defaults to 'all')
 */
getScope(): string;

/**
 * Delete a scope and all associated shortcuts
 * @param scopeName - Name of the scope to delete
 * @param newScopeName - Optional new scope to set after deletion
 */
deleteScope(scopeName: string, newScopeName?: string): void;

Key State Queries

Check the current state of pressed keys and retrieve information about active shortcuts.

/**
 * Check if a specific key is currently pressed
 * @param keyCode - Key code number or key string to check
 * @returns True if the key is currently pressed
 */
isPressed(keyCode: number | string): boolean;

/**
 * Get array of key codes currently pressed
 * @returns Array of numeric key codes for currently pressed keys
 */
getPressedKeyCodes(): number[];

/**
 * Get array of key string representations currently pressed
 * @returns Array of string representations of currently pressed keys
 */
getPressedKeyString(): string[];

/**
 * Get list of all registered shortcut key combinations with their metadata
 * @returns Array of registered shortcuts with scope, shortcut, mods, and keys
 */
getAllKeyCodes(): Omit<HotkeysEvent, 'method' | 'key'>[];

Event Management

Control shortcut bindings and programmatically trigger shortcuts.

/**
 * Remove all keyboard shortcut bindings
 */
unbind(): void;

/**
 * Remove keyboard shortcut bindings for a specific key
 * @param key - Key combination to unbind
 */
unbind(key: string): void;

/**
 * Remove keyboard shortcut bindings for a key in a specific scope
 * @param key - Key combination to unbind
 * @param scopeName - Scope name to unbind from
 */
unbind(key: string, scopeName: string): void;

/**
 * Remove a specific handler for a key in a specific scope
 * @param key - Key combination to unbind
 * @param scopeName - Scope name to unbind from
 * @param method - Specific handler function to remove
 */
unbind(key: string, scopeName: string, method: KeyHandler): void;

/**
 * Remove a specific handler for a key
 * @param key - Key combination to unbind
 * @param method - Specific handler function to remove
 */
unbind(key: string, method: KeyHandler): void;

/**
 * Programmatically trigger a keyboard shortcut
 * @param shortcut - Shortcut string to trigger
 * @param scope - Optional scope to trigger within
 */
trigger(shortcut: string, scope?: string): void;

/**
 * Filter function to determine if hotkeys should be active for given events
 * Can be overridden to customize filtering behavior
 * @param event - Keyboard event to filter
 * @returns True if hotkeys should be active, false otherwise
 */
filter(event: KeyboardEvent): boolean;

Utility Methods

Additional utility functions for library management and conflict resolution.

/**
 * Release control of global 'hotkeys' variable and return hotkeys reference
 * @param deep - Optional flag for deep conflict resolution
 * @returns Reference to the hotkeys function
 */
noConflict(deep?: boolean): Hotkeys;

Properties

Modifier Key State Flags

Boolean properties indicating the current state of modifier keys.

hotkeys.shift: boolean;     // Shift key state
hotkeys.ctrl: boolean;      // Ctrl key state
hotkeys.alt: boolean;       // Alt key state
hotkeys.option: boolean;    // Option key state (alias for alt)
hotkeys.control: boolean;   // Control key state (alias for ctrl)
hotkeys.cmd: boolean;       // Command key state
hotkeys.command: boolean;   // Command key state (alias for cmd)

Key Mapping Objects

Objects containing mappings between key names and key codes.

hotkeys.keyMap: Record<string, number>;         // Map of key names to key codes
hotkeys.modifier: Record<string, number>;       // Map of modifier key names to codes
hotkeys.modifierMap: Record<string, number | string>; // Bidirectional modifier mapping

Types

interface HotkeysEvent {
  key: string;      // The pressed key
  keys: number[];   // Array of pressed key codes
  method: KeyHandler; // The handler function
  mods: number[];   // Modifier key codes
  scope: string;    // Current scope
  shortcut: string; // The shortcut string
}

type KeyHandler = (keyboardEvent: KeyboardEvent, hotkeysEvent: HotkeysEvent) => void | boolean;

type Options = {
  scope?: string;           // Scope name
  element?: HTMLElement | null; // Target element
  keyup?: boolean | null;   // Listen to keyup events
  keydown?: boolean | null; // Listen to keydown events
  capture?: boolean;        // Use capture phase
  splitKey?: string;        // Key combination separator
  single?: boolean;         // Single callback only
}

Supported Keys

Special Keys

  • Navigation: left, right, up, down, arrowup, arrowdown, arrowleft, arrowright
  • Function Keys: f1 through f19
  • Editing: backspace, delete, del, insert, ins, home, end, pageup, pagedown
  • Control: tab, enter, return, esc, escape, space, clear, capslock
  • Numpad: num_0 through num_9, num_multiply, num_add, num_enter, num_subtract, num_decimal, num_divide

Modifier Keys

  • Shift: shift,
  • Alt/Option: alt, option,
  • Control: ctrl, control,
  • Command/Meta: cmd, command, meta,

Key Combinations

Use + to combine keys: ctrl+s, ctrl+shift+z, command+option+i

Use , to define multiple shortcuts for the same handler: ctrl+s, command+s

Usage Examples

Scope Management

// Define shortcuts with different scopes
hotkeys('ctrl+z', 'editing', function() {
  console.log('Undo in editing mode');
});

hotkeys('ctrl+z', 'viewing', function() {
  console.log('Undo in viewing mode');
});

// Switch between scopes
hotkeys.setScope('editing'); // Only 'all' and 'editing' shortcuts active
hotkeys.setScope('viewing');  // Only 'all' and 'viewing' shortcuts active

Advanced Options

// Listen only to keyup events
hotkeys('space', { keyup: true }, function(event, handler) {
  console.log('Space released');
});

// Target specific element
hotkeys('enter', { 
  element: document.getElementById('search-input'),
  scope: 'search' 
}, function(event, handler) {
  console.log('Enter in search input');
});

Filtering Events

// Customize filtering to allow hotkeys in contentEditable elements
hotkeys.filter = function(event) {
  const target = event.target || event.srcElement;
  const tagName = target.tagName;
  // Allow hotkeys in contentEditable but not in inputs
  return !(tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA');
};

Key State Checking

hotkeys('ctrl+shift+d', function(event, handler) {
  // Check what other keys are pressed
  const pressedCodes = hotkeys.getPressedKeyCodes();
  const pressedKeys = hotkeys.getPressedKeyString();
  
  console.log('Pressed key codes:', pressedCodes);
  console.log('Pressed keys:', pressedKeys);
  
  // Check specific key
  if (hotkeys.isPressed('m')) {
    console.log('M key is also pressed');
  }
});

Browser Compatibility

  • Internet Explorer 6+
  • Chrome (all versions)
  • Firefox (all versions)
  • Safari (all versions)
  • Opera (all versions)

Features

  • Zero Dependencies: No external dependencies required
  • Small Footprint: ~6kB uncompressed, 2.8kB gzipped
  • TypeScript Support: Complete type definitions included
  • Flexible API: Multiple ways to define shortcuts and options
  • Scope Management: Context-aware shortcut handling
  • Cross-browser: Works across all major browsers
  • Customizable Filtering: Override default behavior for form elements
  • Programmatic Control: Trigger shortcuts programmatically and check key states
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/hotkeys-js@3.13.x
Publish Source
CLI
Badge
tessl/npm-hotkeys-js badge