Skip to content

Commit

Permalink
fix: do not wrap global handler in a div
Browse files Browse the repository at this point in the history
document.body can be used as a target instead.
  • Loading branch information
targos committed May 6, 2021
1 parent 5cca3b7 commit b8afafc
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 30 deletions.
48 changes: 21 additions & 27 deletions src/component/KbsProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
useContext,
useReducer,
Dispatch,
KeyboardEvent,
useEffect,
} from 'react';

import { KbsDefinition } from './types';
Expand Down Expand Up @@ -76,40 +76,34 @@ function kbsReducer(state: KbsState, action: KbsAction): KbsState {
}
}

const divStyle = {
outline: 'none',
};

export function KbsProvider(props: KbsProviderProps) {
const [kbsState, kbsDispatch] = useReducer(kbsReducer, initialKbsState);

function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {
if (!(event.target as HTMLDivElement).hasAttribute('data-kbs-receiver')) {
return;
}
const key = eventToKey(event);
const shortcut = kbsState.combinedShortcuts[key];
if (shortcut) {
event.stopPropagation();
event.preventDefault();
shortcut.handler(event);
useEffect(() => {
if (kbsState.disableCount !== 0) return;
function handleKeyDown(event: KeyboardEvent) {
if (
event.target !== document.body &&
!(event.target as HTMLDivElement).hasAttribute('data-kbs-receiver')
) {
return;
}
const key = eventToKey(event);
const shortcut = kbsState.combinedShortcuts[key];
if (shortcut) {
event.stopPropagation();
event.preventDefault();
shortcut.handler(event);
}
}
}

const divProps =
kbsState.disableCount === 0
? {
tabIndex: 0,
style: divStyle,
onKeyDown: handleKeyDown,
'data-kbs-receiver': true,
}
: null;
document.body.addEventListener('keydown', handleKeyDown);
return () => document.body.removeEventListener('keydown', handleKeyDown);
}, [kbsState.disableCount, kbsState.combinedShortcuts]);

return (
<kbsContext.Provider value={kbsState}>
<kbsDispatchContext.Provider value={kbsDispatch}>
<div {...divProps}>{props.children}</div>
{props.children}
</kbsDispatchContext.Provider>
</kbsContext.Provider>
);
Expand Down
4 changes: 3 additions & 1 deletion src/component/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export interface KbsKeyDefinition {

export interface KbsDefinition {
shortcut: string | KbsKeyDefinition | Array<string | KbsKeyDefinition>;
handler: (event: KeyboardEvent<HTMLDivElement>) => void;
handler: (
event: KeyboardEvent<HTMLDivElement> | globalThis.KeyboardEvent,
) => void;
description?: string;
}
2 changes: 1 addition & 1 deletion src/component/utils/macInterop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const isMac =
typeof navigator !== 'undefined' && navigator.platform === 'MacIntel';

export function isMultiplatformCtrlKey(
event: MouseEvent | KeyboardEvent,
event: MouseEvent | KeyboardEvent | globalThis.KeyboardEvent,
): boolean {
return isMac ? event.metaKey : event.ctrlKey;
}
4 changes: 3 additions & 1 deletion src/component/utils/makeKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ export function shortcutElementToKey(shortcut: string, modifiers: Modifiers) {
}
}

export function eventToKey(event: KeyboardEvent<HTMLDivElement>): string {
export function eventToKey(
event: KeyboardEvent<HTMLDivElement> | globalThis.KeyboardEvent,
): string {
return `key[${event.key.toLowerCase()}]_ctrl[${boolToString(
isMultiplatformCtrlKey(event),
)}]_alt[${boolToString(event.altKey)}]_shift[${boolToString(
Expand Down

0 comments on commit b8afafc

Please sign in to comment.