UNPKG

@primer/components

Version:
69 lines (59 loc) 2.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useOnEscapePress = void 0; var _react = require("react"); const handlers = []; /** * Calls all handlers in reverse order * @param event The KeyboardEvent generated by the Escape keydown. */ function handleEscape(event) { if (event.key === 'Escape' && !event.defaultPrevented) { for (let i = handlers.length - 1; i >= 0; --i) { handlers[i](event); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (event.defaultPrevented) { break; } } } } /** * Sets up a `keydown` listener on `window.document`. If * 1) The pressed key is "Escape", and * 2) The event has not had `.preventDefault()` called * The given callback will be executed. * * Note: If multiple `useOnEscapePress` hooks are active simultaneously, the * callbacks will occur in reverse order. In other words, if a parent component * and a child component both call `useOnEscapePress`, when the user presses * Escape, the child component's callback will execute, followed by the parent's * callback. Each callback has the chance to call `.preventDefault()` on the * event to prevent further callbacks. * * @param callback {(e: KeyboardEvent) => void} The callback that gets executed * when the Escape key is pressed. The KeyboardEvent generated by the Escape * keypress is passed as the only argument. * * @param callbackDependencies {React.DependencyList} The dependencies of the given * `onEscape` callback for memoization. Omit this param if the callback is already * memoized. See `React.useCallback` for more info on memoization. */ const useOnEscapePress = (onEscape, callbackDependencies = [onEscape]) => { // eslint-disable-next-line react-hooks/exhaustive-deps const escapeCallback = (0, _react.useCallback)(onEscape, callbackDependencies); (0, _react.useEffect)(() => { if (handlers.length === 0) { document.addEventListener('keydown', handleEscape); } handlers.push(escapeCallback); return () => { handlers.splice(handlers.findIndex(h => h === escapeCallback), 1); if (handlers.length === 0) { document.removeEventListener('keydown', handleEscape); } }; }, [escapeCallback]); }; exports.useOnEscapePress = useOnEscapePress;