UNPKG

@wordpress/compose

Version:
100 lines (83 loc) 3.25 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _mousetrap = _interopRequireDefault(require("mousetrap")); require("mousetrap/plugins/global-bind/mousetrap-global-bind"); var _lodash = require("lodash"); var _element = require("@wordpress/element"); /** * External dependencies */ /** * WordPress dependencies */ /** * A block selection object. * * @typedef {Object} WPKeyboardShortcutConfig * * @property {boolean} [bindGlobal] Handle keyboard events anywhere including inside textarea/input fields. * @property {string} [eventName] Event name used to trigger the handler, defaults to keydown. * @property {boolean} [isDisabled] Disables the keyboard handler if the value is true. * @property {Object} [target] React reference to the DOM element used to catch the keyboard event. */ /** * Return true if platform is MacOS. * * @param {Object} _window window object by default; used for DI testing. * * @return {boolean} True if MacOS; false otherwise. */ function isAppleOS(_window = window) { const { platform } = _window.navigator; return platform.indexOf('Mac') !== -1 || (0, _lodash.includes)(['iPad', 'iPhone'], platform); } /** * Attach a keyboard shortcut handler. * * @param {string[]|string} shortcuts Keyboard Shortcuts. * @param {Function} callback Shortcut callback. * @param {WPKeyboardShortcutConfig} options Shortcut options. */ function useKeyboardShortcut(shortcuts, callback, { bindGlobal = false, eventName = 'keydown', isDisabled = false, // This is important for performance considerations. target } = {}) { const currentCallback = (0, _element.useRef)(callback); (0, _element.useEffect)(() => { currentCallback.current = callback; }, [callback]); (0, _element.useEffect)(() => { if (isDisabled) { return; } const mousetrap = new _mousetrap.default(target ? target.current : document); (0, _lodash.castArray)(shortcuts).forEach(shortcut => { const keys = shortcut.split('+'); // Determines whether a key is a modifier by the length of the string. // E.g. if I add a pass a shortcut Shift+Cmd+M, it'll determine that // the modifiers are Shift and Cmd because they're not a single character. const modifiers = new Set(keys.filter(value => value.length > 1)); const hasAlt = modifiers.has('alt'); const hasShift = modifiers.has('shift'); // This should be better moved to the shortcut registration instead. if (isAppleOS() && (modifiers.size === 1 && hasAlt || modifiers.size === 2 && hasAlt && hasShift)) { throw new Error(`Cannot bind ${shortcut}. Alt and Shift+Alt modifiers are reserved for character input.`); } const bindFn = bindGlobal ? 'bindGlobal' : 'bind'; mousetrap[bindFn](shortcut, (...args) => currentCallback.current(...args), eventName); }); return () => { mousetrap.reset(); }; }, [shortcuts, bindGlobal, eventName, target, isDisabled]); } var _default = useKeyboardShortcut; exports.default = _default; //# sourceMappingURL=index.js.map