Skip to content

React Quick Start

This guide shows how to use @keekuun/keymaster-react to register keyboard shortcuts in React projects, with basic examples.

Installation

💡 Version Notice: The documentation shows the latest version (v0.5.0). If you need a specific version, check the Version Management documentation or all versions on npm.

Install Latest Version

bash
npm install @keekuun/keymaster-react
# or
pnpm add @keekuun/keymaster-react

Install Specific Version

If you need a specific version (e.g., 0.1.0), specify the version:

bash
npm install @keekuun/keymaster-react@0.1.0
# or
pnpm add @keekuun/keymaster-react@0.1.0

⚠️ Note: If using an older version, some APIs in the documentation may not be available. Check the README for that version (on the npm package page) or the Version Management documentation.

Basic Example: Save Shortcut Ctrl+S

The following example shows how to bind save logic to Ctrl+S in an editor component:

tsx
import React from 'react';
import { useKeyBinding } from '@keekuun/keymaster-react';

function Editor() {
  useKeyBinding(
    'ctrl+s',
    () => {
      // Execute save logic here, e.g., call API / update local state
      console.log('Saved successfully');
    },
    { preventDefault: true }, // Prevent browser's default save page behavior
  );

  return <textarea placeholder="Type here, then press Ctrl+S to save"></textarea>;
}

export default Editor;

To verify the behavior in your application, simply mount the Editor component to the page, then press Ctrl+S in the browser to observe the console output or whether your actual save logic is triggered.

Try it out:

Multiple Shortcuts

You can also call useKeyBinding multiple times in the same component to bind different behaviors to different shortcuts:

tsx
import React from 'react';
import { useKeyBinding } from '@keekuun/keymaster-react';

function Editor() {
  useKeyBinding(
    'ctrl+s',
    () => {
      saveContent();
    },
    { preventDefault: true },
  );

  useKeyBinding('ctrl+z', () => {
    undo();
  });

  useKeyBinding('ctrl+shift+z', () => {
    redo();
  });

  return <textarea />;
}

Interactive Demo:

Advanced APIs

Scoped Shortcuts (scopedElement)

When you need to bind shortcuts within a specific element scope (e.g., editors, dialogs), you can use the scopedElement option:

tsx
import React, { useRef } from 'react';
import { useKeyBinding } from '@keekuun/keymaster-react';

function Editor() {
  const editorRef = useRef<HTMLTextAreaElement>(null);

  // Only works within the editor area
  useKeyBinding(
    'ctrl+s',
    () => {
      console.log('Save editor content');
    },
    {
      scopedElement: editorRef.current,
      preventDefault: true,
    },
  );

  return <textarea ref={editorRef} placeholder="Press Ctrl+S to save" />;
}

Or use the convenient useScopedKeyBinding Hook:

tsx
import { useScopedKeyBinding } from '@keekuun/keymaster-react';

const containerRef = useRef<HTMLDivElement>(null);
useScopedKeyBinding(
  'ctrl+k',
  () => {
    console.log('Only works within container');
  },
  containerRef,
);

Interactive Demo:

Editor Mode

Editor mode automatically handles common shortcut conflicts, especially suitable for code editors, rich text editors, and similar scenarios:

tsx
import { useEditorKeyBinding } from '@keekuun/keymaster-react';

function CodeEditor() {
  const editorRef = useRef<HTMLTextAreaElement>(null);

  // Editor mode automatically prevents default behavior
  useEditorKeyBinding(
    'ctrl+s',
    () => {
      saveCode();
    },
    editorRef.current,
  );

  useEditorKeyBinding(
    'ctrl+z',
    () => {
      undo();
    },
    editorRef.current,
  );

  return <textarea ref={editorRef} />;
}

Interactive Demo:

Electron Mode

In Electron applications, you can use useElectronKeyBinding to adapt shortcut coordination between the main process and renderer process:

tsx
import { useElectronKeyBinding } from '@keekuun/keymaster-react';

function ElectronApp() {
  useElectronKeyBinding(
    'ctrl+alt+r',
    () => {
      // Your Electron logic here, e.g. via bridge / ipc
      window.electron?.ipcRenderer?.send('shortcut:reload');
    },
    {
      electronHook: ({ parsed, processInfo, versions }) => {
        console.log('[electron shortcut]', parsed, processInfo, versions);
        // return false here if you want to stop further handling
        return true;
      },
    },
  );

  return <div>Electron App</div>;
}

Electron Hook (electronHook)

When using Electron mode, you can optionally provide an electronHook to collect environment information or intercept handling:

ts
useElectronKeyBinding('ctrl+alt+r', handler, {
  electronHook: ({ event, parsed, processInfo, versions }) => {
    // custom logging / monitoring
    if (!versions?.electron) return false; // cancel handling if environment is unexpected
    return true;
  },
});

Interactive Demo:

Electron Mode Demo

Electron mode adapts to desktop application scenarios, allowing you to extend or intercept Electron-specific behaviors via electronHook.

Current Environment:Browser Environment (Demo Only)

Try these shortcuts (will trigger hook in Electron environment):

Ctrl+Alt+R Reload
Ctrl+Shift+I DevTools

Last triggered:None

Shortcut Combination Management

Use KeyBindingManager to manage a group of related shortcut bindings:

tsx
import { useEffect } from 'react';
import { createKeyBindingManager, isValidShortcut, formatShortcut } from '@keekuun/keymaster-react';

function Editor() {
  useEffect(() => {
    const manager = createKeyBindingManager();

    // Chain register multiple shortcuts
    manager
      .register('ctrl+s', () => save(), { preventDefault: true })
      .register('ctrl+z', () => undo())
      .register('ctrl+shift+z', () => redo());

    // Automatically clean up all bindings when component unmounts
    return () => manager.dispose();
  }, []);

  return <textarea />;
}

Utility functions:

  • isValidShortcut(shortcut): Check if shortcut format is valid
  • formatShortcut(shortcut): Format shortcut string (normalize case)

Interactive Demo:

API Overview

useKeyBinding(shortcut, handler, options?)

  • shortcut: string - Shortcut string, e.g., "ctrl+s", "ctrl+shift+z"
  • handler: (event: KeyboardEvent) => void - Callback triggered when matching shortcut is detected
  • options: KeymasterBindingOptions (optional)
    • preventDefault?: boolean - Whether to call event.preventDefault() after trigger
    • stopPropagation?: boolean - Whether to call event.stopPropagation() after trigger
    • scopedElement?: HTMLElement | null - Scoped element, shortcut only works within element
    • editorMode?: boolean - Editor mode, automatically handles shortcut conflicts
    • electronMode?: boolean - Electron mode, adapts for Electron applications

Current versions: React v0.5.0 / Vue v0.5.0 / Core v0.5.0