or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

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