UNPKG

@bonsai-components/react-global-keys

Version:

A simple way to add global keys

138 lines 5.85 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GlobalKeysProvider = exports.GlobalKeysContext = void 0; const react_1 = __importStar(require("react")); const error_helpers_1 = require("../helpers/error.helpers"); const DELIMITER = '#!'; const hasCode = (descriptor) => { return Boolean(descriptor.code); }; const initialState = { addKeyBinding: (_keyBinding) => '', getKeyBindingDescriptors: () => [], keyBindings: new Map(), }; exports.GlobalKeysContext = react_1.default.createContext(initialState); class GlobalKeysProvider extends react_1.Component { constructor() { super(...arguments); this.state = Object.assign(Object.assign({}, initialState), { addKeyBinding: (keyBinding) => { const id = this.encodeKeyBinding(keyBinding); this.setState((prevState) => { const existingKeyBindingAction = prevState.keyBindings.has(id); if (existingKeyBindingAction) { if (this.props.debug) { (0, error_helpers_1.reportKeyBindingConflict)(keyBinding); } return { keyBindings: prevState.keyBindings }; } const newKeyBindingsMap = new Map(prevState.keyBindings); newKeyBindingsMap.set(id, keyBinding); return { keyBindings: newKeyBindingsMap }; }); return id; }, getKeyBindingDescriptors: () => { return Array.from(this.state.keyBindings.values()).map((e) => { if (hasCode(e)) { return { code: e.code, modifier: e.modifier, description: e.description || '', }; } else { return { key: e.key, modifier: e.modifier, description: e.description || '', }; } }); } }); this.handleKeyDown = (e) => { const [keyId, codeId] = this.encodeKeyEvent(e); if (this.props.debug) { console.log(JSON.stringify({ keyId, codeId }, null, 2)); } // for now only one binding will win if (this.state.keyBindings.has(codeId)) { return this.state.keyBindings.get(codeId).action(e); } if (this.state.keyBindings.has(keyId)) { return this.state.keyBindings.get(keyId).action(e); } }; this.encodeKeyEvent = (e) => { const { key, code, metaKey, ctrlKey, altKey, shiftKey } = e; return [ `${key}${this.encodeModifierStates(metaKey, ctrlKey, altKey, shiftKey)}`, `${code}${this.encodeModifierStates(metaKey, ctrlKey, altKey, shiftKey)}`, ]; }; this.encodeKeyBinding = (keyBinding) => { const modifier = keyBinding.modifier ? keyBinding.modifier : null; let identifier; if (hasCode(keyBinding)) { identifier = keyBinding.code; } else { identifier = keyBinding.key; } if (!modifier) { return `${identifier}${DELIMITER}`; } return `${identifier}${this.encodeModifierStates(modifier.meta, modifier.ctrl, modifier.alt, modifier.shift)}`; }; this.encodeModifierStates = (meta, ctrl, alt, shift) => { if (this.props.useCtrlAsMetaAlternative) { return `${DELIMITER}${ctrl || meta ? 'c' : ''}${alt ? 'a' : ''}${shift ? 's' : ''}`; } return `${DELIMITER}${meta ? 'm' : ''}${ctrl ? 'c' : ''}${alt ? 'a' : ''}${shift ? 's' : ''}`; }; this.addListener = () => { document.addEventListener('keydown', this.handleKeyDown); }; this.removeListener = () => { document.removeEventListener('keydown', this.handleKeyDown); }; } componentDidMount() { this.addListener(); } componentWillUnmount() { this.removeListener(); } render() { if (this.props.disableKeybindings) { return react_1.default.createElement(react_1.default.Fragment, null, this.props.children); } return (react_1.default.createElement(exports.GlobalKeysContext.Provider, { value: this.state }, this.props.children)); } } exports.GlobalKeysProvider = GlobalKeysProvider; //# sourceMappingURL=global-keys.context.js.map