Skip to content

Instantly share code, notes, and snippets.

@metruzanca
Created November 3, 2024 09:00
Show Gist options
  • Save metruzanca/6c0e9f3c269d93887a5860c16d173bc9 to your computer and use it in GitHub Desktop.
Save metruzanca/6c0e9f3c269d93887a5860c16d173bc9 to your computer and use it in GitHub Desktop.
type Modifiers = {
ctrl?: boolean;
shift?: boolean;
};
type HotkeyDetails = { key: string } & Modifiers;
const hotkeyName = ({ key, ctrl, shift }: HotkeyDetails) =>
`hotkey:${ctrl || ""}+${shift || ""}+${key}`;
function hotkeyPressed(detail: HotkeyDetails) {
const hotkeyEvent = new CustomEvent(hotkeyName(detail), { detail });
document.dispatchEvent(hotkeyEvent);
}
export type HotkeyEvent = CustomEvent<{ key: string; mod: Modifiers }>;
/** Dispatches hotkey events */
export function registerHotkeys(supportedHotkeys: HotkeyDetails[]) {
const handler = (event: KeyboardEvent) => {
if (
supportedHotkeys.some((options) => {
return (
options.key === event.key &&
(!!options.ctrl === event.ctrlKey || event.metaKey) &&
!!options.shift === event.shiftKey
);
})
) {
event.preventDefault();
hotkeyPressed({
key: event.key,
ctrl: event.ctrlKey || event.metaKey,
shift: event.shiftKey,
});
}
};
document.addEventListener("keydown", handler);
return () => document.removeEventListener("keydown", handler);
}
/**
* @returns unsubscribe callback
*/
export function onHotkey(
options: { key: string; ctrl?: boolean; shift?: boolean },
callback: (event: HotkeyEvent) => void
) {
//@ts-ignore no clue how to register the hotkey name
document.addEventListener(hotkeyName(options), callback);
return () =>
//@ts-ignore
document.removeEventListener(hotkeyName(options), callback);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment