@molecule/app-keyboard-shortcuts-react

Feature · keyboard-shortcuts · App (browser) · v1.0.3 · Apache-2.0

React hook for @molecule/app-keyboard-shortcuts — register a shortcut for the life of a component

npm install @molecule/app-keyboard-shortcuts-react

npm · Source on GitHub

How it works

@molecule/app-keyboard-shortcuts-react is a ready-made keyboard-shortcuts feature for the app (browser) side. It composes the core interfaces it needs, so it works with whichever providers your app has bonded.

import { useRef } from 'react'
import { useKeyboardShortcut } from '@molecule/app-keyboard-shortcuts-react'

function Search() {
  const input = useRef<HTMLInputElement>(null)
  useKeyboardShortcut('/', () => input.current?.focus(), {
    description: t('catalogSearch.focus', undefined, { defaultValue: 'Focus search' }),
  })
  useKeyboardShortcut('mod+k', () => openPalette())
  return <input ref={input} />
}

Works with: @molecule/app-keyboard-shortcuts

Reference

React hook for @molecule/app-keyboard-shortcuts.

useKeyboardShortcut registers a shortcut with the bonded provider for the life of a component and always calls the latest handler, so a component can bind / to focus its search box or mod+k to open a palette in one line.

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Quick Start

import { useRef } from 'react'
import { useKeyboardShortcut } from '@molecule/app-keyboard-shortcuts-react'

function Search() {
  const input = useRef<HTMLInputElement>(null)
  useKeyboardShortcut('/', () => input.current?.focus(), {
    description: t('catalogSearch.focus', undefined, { defaultValue: 'Focus search' }),
  })
  useKeyboardShortcut('mod+k', () => openPalette())
  return <input ref={input} />
}

Type

feature

Installation

npm install @molecule/app-keyboard-shortcuts-react @molecule/app-keyboard-shortcuts react
npm install -D @types/react

API

Interfaces

UseKeyboardShortcutOptions

Options for useKeyboardShortcut.

interface UseKeyboardShortcutOptions {
  /** Register the shortcut at all. `false` unregisters it. Defaults to `true`. */
  enabled?: boolean

  /** What the shortcut does, already translated, for a shortcuts panel. */
  description?: string

  /** The provider scope to register under. */
  scope?: string

  /** Call `preventDefault()` on the event. Defaults to `true`. */
  preventDefault?: boolean
}

Functions

useKeyboardShortcut(keys, handler, options)

Registers keys with the bonded keyboard-shortcuts provider while the component is mounted, and unregisters on unmount or when enabled turns false. The latest handler is always the one called, so it need not be memoized. With no provider bonded the hook does nothing.

function useKeyboardShortcut(
  keys: string | string[],
  handler: (event: KeyboardEvent) => void,
  options?: UseKeyboardShortcutOptions,
): void
  • keys — One combination or several ('mod+k' is expanded to ctrl+k and command+k).
  • handler — Called with the keyboard event.
  • options — Enable flag, description, scope, preventDefault.

expandKeys(keys)

Normalizes a key spec: 'mod+k' becomes both ctrl+k and command+k, so one declaration serves every platform.

function expandKeys(keys: string | string[]): string[]
  • keys — One combination or several.

Returns: The combinations to register.

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-keyboard-shortcuts ^1.0.1
  • react ^18.0.0 || ^19.0.0

Runtime Dependencies

  • @molecule/app-keyboard-shortcuts

  • react

  • mod+ means Ctrl on Windows and Linux, Command on macOS — the hook registers both, so never write ctrl+k for a shortcut people expect as ⌘K on a Mac.

  • Whether a shortcut fires while an input has focus is the bond's decision (the hotkeys bond suppresses it, which is what / needs). Keys the input itself should handle — Escape to clear, arrows to move — belong on the input's onKeyDown, not here.

  • With no provider bonded the hook is a no-op rather than an error, so a shared component still renders in an app that never wired shortcuts.

  • The description is shown by shortcut panels: pass it through t().