Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
Original file line number Diff line number Diff line change
@@ -1,41 +1,50 @@
/** @jsx jsx */
import { jsx } from '@emotion/core';
import { FC, useRef } from 'react';

import { FC } from 'react';
import { mapShortcutToKeyboardCommand } from '../../constants/KeyboardCommandTypes';

interface NodeProps {
const KeyNameByModifierAttr = {
ctrlKey: 'Control',
metaKey: 'Meta',
altKey: 'Alt',
shiftKey: 'Shift',
};

const overriddenKeyCodes = ['Tab', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];

interface KeyboardZoneProps {
when: string;
onCommand: (action) => object | void;
onCommand: (action, e: KeyboardEvent) => object | void;
}

const isMac = () => {
return /macintosh|mac os x/i.test(navigator.userAgent);
};
export const KeyboardZone: FC<NodeProps> = ({ when, onCommand, children }): JSX.Element => {
const keyPressed = useRef({});

const buildModifierKeyPrefix = (e: KeyboardEvent): string => {
let prefix = isMac() ? 'Mac.' : 'Windows.';
['ctrlKey', 'metaKey', 'altKey', 'shiftKey'].forEach(modifierAttr => {
if (e[modifierAttr]) {
prefix += `${KeyNameByModifierAttr[modifierAttr]}.`;
}
});
return prefix;
};

export const KeyboardZone: FC<KeyboardZoneProps> = ({ when, onCommand, children }): JSX.Element => {
const handleKeyDown = e => {
if (e.key === 'Tab') {
if (overriddenKeyCodes.includes(e.key)) {
e.preventDefault();
e.stopPropagation();
}
keyPressed.current[e.key] = true;
};

const handleKeyUp = e => {
if (when !== 'normal') {
let keyCode = isMac() ? 'Mac' : 'Windows';
for (const key in keyPressed.current) {
if (keyPressed.current[key]) {
keyCode += `.${key}`;
}
}
onCommand(mapShortcutToKeyboardCommand(keyCode));
}
delete keyPressed.current[e.key];
const modifierPrefix = buildModifierKeyPrefix(e);
const shortcut = modifierPrefix + e.key;
onCommand(mapShortcutToKeyboardCommand(shortcut), e);
};

return (
<div onKeyDown={handleKeyDown} onKeyUp={handleKeyUp} tabIndex={0} data-test-id="keyboard-zone">
<div onKeyDown={handleKeyDown} tabIndex={0} data-test-id="keyboard-zone">
{children}
</div>
);
Expand Down