UNPKG

apphouse

Version:

Component library for React that uses observable state management and theme-able components.

114 lines (104 loc) 2.8 kB
import { makeAutoObservable } from 'mobx'; import View from '../app/View'; import hotkeys from 'hotkeys-js'; export interface Shortcut { /** * The shortcut combo to trigger the action. * @example * 'ctrl+s' * 'command+s' * ['ctrl+s', 'command+s'] * 'ctrl+shift+s' */ combo: string | string[]; /** * The action to be called when the shortcut is triggered. * @returns */ action: () => void; /** * The description of the shortcut. Added for convenience. * @optional * @example * 'Save the file to disk' * 'Open the preview' */ description?: string; /** * The view where the shortcut should be active. It should match with your view id. * The shortcut will be active in all views if not specified. * @optional */ view?: string; } /** * The Shortcuts class handles all the keyboard shortcuts in the app. * It uses the hotkeys library to handle the shortcuts. */ export class Shortcuts { currentView: View; shiftPress: boolean; /** * The scope where the shortcut should be active. * It should match with your scope id. */ scoped: { [key: string]: { [id: string]: () => void } }; constructor(view: View) { this.currentView = view; this.shiftPress = false; this.scoped = {}; hotkeys('shift', () => { this.setShiftPress(true); }); makeAutoObservable(this); } /** * Register a new shortcut * @param shortcut the shortcut combo to trigger the action. * @param callback the action to be called when the shortcut is triggered. */ register = (shortcut: string | string[], callback: () => void) => { if (typeof shortcut === 'string') { hotkeys(shortcut, callback); } else { shortcut.forEach((combo) => { hotkeys(combo, callback); }); } }; /** * Unregister a current shortcut * @param shortcut the shortcut combo to be unregistered. */ unregister = (shortcut: string | string[]) => { if (typeof shortcut === 'string') { hotkeys.unbind(shortcut); } else { shortcut.forEach((combo) => { hotkeys.unbind(combo); }); } }; /** * Register a list of shortcuts to be used in the app. * @param shortcuts the shortcuts to be registered. */ registerAppShortcuts = (shortcuts: Shortcut[]) => { const applyShortcut = (shortcut: Shortcut) => { this.register(shortcut.combo, () => { if (shortcut.view && shortcut.view !== this.currentView.path) { return; } shortcut.action(); }); }; shortcuts.forEach(applyShortcut); }; /** * Set the shift key press state. * @param value boolean if true, the shift key is pressed */ private setShiftPress = (value: boolean) => { this.shiftPress = value; }; }