@bonsai-components/react-global-keys
Version:
A simple way to add global keys
138 lines • 5.85 kB
JavaScript
;
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