fix(svelte): shortcut delete/input issue #3712
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
type: 'target'
|
type: 'target'
|
||||||
});
|
});
|
||||||
|
|
||||||
const nodeData = useNodesData($connections.map((connection) => connection.source));
|
$: nodeData = useNodesData($connections.map((connection) => connection.source));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="custom">
|
<div class="custom">
|
||||||
|
|||||||
@@ -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> | 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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { shortcut, type ShortcutModifierDefinition } from '@svelte-put/shortcut';
|
import { isInputDOMNode, isMacOs } from '@xyflow/system';
|
||||||
|
|
||||||
import { useStore } from '$lib/store';
|
import { useStore } from '$lib/store';
|
||||||
import type { KeyHandlerProps } from './types';
|
import type { KeyHandlerProps } from './types';
|
||||||
import type { KeyDefinition, KeyDefinitionObject } from '$lib/types';
|
import type { KeyDefinition, KeyDefinitionObject } from '$lib/types';
|
||||||
import { isMacOs } from '@xyflow/system';
|
import { shortcut, type ShortcutModifierDefinition } from '../../actions/shortcut';
|
||||||
|
|
||||||
type $$Props = KeyHandlerProps;
|
type $$Props = KeyHandlerProps;
|
||||||
|
|
||||||
@@ -71,16 +71,19 @@
|
|||||||
trigger: [
|
trigger: [
|
||||||
{
|
{
|
||||||
...selectionKeyDefinition,
|
...selectionKeyDefinition,
|
||||||
callback: () => selectionKeyDefinition.key && selectionKeyPressed.set(true)
|
enabled: selectionKeyDefinition.key !== null,
|
||||||
|
callback: () => selectionKeyPressed.set(true)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
type: 'keydown'
|
type: 'keydown'
|
||||||
}}
|
}}
|
||||||
use:shortcut={{
|
use:shortcut={{
|
||||||
trigger: [
|
trigger: [
|
||||||
{
|
{
|
||||||
...selectionKeyDefinition,
|
...selectionKeyDefinition,
|
||||||
callback: () => selectionKeyDefinition.key && selectionKeyPressed.set(false)
|
enabled: selectionKeyDefinition.key !== null,
|
||||||
|
callback: () => selectionKeyPressed.set(false)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
type: 'keyup'
|
type: 'keyup'
|
||||||
@@ -89,7 +92,8 @@
|
|||||||
trigger: [
|
trigger: [
|
||||||
{
|
{
|
||||||
...multiSelectionKeyDefinition,
|
...multiSelectionKeyDefinition,
|
||||||
callback: () => multiSelectionKeyDefinition.key && multiselectionKeyPressed.set(true)
|
enabled: multiSelectionKeyDefinition.key !== null,
|
||||||
|
callback: () => multiselectionKeyPressed.set(true)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
type: 'keydown'
|
type: 'keydown'
|
||||||
@@ -98,7 +102,8 @@
|
|||||||
trigger: [
|
trigger: [
|
||||||
{
|
{
|
||||||
...multiSelectionKeyDefinition,
|
...multiSelectionKeyDefinition,
|
||||||
callback: () => multiSelectionKeyDefinition.key && multiselectionKeyPressed.set(false)
|
enabled: multiSelectionKeyDefinition.key !== null,
|
||||||
|
callback: () => multiselectionKeyPressed.set(false)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
type: 'keyup'
|
type: 'keyup'
|
||||||
@@ -107,7 +112,8 @@
|
|||||||
trigger: [
|
trigger: [
|
||||||
{
|
{
|
||||||
...deleteKeyDefinition,
|
...deleteKeyDefinition,
|
||||||
callback: (event) => deleteKeyDefinition.key && deleteKeyPressed.set(true)
|
enabled: deleteKeyDefinition.key !== null,
|
||||||
|
callback: (detail) => !isInputDOMNode(detail.event) && deleteKeyPressed.set(true)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
type: 'keydown'
|
type: 'keydown'
|
||||||
@@ -116,7 +122,8 @@
|
|||||||
trigger: [
|
trigger: [
|
||||||
{
|
{
|
||||||
...deleteKeyDefinition,
|
...deleteKeyDefinition,
|
||||||
callback: () => deleteKeyDefinition.key && deleteKeyPressed.set(false)
|
enabled: deleteKeyDefinition.key !== null,
|
||||||
|
callback: () => deleteKeyPressed.set(false)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
type: 'keyup'
|
type: 'keyup'
|
||||||
@@ -125,7 +132,8 @@
|
|||||||
trigger: [
|
trigger: [
|
||||||
{
|
{
|
||||||
...panActivationKeyDefinition,
|
...panActivationKeyDefinition,
|
||||||
callback: () => panActivationKeyDefinition.key && panActivationKeyPressed.set(true)
|
enabled: panActivationKeyDefinition.key !== null,
|
||||||
|
callback: () => panActivationKeyPressed.set(true)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
type: 'keydown'
|
type: 'keydown'
|
||||||
@@ -134,7 +142,8 @@
|
|||||||
trigger: [
|
trigger: [
|
||||||
{
|
{
|
||||||
...panActivationKeyDefinition,
|
...panActivationKeyDefinition,
|
||||||
callback: () => panActivationKeyDefinition.key && panActivationKeyPressed.set(false)
|
enabled: panActivationKeyDefinition.key !== null,
|
||||||
|
callback: () => panActivationKeyPressed.set(false)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
type: 'keyup'
|
type: 'keyup'
|
||||||
@@ -143,7 +152,8 @@
|
|||||||
trigger: [
|
trigger: [
|
||||||
{
|
{
|
||||||
...zoomActivationKeyDefinition,
|
...zoomActivationKeyDefinition,
|
||||||
callback: () => zoomActivationKeyDefinition.key && zoomActivationKeyPressed.set(true)
|
enabled: zoomActivationKeyDefinition.key !== null,
|
||||||
|
callback: () => zoomActivationKeyPressed.set(true)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
type: 'keydown'
|
type: 'keydown'
|
||||||
@@ -152,7 +162,8 @@
|
|||||||
trigger: [
|
trigger: [
|
||||||
{
|
{
|
||||||
...zoomActivationKeyDefinition,
|
...zoomActivationKeyDefinition,
|
||||||
callback: () => zoomActivationKeyDefinition.key && zoomActivationKeyPressed.set(false)
|
enabled: zoomActivationKeyDefinition.key !== null,
|
||||||
|
callback: () => zoomActivationKeyPressed.set(false)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
type: 'keyup'
|
type: 'keyup'
|
||||||
|
|||||||
Reference in New Issue
Block a user