Files
xyflow/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte
T

172 lines
4.3 KiB
Svelte

<script lang="ts">
import { shortcut, type ShortcutModifierDefinition } from '@svelte-put/shortcut';
import { isInputDOMNode, isMacOs } from '@xyflow/system';
import { useStore } from '$lib/store';
import type { KeyHandlerProps } from './types';
import type { KeyDefinition, KeyDefinitionObject } from '$lib/types';
type $$Props = KeyHandlerProps;
export let selectionKey: $$Props['selectionKey'] = 'Shift';
export let multiSelectionKey: $$Props['multiSelectionKey'] = isMacOs() ? 'Meta' : 'Control';
export let deleteKey: $$Props['deleteKey'] = 'Backspace';
export let panActivationKey: $$Props['panActivationKey'] = ' ';
export let zoomActivationKey: $$Props['zoomActivationKey'] = isMacOs() ? 'Meta' : 'Control';
const {
selectionKeyPressed,
multiselectionKeyPressed,
deleteKeyPressed,
panActivationKeyPressed,
zoomActivationKeyPressed
} = useStore();
function isKeyObject(key?: KeyDefinition | null): key is KeyDefinitionObject {
return key !== null && typeof key === 'object';
}
function getModifier(key?: KeyDefinition | null): ShortcutModifierDefinition {
return isKeyObject(key) ? key.modifier || [] : [];
}
function getKeyString(key?: KeyDefinition | null): string {
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;
}
$: selectionKeyDefinition = {
key: getKeyString(selectionKey),
modifier: getModifier(selectionKey)
};
$: multiSelectionKeyDefinition = {
key: getKeyString(multiSelectionKey),
modifier: getModifier(multiSelectionKey)
};
$: deleteKeyDefinition = {
key: getKeyString(deleteKey),
modifier: getModifier(deleteKey)
};
$: panActivationKeyDefinition = {
key: getKeyString(panActivationKey),
modifier: getModifier(panActivationKey)
};
$: zoomActivationKeyDefinition = {
key: getKeyString(zoomActivationKey),
modifier: getModifier(zoomActivationKey)
};
</script>
<svelte:window
use:shortcut={{
trigger: [
{
...selectionKeyDefinition,
enabled: selectionKeyDefinition.key !== null,
callback: () => selectionKeyPressed.set(true)
}
],
type: 'keydown'
}}
use:shortcut={{
trigger: [
{
...selectionKeyDefinition,
enabled: selectionKeyDefinition.key !== null,
callback: () => selectionKeyPressed.set(false)
}
],
type: 'keyup'
}}
use:shortcut={{
trigger: [
{
...multiSelectionKeyDefinition,
enabled: multiSelectionKeyDefinition.key !== null,
callback: () => multiselectionKeyPressed.set(true)
}
],
type: 'keydown'
}}
use:shortcut={{
trigger: [
{
...multiSelectionKeyDefinition,
enabled: multiSelectionKeyDefinition.key !== null,
callback: () => multiselectionKeyPressed.set(false)
}
],
type: 'keyup'
}}
use:shortcut={{
trigger: [
{
...deleteKeyDefinition,
enabled: deleteKeyDefinition.key !== null,
callback: (detail) => !isInputDOMNode(detail.originalEvent) && deleteKeyPressed.set(true)
}
],
type: 'keydown'
}}
use:shortcut={{
trigger: [
{
...deleteKeyDefinition,
enabled: deleteKeyDefinition.key !== null,
callback: () => deleteKeyPressed.set(false)
}
],
type: 'keyup'
}}
use:shortcut={{
trigger: [
{
...panActivationKeyDefinition,
enabled: panActivationKeyDefinition.key !== null,
callback: () => panActivationKeyPressed.set(true)
}
],
type: 'keydown'
}}
use:shortcut={{
trigger: [
{
...panActivationKeyDefinition,
enabled: panActivationKeyDefinition.key !== null,
callback: () => panActivationKeyPressed.set(false)
}
],
type: 'keyup'
}}
use:shortcut={{
trigger: [
{
...zoomActivationKeyDefinition,
enabled: zoomActivationKeyDefinition.key !== null,
callback: () => zoomActivationKeyPressed.set(true)
}
],
type: 'keydown'
}}
use:shortcut={{
trigger: [
{
...zoomActivationKeyDefinition,
enabled: zoomActivationKeyDefinition.key !== null,
callback: () => zoomActivationKeyPressed.set(false)
}
],
type: 'keyup'
}}
/>