Files
nodarium/app/src/lib/helpers/createKeyMap.ts
2026-02-02 16:22:14 +01:00

58 lines
1.9 KiB
TypeScript

import { derived, get, writable } from 'svelte/store';
export type ShortCut = {
key: string | string[];
shift?: boolean;
ctrl?: boolean;
alt?: boolean;
preventDefault?: boolean;
description?: string;
callback: (event: KeyboardEvent) => void;
};
function getShortcutId(shortcut: ShortCut) {
return `${shortcut.key}${shortcut.shift ? '+shift' : ''}${shortcut.ctrl ? '+ctrl' : ''}${
shortcut.alt ? '+alt' : ''
}`;
}
export function createKeyMap(keys: ShortCut[]) {
const store = writable(new Map(keys.map(k => [getShortcutId(k), k])));
return {
handleKeyboardEvent: (event: KeyboardEvent) => {
const activeElement = document.activeElement as HTMLElement;
if (activeElement?.tagName === 'INPUT' || activeElement?.tagName === 'TEXTAREA') return;
const key = [...get(store).values()].find(k => {
if (Array.isArray(k.key) ? !k.key.includes(event.key) : k.key !== event.key) return false;
if ('shift' in k && k.shift !== event.shiftKey) return false;
if ('ctrl' in k && k.ctrl !== event.ctrlKey) return false;
if ('alt' in k && k.alt !== event.altKey) return false;
return true;
});
if (key && key.preventDefault) event.preventDefault();
key?.callback(event);
},
addShortcut: (shortcut: ShortCut) => {
if (Array.isArray(shortcut.key)) {
for (const k of shortcut.key) {
store.update(shortcuts => {
const id = getShortcutId({ ...shortcut, key: k });
shortcuts.delete(id);
shortcuts.set(id, { ...shortcut, key: k });
return shortcuts;
});
}
} else {
store.update(shortcuts => {
const id = getShortcutId(shortcut);
shortcuts.delete(id);
shortcuts.set(id, shortcut);
return shortcuts;
});
}
},
keys: derived(store, $store => Array.from($store.values()))
};
}