UnflowUI
ComponentsHooks

useHotkey

Detects a keyboard combo and fires an action callback. Returns platform-aware visual representations of the keys for use in Shortcut or tooltips.

Overview

useHotkey registers a global keydown listener for a combination of keys and fires a callback when all specified keys are held simultaneously. It also returns ReactNode[] representations of the keys — with modifier keys rendered as SVG icons on macOS and as text labels on Windows — ready to pass to the Shortcut component.

useHotkey is used internally by Shortcut and ActionCard. You can also call it directly when you need keyboard listener logic without the visual badge.

Import

import { useHotkey } from '@unflow/ui/hooks/useHotkey';

Parameters

ParamTypeDefaultDescription
keysstring[]undefinedKeys in MDN KeyboardEvent.key format
action() => voidundefinedCallback to fire when the combo is pressed
listenbooleanfalseEnables/disables the listener
allowRepeatbooleanfalseFire on key repeat (holding the key)

Return value

FieldTypeDescription
activebooleanWhether all keys are currently held
isHotkeyValidbooleanWhether the config is complete and listening
hotkeyReactNode[]Platform-rendered key labels

Usage

Basic global shortcut

const { hotkey } = useHotkey({
  keys: ['Meta', 'k'],
  action: openSearch,
  listen: true,
});

// Render the shortcut badge manually
return <div className="flex gap-1">{hotkey}</div>;

Conditional listener

const { isHotkeyValid, hotkey } = useHotkey({
  keys: selectedKeys,
  action: performAction,
  listen: isDialogOpen,  // only active while dialog is open
});

Check validity before rendering

isHotkeyValid is true only when listen is true, keys is non-empty, and action is defined. Use it to conditionally render the shortcut badge:

{isHotkeyValid && (
  <div className="flex gap-0.5">{hotkey}</div>
)}

Key naming

Keys follow MDN KeyboardEvent.key:

['Meta', 'k']            // ⌘K
['Control', 'Shift', 's'] // ⌃⇧S
['Alt', 'p']              // ⌥P (Mac) or Alt+P (Win)
['Enter']                 // Enter

Platform awareness

KeymacOS renderWindows render
Meta⌘ SVG iconWin
Alt⌥ SVG iconAlt
Control⌃ SVG iconCtrl
Shift⇧ SVG iconShift
OtherUppercase textUppercase text

Platform is detected via navigator.platform at runtime.

Blacklisted keys

The following keys are silently ignored and will result in isHotkeyValid: false:

  • Arrow keys (ArrowDown, ArrowUp, ArrowLeft, ArrowRight)
  • Escape
  • , (comma — used as a separator in some key string formats)

These conflict with focus management (arrows, Escape) and could cause unexpected behavior if registered globally.

Normalization

Keys are lowercased and sorted before registration. This means:

useHotkey({ keys: ['Control', 'K'] })
useHotkey({ keys: ['k', 'control'] })
// Both register the same combo

Implementation notes

The hook attaches a single document.addEventListener('keydown', …) per combo. When multiple components call useHotkey with the same combo, each registers its own listener — there is no global deduplication. Use listen to ensure only one listener is active at a time when using the same combo in multiple places.