feat(frontend): add hotkey registration function and hotkey helper modal (#12128)

* add new hotkey registration interface and hotkey modal

* fix import

* add printing hotkey

* add todo

* add hotkey for barcode scanning

* register spotlight shortcut key

* sort keys

* render nicer overview

* fix props

* expose for plugins

---------

Co-authored-by: Oliver <oliver.henry.walters@gmail.com>
This commit is contained in:
Matthias Mair
2026-06-09 13:05:52 +10:00
committed by GitHub
co-authored by Oliver
parent 4fb4ba7b2e
commit 3d527eb392
15 changed files with 220 additions and 20 deletions
+31
View File
@@ -1,6 +1,37 @@
import { useHotkeys } from '@mantine/hooks';
import type { HotkeyItemOptions } from '@mantine/hooks';
import { useEffect } from 'react';
import { useLocalLibState } from '..';
// Helper function to cancel event propagation
export function cancelEvent(event: any) {
event?.preventDefault();
event?.stopPropagation();
event?.nativeEvent?.stopImmediatePropagation();
}
export type InvenTreeHotkeyItem = [
string,
string,
(event: KeyboardEvent) => void,
HotkeyItemOptions?
];
export function useInvenTreeHotkeys(hotkeys: InvenTreeHotkeyItem[]) {
// Register the hotkeys using the Mantine hook
useHotkeys(
hotkeys.map(([key, _, handler, options]) => [key, handler, options])
);
// register to helper state to store hotkeys
// This allows us to display the hotkeys in the UI
const keyelems: [string, string][] = hotkeys.map(([key, description]) => [
key,
description
]);
useEffect(() => {
useLocalLibState.getState().addHotkeys(keyelems);
return () =>
useLocalLibState.getState().removeHotkeys(keyelems.map(([key]) => key));
}, []);
}
+2
View File
@@ -139,6 +139,8 @@ export {
type TableStateExtraProps
} from './hooks/UseTable';
export { useInvenTreeHotkeys } from './functions/Events';
export {
type DrawerProps,
DetailDrawer,
+19
View File
@@ -10,8 +10,24 @@ export const useLocalLibState = create<LocalLibStateProps>()(
detailDrawerStack:
value === false ? 0 : get().detailDrawerStack + value
});
},
hotkeys: {},
addHotkeys: (hotkeys) => {
const newHotkeys = { ...get().hotkeys };
for (const [ref, details] of hotkeys) {
newHotkeys[ref] = details;
}
set({ hotkeys: newHotkeys });
},
removeHotkeys: (hotkeys) => {
const newHotkeys = { ...get().hotkeys };
for (const ref of hotkeys) {
delete newHotkeys[ref];
}
set({ hotkeys: newHotkeys });
}
}),
{
name: 'session-settings-inventreedb_lib'
}
@@ -20,4 +36,7 @@ export const useLocalLibState = create<LocalLibStateProps>()(
export interface LocalLibStateProps {
detailDrawerStack: number;
addDetailDrawer: (value: number | false) => void;
hotkeys: Record<string, string>;
addHotkeys: (hotkeys: [string, string][]) => void;
removeHotkeys: (hotkeys: string[]) => void;
}