box-ui-elements
Version:
Box UI Elements
188 lines • 10.4 kB
JavaScript
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 /*#__PURE__*/React.createElement(HotkeyLayer, {
configs: baseHotkeys,
enableHelpModal: true,
helpModalShortcut: "?"
}, /*#__PURE__*/React.createElement(Card, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Card, null, /*#__PURE__*/React.createElement(Text, {
as: "h2"
}, "Hotkeys"), /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement("strong", null, "Basic:"), " ", /*#__PURE__*/React.createElement("kbd", null, "a"), " ", /*#__PURE__*/React.createElement("kbd", null, "b"), " ", /*#__PURE__*/React.createElement("kbd", null, "c")), /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement("strong", null, "Navigation:"), " ", /*#__PURE__*/React.createElement("kbd", null, "n"), " ", /*#__PURE__*/React.createElement("kbd", null, "p")), /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement("strong", null, "Actions:"), " ", /*#__PURE__*/React.createElement("kbd", null, "s"), " ", /*#__PURE__*/React.createElement("kbd", null, "d")), /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement("strong", null, "Combinations:"), " ", /*#__PURE__*/React.createElement("kbd", null, "Ctrl"), "+", /*#__PURE__*/React.createElement("kbd", null, "S"), " ", /*#__PURE__*/React.createElement("kbd", null, "Shift"), "+", /*#__PURE__*/React.createElement("kbd", null, "A"), ' ', /*#__PURE__*/React.createElement("kbd", null, "Alt"), "+", /*#__PURE__*/React.createElement("kbd", null, "N")), /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement("strong", null, "Hidden:"), " ", /*#__PURE__*/React.createElement("kbd", null, "h"), " (not shown in help modal)"), /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement("strong", null, "Modal:"), " ", /*#__PURE__*/React.createElement("kbd", null, "o"), " to open, ", /*#__PURE__*/React.createElement("kbd", null, "esc"), " to close"), /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement("strong", null, "Help:"), " ", /*#__PURE__*/React.createElement("kbd", null, "?"), " to see all hotkeys")), /*#__PURE__*/React.createElement(Card, null, /*#__PURE__*/React.createElement(Text, {
as: "h2"
}, "Status"), /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement("strong", null, "Message:"), " ", message), /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement("strong", null, "Hotkeys triggered:"), " ", count), /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement("strong", null, "Last action:"), " ", action), /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement("strong", null, "Base Layer:"), " ", baseMessage), /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement("strong", null, "Modal Layer:"), " ", modalMessage))), /*#__PURE__*/React.createElement(InlineNotice, {
title: "Features Demonstrated",
type: "info"
}, /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("strong", null, "Basic hotkeys:"), " Single key presses (a, b, c)"), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("strong", null, "Help modal:"), " Press ", /*#__PURE__*/React.createElement("kbd", null, "?"), " to see all available hotkeys organized by type"), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("strong", null, "Multiple types:"), " Hotkeys categorized as navigation, actions, base, modal"), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("strong", null, "Hidden hotkeys:"), " Press ", /*#__PURE__*/React.createElement("kbd", null, "h"), " - it works but won't show in help modal (no type)"), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("strong", null, "Key combinations:"), " Modifier keys like Ctrl+S, Shift+A, Alt+N"), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("strong", null, "Multiple bindings:"), " Ctrl+Z (Windows/Linux) or Cmd+Z (Mac) for the same action"), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("strong", null, "Nested layers:"), " Press ", /*#__PURE__*/React.createElement("kbd", null, "o"), " to open modal - it has its own hotkey layer that overrides base layer hotkeys")))), isModalOpen && /*#__PURE__*/React.createElement(HotkeyLayer, {
configs: modalHotkeys,
enableHelpModal: true,
helpModalShortcut: "?"
}, /*#__PURE__*/React.createElement(Modal, {
isOpen: isModalOpen,
onRequestClose: () => setIsModalOpen(false),
title: "Modal Layer (Active)"
}, /*#__PURE__*/React.createElement(Text, null, "This modal has its own hotkey layer that overrides the base layer."), /*#__PURE__*/React.createElement(InlineNotice, {
title: "Try these in the modal:",
type: "warning"
}, /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", null, "Press ", /*#__PURE__*/React.createElement("kbd", null, "x"), " - triggers modal action (not base action)"), /*#__PURE__*/React.createElement("li", null, "Press ", /*#__PURE__*/React.createElement("kbd", null, "s"), " - saves from modal context"), /*#__PURE__*/React.createElement("li", null, "Press ", /*#__PURE__*/React.createElement("kbd", null, "esc"), " - closes modal"), /*#__PURE__*/React.createElement("li", null, "Press ", /*#__PURE__*/React.createElement("kbd", null, "?"), " - see only modal hotkeys in help")), /*#__PURE__*/React.createElement(Text, null, "Notice how base layer hotkeys (like ", /*#__PURE__*/React.createElement("kbd", null, "a"), ", ", /*#__PURE__*/React.createElement("kbd", null, "b"), ") don't work here - the modal layer blocks them!")), /*#__PURE__*/React.createElement(ModalActions, null, /*#__PURE__*/React.createElement(Button, {
onClick: () => setIsModalOpen(false)
}, "Close Modal")))));
};
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.'
}
};
//# sourceMappingURL=Hotkeys.stories.js.map