import * as React from 'react'; import { Card, Text, InlineNotice } from '@box/blueprint-web'; import Button from '../button/Button'; import Modal from '../modal/Modal'; import ModalActions from '../modal/ModalActions'; import HotkeyLayer from './HotkeyLayer'; import HotkeyRecord from './HotkeyRecord'; export const Hotkeys = () => { const [message, setMessage] = React.useState('Press keys to see actions'); const [count, setCount] = React.useState(0); const [baseMessage, setBaseMessage] = React.useState('Base layer active'); const [modalMessage, setModalMessage] = React.useState('Modal layer active'); const [isModalOpen, setIsModalOpen] = React.useState(false); const [action, setAction] = React.useState('No action yet'); const baseHotkeys = [ // Basic single key hotkeys new HotkeyRecord({ key: 'a', handler: () => { setMessage('Hotkey "a" was pressed!'); setCount(c => c + 1); }, description: 'Show a message', type: 'navigation', }), new HotkeyRecord({ key: 'b', handler: () => { setMessage('Hotkey "b" was pressed!'); setCount(c => c + 1); }, description: 'Show another message', type: 'navigation', }), new HotkeyRecord({ key: 'c', handler: () => { setCount(0); setMessage('Count reset!'); }, description: 'Reset counter', type: 'actions', }), // Navigation hotkeys new HotkeyRecord({ key: 'n', handler: () => { setAction('Next item'); }, description: 'Go to next item', type: 'navigation', }), new HotkeyRecord({ key: 'p', handler: () => { setAction('Previous item'); }, description: 'Go to previous item', type: 'navigation', }), // Action hotkeys new HotkeyRecord({ key: 's', handler: () => { setAction('Save changes'); }, description: 'Save', type: 'actions', }), new HotkeyRecord({ key: 'd', handler: () => { setAction('Delete item'); }, description: 'Delete', type: 'actions', }), // Key combinations new HotkeyRecord({ key: 'ctrl+s', handler: event => { event.preventDefault(); setAction('Save (Ctrl+S)'); }, description: 'Save document', type: 'actions', }), new HotkeyRecord({ key: 'shift+a', handler: event => { event.preventDefault(); setAction('Select All (Shift+A)'); }, description: 'Select all items', type: 'actions', }), new HotkeyRecord({ key: ['ctrl+z', 'meta+z'], handler: () => { setAction('Undo (Ctrl+Z or Cmd+Z)'); }, description: 'Undo last action', type: 'actions', }), new HotkeyRecord({ key: 'alt+n', handler: event => { event.preventDefault(); setAction('New (Alt+N)'); }, description: 'Create new item', type: 'actions', }), // Hidden hotkey (no type) new HotkeyRecord({ key: 'h', handler: () => { setMessage('Hidden hotkey pressed'); }, description: null, // Hidden hotkey }), // Open modal new HotkeyRecord({ key: 'o', handler: () => { setIsModalOpen(true); }, description: 'Open modal', type: 'base', }), // Base layer action that will be overridden by modal new HotkeyRecord({ key: 'x', handler: () => { setBaseMessage('Base hotkey "x" pressed'); }, description: 'Base layer action', type: 'base', }), ]; const modalHotkeys = [ new HotkeyRecord({ key: 'x', handler: () => { setModalMessage('Modal hotkey "x" pressed (overrides base)'); }, description: 'Modal layer action', type: 'modal', }), new HotkeyRecord({ key: 'esc', handler: () => { setIsModalOpen(false); }, description: 'Close modal', type: 'modal', }), new HotkeyRecord({ key: 's', handler: () => { setAction('Save from modal'); }, description: 'Save in modal', type: 'modal', }), ]; return (
Hotkeys Basic: a b c Navigation: n p Actions: s d Combinations: Ctrl+S Shift+A{' '} Alt+N Hidden: h (not shown in help modal) Modal: o to open, esc to close Help: ? to see all hotkeys Status Message: {message} Hotkeys triggered: {count} Last action: {action} Base Layer: {baseMessage} Modal Layer: {modalMessage}
  • Basic hotkeys: Single key presses (a, b, c)
  • Help modal: Press ? to see all available hotkeys organized by type
  • Multiple types: Hotkeys categorized as navigation, actions, base, modal
  • Hidden hotkeys: Press h - it works but won't show in help modal (no type)
  • Key combinations: Modifier keys like Ctrl+S, Shift+A, Alt+N
  • Multiple bindings: Ctrl+Z (Windows/Linux) or Cmd+Z (Mac) for the same action
  • Nested layers: Press o to open modal - it has its own hotkey layer that overrides base layer hotkeys
{isModalOpen && ( setIsModalOpen(false)} title="Modal Layer (Active)" > This modal has its own hotkey layer that overrides the base layer.
  • Press x - triggers modal action (not base action)
  • Press s - saves from modal context
  • Press esc - closes modal
  • Press ? - see only modal hotkeys in help
Notice how base layer hotkeys (like a, b) don't work here - the modal layer blocks them!
)}
); }; export default { title: 'Components/Hotkeys', component: HotkeyLayer, parameters: { notes: 'The Hotkey system allows you to register keyboard shortcut handlers. ' + 'Press "?" to open the help modal. ' + 'This demo shows all hotkey features: basic hotkeys, help modal, multiple types, ' + 'hidden hotkeys, key combinations, multiple bindings, and nested layers.', }, };