Graduation
/
ui
/node_modules
/@xyflow
/svelte
/dist
/lib
/components
/KeyHandler
/KeyHandler.svelte
<script>import { shortcut } from '@svelte-put/shortcut'; | |
import { isInputDOMNode, isMacOs } from '@xyflow/system'; | |
import { useStore } from '../../store'; | |
export let selectionKey = 'Shift'; | |
export let multiSelectionKey = isMacOs() ? 'Meta' : 'Control'; | |
export let deleteKey = 'Backspace'; | |
export let panActivationKey = ' '; | |
export let zoomActivationKey = isMacOs() ? 'Meta' : 'Control'; | |
const { selectionKeyPressed, multiselectionKeyPressed, deleteKeyPressed, panActivationKeyPressed, zoomActivationKeyPressed, selectionRect } = useStore(); | |
function isKeyObject(key) { | |
return key !== null && typeof key === 'object'; | |
} | |
function getModifier(key) { | |
return isKeyObject(key) ? key.modifier || [] : []; | |
} | |
function getKeyString(key) { | |
if (key === null || key === undefined) { | |
// this is a workaround to check if a key is set | |
// if not we won't call the callback | |
return ''; | |
} | |
return isKeyObject(key) ? key.key : key; | |
} | |
function getShortcutTrigger(key, callback) { | |
const keys = Array.isArray(key) ? key : [key]; | |
return keys.map((_key) => { | |
const keyString = getKeyString(_key); | |
return { | |
key: keyString, | |
modifier: getModifier(_key), | |
enabled: keyString !== null, | |
callback | |
}; | |
}); | |
} | |
function resetKeysAndSelection() { | |
selectionRect.set(null); | |
selectionKeyPressed.set(false); | |
multiselectionKeyPressed.set(false); | |
deleteKeyPressed.set(false); | |
panActivationKeyPressed.set(false); | |
zoomActivationKeyPressed.set(false); | |
} | |
</script> | |
<svelte:window | |
on:blur={resetKeysAndSelection} | |
on:contextmenu={resetKeysAndSelection} | |
use:shortcut={{ | |
trigger: getShortcutTrigger(selectionKey, () => selectionKeyPressed.set(true)), | |
type: 'keydown' | |
}} | |
use:shortcut={{ | |
trigger: getShortcutTrigger(selectionKey, () => selectionKeyPressed.set(false)), | |
type: 'keyup' | |
}} | |
use:shortcut={{ | |
trigger: getShortcutTrigger(multiSelectionKey, () => multiselectionKeyPressed.set(true)), | |
type: 'keydown' | |
}} | |
use:shortcut={{ | |
trigger: getShortcutTrigger(multiSelectionKey, () => multiselectionKeyPressed.set(false)), | |
type: 'keyup' | |
}} | |
use:shortcut={{ | |
trigger: getShortcutTrigger(deleteKey, (detail) => { | |
const isModifierKey = | |
detail.originalEvent.ctrlKey || | |
detail.originalEvent.metaKey || | |
detail.originalEvent.shiftKey; | |
if (!isModifierKey && !isInputDOMNode(detail.originalEvent)) { | |
deleteKeyPressed.set(true); | |
} | |
}), | |
type: 'keydown' | |
}} | |
use:shortcut={{ | |
trigger: getShortcutTrigger(deleteKey, () => deleteKeyPressed.set(false)), | |
type: 'keyup' | |
}} | |
use:shortcut={{ | |
trigger: getShortcutTrigger(panActivationKey, () => panActivationKeyPressed.set(true)), | |
type: 'keydown' | |
}} | |
use:shortcut={{ | |
trigger: getShortcutTrigger(panActivationKey, () => panActivationKeyPressed.set(false)), | |
type: 'keyup' | |
}} | |
use:shortcut={{ | |
trigger: getShortcutTrigger(zoomActivationKey, () => zoomActivationKeyPressed.set(true)), | |
type: 'keydown' | |
}} | |
use:shortcut={{ | |
trigger: getShortcutTrigger(zoomActivationKey, () => zoomActivationKeyPressed.set(false)), | |
type: 'keyup' | |
}} | |
/> | |