Mosmox UI
Current version
GitHubnpmjs.com
Foundations

Keyboard Shortcut

Platform-aware keyboard shortcut hints with optional global shortcut handling.

KeyboardShortcut renders a compact, accessible keyboard shortcut hint. Use it next to an action, in a menu, or anywhere users need to discover a faster way to work.

It can be used in two ways:

  • as a visual hint only, by passing keys;
  • as a functional global shortcut, by also passing onTrigger.

Installation

import { KeyboardShortcut } from '@mosmox/ui';

Display a shortcut

Pass a string such as Ctrl+K, a macOS notation such as ⌘K, or an array of key names:

<KeyboardShortcut keys="Ctrl+K" />
<KeyboardShortcut keys={['Ctrl', 'Shift', 'P']} />
<KeyboardShortcut keys="⌘K" variant="outline" />

The component renders each key as its own keycap. The default separator is + and can be changed with separator.

The parser accepts modifier aliases and common named keys. For example, Command, Cmd, and Meta render as ⌘; Control and Ctrl render as Ctrl; Option and Alt render as ⌥; Escape renders as Esc; and Return renders as Enter. A string containing + is split into tokens, while an array is flattened so both forms can be mixed.

<KeyboardShortcut keys="Command+Shift+P" />
<KeyboardShortcut keys={['Control', 'Alt', 'Delete']} separator=" · " />
<KeyboardShortcut keys="ArrowUp+ArrowDown" separator=" / " />

Platform-specific shortcuts

Use mac and win when the shortcut should look different on macOS and Windows/Linux. The default platform="auto" detects the current browser platform:

<KeyboardShortcut
  keys="Ctrl+K"
  mac="⌘K"
  win="Ctrl+K"
/>

You can force a platform for previews or tests with platform="mac" or platform="win". If the selected platform value is missing, the component falls back to keys.

Handle the shortcut

Add onTrigger to listen for the combination on window:

<KeyboardShortcut
  keys="Ctrl+K"
  mac="⌘K"
  onTrigger={() => setSearchOpen(true)}
/>

The listener is only installed when onTrigger is provided. Modifier keys (Ctrl, ⌘, Alt, ⌥, Shift, and ⌃) and common named keys such as Enter, Esc, Space, arrows, Delete, and function keys are supported.

By default, the event's browser action is prevented. Set preventDefault={false} to preserve it, or set stopPropagation when the event should not continue to other listeners.

Shortcuts ignore inputs, textareas, selects, and contenteditable elements by default so they do not interrupt text entry. Set ignoreEditable={false} when a shortcut must also work while editing.

The listener is cleaned up when the component unmounts or when any shortcut option changes. A disabled shortcut does not install a listener and is rendered with a disabled visual state. The component listens on window, so it is appropriate for application-level shortcuts; use a local key handler instead when the shortcut should only work inside one control.

Sizes and variants

<KeyboardShortcut keys="Esc" size="xs" />
<KeyboardShortcut keys="Ctrl+K" size="sm" />
<KeyboardShortcut keys="⌘+Shift+P" size="default" />

<KeyboardShortcut keys="Ctrl+S" variant="subtle" />
<KeyboardShortcut keys="Ctrl+S" variant="outline" />
<KeyboardShortcut keys="Ctrl+S" variant="solid" />

Available sizes are xs (extra small), sm (small), and default (the regular/full size). There is no lg size. Available variants are subtle, outline, and solid:

  • subtle uses the surface background and a light outline;
  • outline removes the filled surface and uses the current text color for the border;
  • solid uses the text color as the keycap background and the surface color for text.

The size affects the wrapper font size, keycap height, and horizontal/vertical padding. The visual variant does not change the keyboard matching behavior.

Accessibility

The wrapper is exposed as an image-like labelled element and adds aria-keyshortcuts with the active platform's keys. Pass label when the visible keycaps need a more descriptive accessible name:

<KeyboardShortcut keys="F1" label="Open help with F1" />

KeyboardShortcut describes the shortcut; it does not replace a visible button or command action. Pair it with a labelled control when the shortcut performs an action.

Combining a shortcut with an action

<button type="button" onClick={() => setSearchOpen(true)}>
  Search
  <KeyboardShortcut
    keys="Ctrl+K"
    mac="⌘K"
    variant="outline"
    label="Open search"
    onTrigger={() => setSearchOpen(true)}
  />
</button>

Keep the action itself keyboard accessible and use the shortcut as a hint. If the action is rendered inside an input or editor, decide explicitly whether ignoreEditable should remain enabled.

API reference

PropertyTypeDefaultDescription
keysstring | string[]—Base shortcut, such as Ctrl+K or ['Ctrl', 'K'].
macstring | string[]—macOS/iOS display and matching shortcut. Falls back to keys.
winstring | string[]—Windows/Linux display and matching shortcut. Falls back to keys.
platformauto | mac | winautoChooses the platform-specific shortcut or forces one for tests/previews.
onTrigger() => void—Called when the active shortcut is pressed. Installs the global listener.
preventDefaultbooleantruePrevents the browser default action when triggered.
stopPropagationbooleanfalseStops the keyboard event from reaching other listeners.
ignoreEditablebooleantrueIgnores shortcuts inside text-entry and contenteditable elements.
disabledbooleanfalseDisables the visual state and the keyboard listener.
sizexs | sm | defaultdefaultKeycap size: extra small, small, or default.
variantsubtle | outline | solidsubtleKeycap visual treatment.
separatorstring+Text rendered between keycaps.
labelstringgeneratedAccessible name for the shortcut.
classNamestring—Additional class name on the wrapper.

All other HTMLAttributes<HTMLSpanElement> are forwarded to the wrapper. The wrapper renders with role="img", an accessible label, and aria-keyshortcuts generated from the active platform tokens.