diff --git a/examples/svelte/src/routes/examples/usenodesdata/ResultNode.svelte b/examples/svelte/src/routes/examples/usenodesdata/ResultNode.svelte
index c4150f42..2664e8ef 100644
--- a/examples/svelte/src/routes/examples/usenodesdata/ResultNode.svelte
+++ b/examples/svelte/src/routes/examples/usenodesdata/ResultNode.svelte
@@ -17,7 +17,7 @@
type: 'target'
});
- const nodeData = useNodesData($connections.map((connection) => connection.source));
+ $: nodeData = useNodesData($connections.map((connection) => connection.source));
diff --git a/packages/svelte/src/lib/actions/shortcut/index.ts b/packages/svelte/src/lib/actions/shortcut/index.ts
new file mode 100644
index 00000000..10c1e207
--- /dev/null
+++ b/packages/svelte/src/lib/actions/shortcut/index.ts
@@ -0,0 +1,89 @@
+// Shortcut action is copied and slightly adjusted from https://github.com/vnphanquang/svelte-put/tree/main/packages/actions/shortcut
+// If this discussion https://github.com/vnphanquang/svelte-put/discussions/256 gets resolved, we will use the original action again.
+
+export interface ShortcutEventDetail {
+ event: KeyboardEvent;
+ trigger: ShortcutTrigger;
+}
+
+export type ShortcutModifier = 'alt' | 'ctrl' | 'meta' | 'shift';
+
+export type ShortcutModifierDefinition =
+ | ShortcutModifier
+ | ShortcutModifier[]
+ | ShortcutModifier[][];
+
+export type ShortcutTrigger = {
+ enabled?: boolean;
+ modifier?: ShortcutModifierDefinition;
+ id?: string;
+ key: string;
+ callback?: (detail: ShortcutEventDetail) => void;
+ preventDefault?: boolean;
+};
+
+export type ShortcutParameter = {
+ enabled?: boolean;
+ trigger: Array | ShortcutTrigger;
+ type?: 'keydown' | 'keyup';
+};
+
+export function shortcut(node: Window, param: ShortcutParameter) {
+ let { enabled = true, trigger, type = 'keydown' } = param;
+
+ function handler(event: KeyboardEvent) {
+ const normalizedTriggers = Array.isArray(trigger) ? trigger : [trigger];
+ const modifiedMap = {
+ alt: event.altKey,
+ ctrl: event.ctrlKey,
+ shift: event.shiftKey,
+ meta: event.metaKey
+ };
+ for (const trigger of normalizedTriggers) {
+ const mergedTrigger = {
+ modifier: [],
+ preventDefault: false,
+ enabled: true,
+ ...trigger
+ };
+ const { modifier, key, callback, preventDefault, enabled: triggerEnabled } = mergedTrigger;
+ if (triggerEnabled) {
+ if (modifier.length) {
+ const modifierDefs = (Array.isArray(modifier) ? modifier : [modifier]).map((def) =>
+ typeof def === 'string' ? [def] : def
+ );
+ const modified = modifierDefs.some((def) =>
+ def.every((modifier) => modifiedMap[modifier])
+ );
+ if (!modified) continue;
+ }
+ if (event.key === key) {
+ if (preventDefault) event.preventDefault();
+ const detail = { event, trigger: mergedTrigger };
+ callback?.(detail);
+ }
+ }
+ }
+ }
+
+ if (enabled) node.addEventListener(type, handler);
+
+ return {
+ update: (update: ShortcutParameter) => {
+ const { enabled: newEnabled = true, type: newType = 'keydown' } = update;
+
+ if (enabled && (!newEnabled || type !== newType)) {
+ node.removeEventListener(type, handler);
+ } else if (!enabled && newEnabled) {
+ node.addEventListener(newType, handler);
+ }
+
+ enabled = newEnabled;
+ type = newType;
+ trigger = update.trigger;
+ },
+ destroy: () => {
+ node.removeEventListener(type, handler);
+ }
+ };
+}
diff --git a/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte b/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte
index f52d696a..54f3a9c1 100644
--- a/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte
+++ b/packages/svelte/src/lib/components/KeyHandler/KeyHandler.svelte
@@ -1,10 +1,10 @@