From 35a4356d4ff20cefb79d03aa066c9065e011216a Mon Sep 17 00:00:00 2001 From: peterkogo Date: Mon, 18 Mar 2024 14:29:25 +0100 Subject: [PATCH 1/4] Svelte Flow: possible to add multiple keys --- .../components/KeyHandler/KeyHandler.svelte | 163 +++++++----------- .../src/lib/components/KeyHandler/types.ts | 10 +- .../src/lib/container/SvelteFlow/types.ts | 10 +- 3 files changed, 74 insertions(+), 109 deletions(-) diff --git a/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte b/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte index 4c4f138e..38a54158 100644 --- a/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte +++ b/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte @@ -1,5 +1,9 @@ selectionKeyPressed.set(true) - } - ], - + trigger: getShortcutTrigger(selectionKeyDefinition, () => selectionKeyPressed.set(true)), type: 'keydown' }} use:shortcut={{ - trigger: [ - { - ...selectionKeyDefinition, - enabled: selectionKeyDefinition.key !== null, - callback: () => selectionKeyPressed.set(false) - } - ], + trigger: getShortcutTrigger(selectionKeyDefinition, () => selectionKeyPressed.set(false)), type: 'keyup' }} use:shortcut={{ - trigger: [ - { - ...multiSelectionKeyDefinition, - enabled: multiSelectionKeyDefinition.key !== null, - callback: () => multiselectionKeyPressed.set(true) - } - ], + trigger: getShortcutTrigger(multiSelectionKeyDefinition, () => + multiselectionKeyPressed.set(true) + ), type: 'keydown' }} use:shortcut={{ - trigger: [ - { - ...multiSelectionKeyDefinition, - enabled: multiSelectionKeyDefinition.key !== null, - callback: () => multiselectionKeyPressed.set(false) - } - ], + trigger: getShortcutTrigger(multiSelectionKeyDefinition, () => + multiselectionKeyPressed.set(false) + ), type: 'keyup' }} use:shortcut={{ - trigger: [ - { - ...deleteKeyDefinition, - enabled: deleteKeyDefinition.key !== null, - callback: (detail) => { - const isModifierKey = - detail.originalEvent.ctrlKey || - detail.originalEvent.metaKey || - detail.originalEvent.shiftKey; - if (!isModifierKey && !isInputDOMNode(detail.originalEvent)) { - deleteKeyPressed.set(true); - } - } + trigger: getShortcutTrigger(deleteKeyDefinition, (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: [ - { - ...deleteKeyDefinition, - enabled: deleteKeyDefinition.key !== null, - callback: () => deleteKeyPressed.set(false) - } - ], + trigger: getShortcutTrigger(deleteKeyDefinition, () => deleteKeyPressed.set(false)), type: 'keyup' }} use:shortcut={{ - trigger: [ - { - ...panActivationKeyDefinition, - enabled: panActivationKeyDefinition.key !== null, - callback: () => panActivationKeyPressed.set(true) - } - ], + trigger: getShortcutTrigger(panActivationKeyDefinition, () => + panActivationKeyPressed.set(true) + ), type: 'keydown' }} use:shortcut={{ - trigger: [ - { - ...panActivationKeyDefinition, - enabled: panActivationKeyDefinition.key !== null, - callback: () => panActivationKeyPressed.set(false) - } - ], + trigger: getShortcutTrigger(panActivationKeyDefinition, () => + panActivationKeyPressed.set(false) + ), type: 'keyup' }} use:shortcut={{ - trigger: [ - { - ...zoomActivationKeyDefinition, - enabled: zoomActivationKeyDefinition.key !== null, - callback: () => zoomActivationKeyPressed.set(true) - } - ], + trigger: getShortcutTrigger(zoomActivationKeyDefinition, () => + zoomActivationKeyPressed.set(true) + ), type: 'keydown' }} use:shortcut={{ - trigger: [ - { - ...zoomActivationKeyDefinition, - enabled: zoomActivationKeyDefinition.key !== null, - callback: () => zoomActivationKeyPressed.set(false) - } - ], + trigger: getShortcutTrigger(zoomActivationKeyDefinition, () => + zoomActivationKeyPressed.set(false) + ), type: 'keyup' }} /> diff --git a/packages/svelte/src/lib/components/KeyHandler/types.ts b/packages/svelte/src/lib/components/KeyHandler/types.ts index 9a6ebe86..0df03d76 100644 --- a/packages/svelte/src/lib/components/KeyHandler/types.ts +++ b/packages/svelte/src/lib/components/KeyHandler/types.ts @@ -1,9 +1,9 @@ import type { KeyDefinition } from '$lib/types'; export type KeyHandlerProps = { - selectionKey?: KeyDefinition | null; - multiSelectionKey?: KeyDefinition | null; - deleteKey?: KeyDefinition | null; - panActivationKey?: KeyDefinition | null; - zoomActivationKey?: KeyDefinition | null; + selectionKey?: KeyDefinition | KeyDefinition[] | null; + multiSelectionKey?: KeyDefinition | KeyDefinition[] | null; + deleteKey?: KeyDefinition | KeyDefinition[] | null; + panActivationKey?: KeyDefinition | KeyDefinition[] | null; + zoomActivationKey?: KeyDefinition | KeyDefinition[] | null; }; diff --git a/packages/svelte/src/lib/container/SvelteFlow/types.ts b/packages/svelte/src/lib/container/SvelteFlow/types.ts index ecda2319..8295b27c 100644 --- a/packages/svelte/src/lib/container/SvelteFlow/types.ts +++ b/packages/svelte/src/lib/container/SvelteFlow/types.ts @@ -86,27 +86,27 @@ export type SvelteFlowProps = DOMAttributes & { /** Pressing down this key you can select multiple elements with a selection box. * @default 'Shift' */ - selectionKey?: KeyDefinition | null; + selectionKey?: KeyDefinition | KeyDefinition[] | null; /** If a key is set, you can pan the viewport while that key is held down even if panOnScroll is set to false. * * By setting this prop to null you can disable this functionality. * @default 'Space' */ - panActivationKey?: KeyDefinition | null; + panActivationKey?: KeyDefinition | KeyDefinition[] | null; /** Pressing down this key deletes all selected nodes & edges. * @default 'Backspace' */ - deleteKey?: KeyDefinition | null; + deleteKey?: KeyDefinition | KeyDefinition[] | null; /** Pressing down this key you can select multiple elements by clicking. * @default 'Meta' for macOS, "Ctrl" for other systems */ - multiSelectionKey?: KeyDefinition | null; + multiSelectionKey?: KeyDefinition | KeyDefinition[] | null; /** If a key is set, you can zoom the viewport while that key is held down even if panOnScroll is set to false. * * By setting this prop to null you can disable this functionality. * @default 'Meta' for macOS, "Ctrl" for other systems * */ - zoomActivationKey?: KeyDefinition | null; + zoomActivationKey?: KeyDefinition | KeyDefinition[] | null; /** If set, initial viewport will show all nodes & edges */ fitView?: boolean; /** Options to be used in combination with fitView From fe77b630e8a4efd0f2babf9b0febd2d11685da2e Mon Sep 17 00:00:00 2001 From: peterkogo Date: Tue, 19 Mar 2024 11:09:05 +0100 Subject: [PATCH 2/4] simplified KeyHandler --- .../components/KeyHandler/KeyHandler.svelte | 73 ++++++------------- 1 file changed, 21 insertions(+), 52 deletions(-) diff --git a/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte b/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte index 38a54158..8f474b85 100644 --- a/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte +++ b/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte @@ -44,65 +44,42 @@ return isKeyObject(key) ? key.key : key; } - function getShortcutDefinition(keyString: KeyDefinition | KeyDefinition[] | null | undefined) { - return Array.isArray(keyString) - ? keyString.map((key) => ({ - key: getKeyString(key), - modifier: getModifier(key) - })) - : [ - { - key: getKeyString(keyString), - modifier: getModifier(keyString) - } - ]; - } - function getShortcutTrigger( - keyDefinition: KeyDefinitionObject[], + key: KeyDefinition | KeyDefinition[] | null | undefined, callback: (detail: ShortcutEventDetail) => void ) { - return keyDefinition.map((definition) => ({ - ...definition, - enabled: definition.key !== null, - 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 + }; + }); } - - $: selectionKeyDefinition = getShortcutDefinition(selectionKey); - - $: multiSelectionKeyDefinition = getShortcutDefinition(multiSelectionKey); - - $: deleteKeyDefinition = getShortcutDefinition(deleteKey); - - $: panActivationKeyDefinition = getShortcutDefinition(panActivationKey); - - $: zoomActivationKeyDefinition = getShortcutDefinition(zoomActivationKey); selectionKeyPressed.set(true)), + trigger: getShortcutTrigger(selectionKey, () => selectionKeyPressed.set(true)), type: 'keydown' }} use:shortcut={{ - trigger: getShortcutTrigger(selectionKeyDefinition, () => selectionKeyPressed.set(false)), + trigger: getShortcutTrigger(selectionKey, () => selectionKeyPressed.set(false)), type: 'keyup' }} use:shortcut={{ - trigger: getShortcutTrigger(multiSelectionKeyDefinition, () => - multiselectionKeyPressed.set(true) - ), + trigger: getShortcutTrigger(multiSelectionKey, () => multiselectionKeyPressed.set(true)), type: 'keydown' }} use:shortcut={{ - trigger: getShortcutTrigger(multiSelectionKeyDefinition, () => - multiselectionKeyPressed.set(false) - ), + trigger: getShortcutTrigger(multiSelectionKey, () => multiselectionKeyPressed.set(false)), type: 'keyup' }} use:shortcut={{ - trigger: getShortcutTrigger(deleteKeyDefinition, (detail) => { + trigger: getShortcutTrigger(deleteKey, (detail) => { const isModifierKey = detail.originalEvent.ctrlKey || detail.originalEvent.metaKey || @@ -114,31 +91,23 @@ type: 'keydown' }} use:shortcut={{ - trigger: getShortcutTrigger(deleteKeyDefinition, () => deleteKeyPressed.set(false)), + trigger: getShortcutTrigger(deleteKey, () => deleteKeyPressed.set(false)), type: 'keyup' }} use:shortcut={{ - trigger: getShortcutTrigger(panActivationKeyDefinition, () => - panActivationKeyPressed.set(true) - ), + trigger: getShortcutTrigger(panActivationKey, () => panActivationKeyPressed.set(true)), type: 'keydown' }} use:shortcut={{ - trigger: getShortcutTrigger(panActivationKeyDefinition, () => - panActivationKeyPressed.set(false) - ), + trigger: getShortcutTrigger(panActivationKey, () => panActivationKeyPressed.set(false)), type: 'keyup' }} use:shortcut={{ - trigger: getShortcutTrigger(zoomActivationKeyDefinition, () => - zoomActivationKeyPressed.set(true) - ), + trigger: getShortcutTrigger(zoomActivationKey, () => zoomActivationKeyPressed.set(true)), type: 'keydown' }} use:shortcut={{ - trigger: getShortcutTrigger(zoomActivationKeyDefinition, () => - zoomActivationKeyPressed.set(false) - ), + trigger: getShortcutTrigger(zoomActivationKey, () => zoomActivationKeyPressed.set(false)), type: 'keyup' }} /> From ffb5c856d9db3f5e7d5ded331074f52bae3cfc6d Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 3 Apr 2024 16:44:05 +0200 Subject: [PATCH 3/4] chore(svelte-example): add multi key --- examples/svelte/src/routes/examples/overview/+page.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/svelte/src/routes/examples/overview/+page.svelte b/examples/svelte/src/routes/examples/overview/+page.svelte index 2f21107d..ef8f9a02 100644 --- a/examples/svelte/src/routes/examples/overview/+page.svelte +++ b/examples/svelte/src/routes/examples/overview/+page.svelte @@ -189,6 +189,7 @@ autoPanOnNodeDrag connectionMode={ConnectionMode.Strict} attributionPosition={'top-center'} + deleteKey={['Backspace', 'd']} > xy From ec78869b702f2bb9450f39f4e6528ace9cbffde2 Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 3 Apr 2024 16:54:09 +0200 Subject: [PATCH 4/4] refactor(svelte): reset selection on context menu --- .../src/lib/components/KeyHandler/KeyHandler.svelte | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte b/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte index 608fd9b3..65661fd2 100644 --- a/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte +++ b/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte @@ -23,7 +23,8 @@ multiselectionKeyPressed, deleteKeyPressed, panActivationKeyPressed, - zoomActivationKeyPressed + zoomActivationKeyPressed, + selectionRect } = useStore(); function isKeyObject(key?: KeyDefinition | null): key is KeyDefinitionObject { @@ -60,7 +61,8 @@ }); } - function resetAll() { + function resetKeysAndSelection() { + selectionRect.set(null); selectionKeyPressed.set(false); multiselectionKeyPressed.set(false); deleteKeyPressed.set(false); @@ -70,8 +72,8 @@ selectionKeyPressed.set(true)), type: 'keydown'