Skip to content

Commit

Permalink
Move shortcut helpers to its own separate module
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianUribe6 committed Feb 7, 2024
1 parent 2aeb7a1 commit 5110ec8
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 66 deletions.
2 changes: 1 addition & 1 deletion apps/front-end/src/components/Sidebar/Category.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { MenuAction } from "./MenuAction";
import { EventHandlersContext } from "./Sidebar";
import { removeItem } from "./state";
import { withDeleteItemShortcut, withRenameItemShortcut } from "./shorcuts";
import { registerShortcuts as registerShortcuts } from "@/utils";
import { registerShortcuts } from "@/lib/hotkeys";

export type CategoryProps = {
category: CategoryItem;
Expand Down
2 changes: 1 addition & 1 deletion apps/front-end/src/components/Sidebar/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { MenuAction } from "./MenuAction";
import { EventHandlersContext } from "./Sidebar";
import { removeItem } from "./state";
import DeleteConfirmationDialog from "./DeleteConfirmationDialog";
import { registerShortcuts } from "@/utils";
import { registerShortcuts } from "@/lib/hotkeys";
import { withDeleteItemShortcut, withRenameItemShortcut } from "./shorcuts";

export type LinkProps = {
Expand Down
2 changes: 1 addition & 1 deletion apps/front-end/src/components/Sidebar/shorcuts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createShortcutHandler } from "@/utils";
import { createShortcutHandler } from "@/lib/hotkeys";

export const withDeleteItemShortcut = createShortcutHandler({
key: "Delete",
Expand Down
63 changes: 63 additions & 0 deletions apps/front-end/src/lib/hotkeys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { KeyboardEventHandler } from "react";

type ShorcutConfiguration = {
modifiers?: Partial<
Pick<KeyboardEvent, "altKey" | "metaKey" | "ctrlKey" | "shiftKey">
>;
key: string;
};

export function createShortcutHandler(options: ShorcutConfiguration) {
return function handler(
callback: KeyboardEventHandler,
): KeyboardEventHandler {
return (e) => {
if (e.repeat || isEditableElement(e.target)) {
// Either This event was already handled (user is holding the keys)
// Or the user is editing some text, so we do nothing.
return;
}
if (!options.modifiers && options.key === e.code) {
callback(e);
return;
}

if (!options.modifiers) {
return;
}

const modifierKeys = Object.keys(options.modifiers) as Array<
keyof typeof options.modifiers
>;
for (const key of modifierKeys) {
if (e[key] !== options.modifiers[key]) {
return;
}
}
if (options.key === e.code) {
callback(e);
}
};
};
}

function isEditableElement(target: EventTarget): boolean {
if (!(target instanceof HTMLElement)) {
return false;
}
return (
target.isContentEditable ||
target.tagName === "INPUT" ||
target.tagName === "TEXTAREA"
);
}

export function registerShortcuts(
...handlers: KeyboardEventHandler[]
): KeyboardEventHandler {
return (e) => {
for (const handler of handlers) {
handler(e);
}
};
}
64 changes: 1 addition & 63 deletions apps/front-end/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { KeyboardEventHandler, MutableRefObject, RefCallback } from "react";
import { MutableRefObject, RefCallback } from "react";

type Ref<T> = RefCallback<T> | MutableRefObject<T> | null;

Expand All @@ -20,65 +20,3 @@ export function mergeRefs<T = any>(...refs: Ref<T>[]) {
});
};
}

type ShorcutConfiguration = {
modifiers?: Partial<
Pick<KeyboardEvent, "altKey" | "metaKey" | "ctrlKey" | "shiftKey">
>;
key: string;
};

export function createShortcutHandler(options: ShorcutConfiguration) {
return function handler(
callback: KeyboardEventHandler,
): KeyboardEventHandler {
return (e) => {
if (e.repeat || isEditableElement(e.target)) {
// Either This event was already handled (user is holding the keys)
// Or the user is editing some text, so we do nothing.
return;
}
if (!options.modifiers && options.key === e.code) {
callback(e);
return;
}

if (!options.modifiers) {
return;
}

const modifierKeys = Object.keys(options.modifiers) as Array<
keyof typeof options.modifiers
>;
for (const key of modifierKeys) {
if (e[key] !== options.modifiers[key]) {
return;
}
}
if (options.key === e.code) {
callback(e);
}
};
};
}

function isEditableElement(target: EventTarget): boolean {
if (!(target instanceof HTMLElement)) {
return false;
}
return (
target.isContentEditable ||
target.tagName === "INPUT" ||
target.tagName === "TEXTAREA"
);
}

export function registerShortcuts(
...handlers: KeyboardEventHandler[]
): KeyboardEventHandler {
return (e) => {
for (const handler of handlers) {
handler(e);
}
};
}

0 comments on commit 5110ec8

Please sign in to comment.