Service for binding keyboard shortcuts to execute commands

A keybinding is a sequence or key combination on a computer keyboard which invokes commands. This service supports key bindings as a way of responding to individual keys typed by a user. The key combination can be pressing a single key or a sequence of keys one after the other.

The service works together with the CommandBus to execute the commands and a command needs to already be registered on the command bus in order to be bound as a keyboard shortcut.

Keybindings are scoped to the component that creates them and should be cleaned up when the component is removed from the DOM to prevent memory leaks and unintended behavior.

Key Combination Format

Key combinations can be:

  • Single keys: 'a', 'enter', 'escape'
  • Modifier combinations: 'ctrl+s', 'alt+shift+n', 'meta+k'
  • Sequences: 'g i' (press 'g' then 'i')

Supported modifiers: ctrl, alt, shift, meta (Command on Mac)

Example

Binding a command to a key combination

const saveCommand = new SaveCommand();
commandBus.register(SaveCommand, { handle: (cmd) => handleSave(cmd) });
const registry = platform.get(PlatformServiceName.KeybindingRegistry);
registry.bind('ctrl+s', saveCommand);

Example

Checking for conflicts before binding

const registry = platform.get(PlatformServiceName.KeybindingRegistry);
if (!registry.isBound('j')) {
registry.bind('j', navigateNextCommand);
}

Example

Vim-style key sequences

const registry = platform.get(PlatformServiceName.KeybindingRegistry);
registry.bind('g i', goToInboxCommand);
registry.bind('g s', goToSentCommand);
registry.bind('g d', goToDraftsCommand);

Example

Usage in a component

class MyComponent {
private saveCommand = new SaveCommand();

connectedCallback() {
this.keybindingRegistry.bind('ctrl+s', this.saveCommand);
}

disconnectedCallback() {
this.keybindingRegistry.unbind('ctrl+s', this.saveCommand);
}

private get keybindingRegistry() {
return this.platform.get(PlatformServiceName.KeybindingRegistry);
}
}

Note

This service is work in progress

Hierarchy

  • KeybindingRegistry

Properties

bind: ((keys: string, command: object) => void)

Type declaration

    • (keys: string, command: object): void
    • Bind a command to a specific key combination to add it to the registry

      When a user presses the specified key combination, the command will be dispatched through the CommandBus. The command must already have a handler registered on the command bus before binding.

      If the same key combination is bound to multiple commands, all commands will be executed in the order they were registered.

      Throws

      Will throw an error if the command is invalid or not registered on the command bus

      Example

      const command = new SaveCommand();
      const registry = platform.get(PlatformServiceName.KeybindingRegistry);
      registry.bind('ctrl+s', command);

      Parameters

      • keys: string

        the string representation of keys (e.g., 'ctrl+s', 'alt+shift+n', 'g i')

      • command: object

        the command instance to trigger when keys are pressed

      Returns void

getKeybindings: (() => Keybinding[])

Type declaration

    • (): Keybinding[]
    • Get a list of the key bindings that are currently in the registry

      Returns all active keybindings across all components. Useful for debugging, displaying keyboard shortcuts to users, or detecting conflicts.

      Returns

      the list of all active keybindings with their commands

      Example

      const registry = platform.get(PlatformServiceName.KeybindingRegistry);
      const bindings = registry.getKeybindings();
      bindings.forEach(binding => {
      console.log(`${binding.keys}${binding.command}`);
      });

      Returns Keybinding[]

isBound: ((keys: string, command?: object) => boolean)

Type declaration

    • (keys: string, command?: object): boolean
    • Checks if a key combination or a specific keybinding is already bound

      Use this method to detect conflicts before binding new keybindings. When called with just a key combination, returns true if any command is bound to those keys. When called with both keys and a command, returns true only if that specific combination exists.

      Returns

      true if the key combination is bound (to any or the specified command), false otherwise

      Example

      Check if any command is bound to keys

      const registry = platform.get(PlatformServiceName.KeybindingRegistry);
      if (registry.isBound('ctrl+s')) {
      console.warn('ctrl+s is already bound');
      }

      Example

      Check if a specific command is bound to keys

      const registry = platform.get(PlatformServiceName.KeybindingRegistry);
      if (registry.isBound('ctrl+s', saveCommand)) {
      console.log('Save command is bound to ctrl+s');
      }

      Parameters

      • keys: string

        the string representation of a key combination (e.g., 'ctrl+s')

      • Optional command: object

        optional command instance to check for a specific binding

      Returns boolean

unbind: ((keys: string, command: object) => void)

Type declaration

    • (keys: string, command: object): void
    • Unbind a keybinding to remove it from the registry

      Removes the association between a key combination and a command. After unbinding, pressing the key combination will no longer trigger the command. This is essential for cleanup when components are removed from the DOM.

      If multiple commands are bound to the same key combination, only the specified command will be unbound.

      Example

      const registry = platform.get(PlatformServiceName.KeybindingRegistry);
      registry.unbind('ctrl+s', saveCommand);

      Parameters

      • keys: string

        the string representation of the key combination (e.g., 'ctrl+s')

      • command: object

        the command instance connected to the key combination

      Returns void