feat(svelte): add panActivationKey
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"dev": "turbo run dev --parallel",
|
||||
"dev:svelte": "turbo run dev --filter=svelte --filter=system",
|
||||
"dev:react": "turbo run dev --filter=react",
|
||||
"build": "turbo run build",
|
||||
"test": "turbo run test",
|
||||
"lint": "turbo run lint",
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@svelte-put/shortcut": "^2.0.0",
|
||||
"@svelte-put/shortcut": "^3.0.0",
|
||||
"@xyflow/system": "workspace:*",
|
||||
"classcat": "^5.0.4"
|
||||
},
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
'customnode',
|
||||
'drag-n-drop',
|
||||
'edges',
|
||||
'figma',
|
||||
'interaction',
|
||||
'overview',
|
||||
'stress',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher, type SvelteComponentTyped } from 'svelte';
|
||||
import { createEventDispatcher, SvelteComponent, type ComponentType } from 'svelte';
|
||||
import { getMarkerId } from '@xyflow/system';
|
||||
|
||||
import { useStore } from '$lib/store';
|
||||
@@ -36,7 +36,7 @@
|
||||
const { edges, edgeTypes, flowId, addSelectedEdges } = useStore();
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const edgeComponent: typeof SvelteComponentTyped<EdgeProps> = $edgeTypes[type!] || BezierEdge;
|
||||
const edgeComponent: ComponentType<SvelteComponent<EdgeProps>> = $edgeTypes[type!] || BezierEdge;
|
||||
|
||||
$: markerStartUrl = markerStart ? `url(#${getMarkerId(markerStart, $flowId)})` : undefined;
|
||||
$: markerEndUrl = markerEnd ? `url(#${getMarkerId(markerEnd, $flowId)})` : undefined;
|
||||
@@ -52,6 +52,7 @@
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
||||
<g
|
||||
class="svelte-flow__edge"
|
||||
class:animated
|
||||
|
||||
@@ -96,6 +96,8 @@
|
||||
on:mousedown={onPointerDown}
|
||||
on:touchstart={onPointerDown}
|
||||
{style}
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
|
||||
export let selectionKey: $$Props['selectionKey'] = 'Shift';
|
||||
export let deleteKey: $$Props['deleteKey'] = 'Backspace';
|
||||
export let panActivationKey: $$Props['panActivationKey'] = ' ';
|
||||
|
||||
const { selectionKeyPressed, deleteKeyPressed } = useStore();
|
||||
const { selectionKeyPressed, deleteKeyPressed, panActivationKeyPressed } = useStore();
|
||||
|
||||
function isKeyObject(key?: KeyDefinition): key is KeyDefinitionObject {
|
||||
return typeof key === 'object';
|
||||
@@ -21,6 +22,10 @@
|
||||
|
||||
$: deleteKeyString = typeof deleteKey === 'string' ? deleteKey : deleteKey!.key;
|
||||
$: deleteKeyModifier = isKeyObject(deleteKey) ? deleteKey?.modifier : [];
|
||||
|
||||
$: panActivationKeyString =
|
||||
typeof panActivationKey === 'string' ? panActivationKey : panActivationKey!.key;
|
||||
$: panActivationKeyModifier = isKeyObject(panActivationKey) ? panActivationKey?.modifier : [];
|
||||
</script>
|
||||
|
||||
<svelte:window
|
||||
@@ -49,7 +54,10 @@
|
||||
{
|
||||
key: deleteKeyString,
|
||||
modifier: deleteKeyModifier,
|
||||
callback: () => deleteKeyPressed.set(true)
|
||||
callback: () => {
|
||||
console.log('delete');
|
||||
deleteKeyPressed.set(true);
|
||||
}
|
||||
}
|
||||
],
|
||||
type: 'keydown'
|
||||
@@ -64,4 +72,24 @@
|
||||
],
|
||||
type: 'keyup'
|
||||
}}
|
||||
use:shortcut={{
|
||||
trigger: [
|
||||
{
|
||||
key: panActivationKeyString,
|
||||
modifier: panActivationKeyModifier,
|
||||
callback: () => panActivationKeyPressed.set(true)
|
||||
}
|
||||
],
|
||||
type: 'keydown'
|
||||
}}
|
||||
use:shortcut={{
|
||||
trigger: [
|
||||
{
|
||||
key: panActivationKeyString,
|
||||
modifier: panActivationKeyModifier,
|
||||
callback: () => panActivationKeyPressed.set(false)
|
||||
}
|
||||
],
|
||||
type: 'keyup'
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -3,4 +3,5 @@ import type { KeyDefinition } from '$lib/types';
|
||||
export type KeyHandlerProps = {
|
||||
selectionKey?: KeyDefinition;
|
||||
deleteKey?: KeyDefinition;
|
||||
panActivationKey?: KeyDefinition;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount, setContext, SvelteComponentTyped } from 'svelte';
|
||||
import {
|
||||
createEventDispatcher,
|
||||
onMount,
|
||||
setContext,
|
||||
SvelteComponent,
|
||||
type ComponentType
|
||||
} from 'svelte';
|
||||
import cc from 'classcat';
|
||||
import { errorMessages, type NodeProps } from '@xyflow/system';
|
||||
|
||||
@@ -19,8 +25,6 @@
|
||||
export let dragging: boolean = false;
|
||||
export let resizeObserver: NodeWrapperProps['resizeObserver'] = null;
|
||||
export let style: NodeWrapperProps['style'] = undefined;
|
||||
export let width: NodeWrapperProps['width'] = undefined;
|
||||
export let height: NodeWrapperProps['height'] = undefined;
|
||||
export let type: NodeWrapperProps['type'] = 'default';
|
||||
export let isParent: NodeWrapperProps['isParent'] = false;
|
||||
export let positionAbsolute: NodeWrapperProps['positionAbsolute'] = undefined;
|
||||
@@ -43,7 +47,7 @@
|
||||
type = 'default';
|
||||
}
|
||||
|
||||
const nodeComponent: typeof SvelteComponentTyped<NodeProps> = $nodeTypes[type!] || DefaultNode;
|
||||
const nodeComponent: ComponentType<SvelteComponent<NodeProps>> = $nodeTypes[type!] || DefaultNode;
|
||||
const selectNodesOnDrag = false;
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
@@ -74,6 +78,7 @@
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div
|
||||
use:drag={{
|
||||
nodeId: id,
|
||||
|
||||
@@ -55,8 +55,6 @@
|
||||
positionAbsolute={node.positionAbsolute}
|
||||
positionOrigin={posOrigin}
|
||||
isParent={!!node[internalsSymbol]?.isParent}
|
||||
width={node.width}
|
||||
height={node.height}
|
||||
style={node.style}
|
||||
class={node.class}
|
||||
type={node.type}
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
selectionRectMode,
|
||||
selectionKeyPressed,
|
||||
selectionMode,
|
||||
panActivationKeyPressed,
|
||||
unselectNodesAndEdges
|
||||
} = useStore();
|
||||
|
||||
@@ -61,6 +62,7 @@
|
||||
|
||||
$: isSelecting = $selectionKeyPressed;
|
||||
$: hasActiveSelection = $elementsSelectable && (isSelecting || $selectionRectMode === 'user');
|
||||
$: _panOnDrag = $panActivationKeyPressed || panOnDrag;
|
||||
|
||||
function onClick(event: MouseEvent) {
|
||||
dispatch('paneclick', event);
|
||||
@@ -159,7 +161,7 @@
|
||||
};
|
||||
|
||||
const onContextMenu = (event: MouseEvent) => {
|
||||
if (Array.isArray(panOnDrag) && panOnDrag?.includes(2)) {
|
||||
if (Array.isArray(_panOnDrag) && _panOnDrag?.includes(2)) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
@@ -168,6 +170,8 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
bind:this={container}
|
||||
class="svelte-flow__pane"
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
export let edgeTypes: $$Props['edgeTypes'] = undefined;
|
||||
export let selectionKey: $$Props['selectionKey'] = undefined;
|
||||
export let selectionMode: $$Props['selectionMode'] = undefined;
|
||||
export let panActivationKey: $$Props['panActivationKey'] = undefined;
|
||||
export let nodesDraggable: $$Props['nodesDraggable'] = undefined;
|
||||
export let nodesConnectable: $$Props['nodesConnectable'] = undefined;
|
||||
export let elementsSelectable: $$Props['elementsSelectable'] = undefined;
|
||||
@@ -124,8 +125,9 @@
|
||||
on:dragover
|
||||
on:drop
|
||||
{...$$restProps}
|
||||
role="application"
|
||||
>
|
||||
<KeyHandler {selectionKey} {deleteKey} />
|
||||
<KeyHandler {selectionKey} {deleteKey} {panActivationKey} />
|
||||
<Zoom
|
||||
{initialViewport}
|
||||
{onMoveStart}
|
||||
@@ -189,7 +191,7 @@
|
||||
|
||||
:root {
|
||||
--background-color-default: #fff;
|
||||
--background-pattern-color-default: #eee;
|
||||
--background-pattern-color-default: #ddd;
|
||||
|
||||
--minimap-background-color-default: #fff;
|
||||
--minimap-mask-color-default: rgb(240, 240, 240, 0.6);
|
||||
|
||||
@@ -25,6 +25,7 @@ export type SvelteFlowProps = DOMAttributes<HTMLDivElement> & {
|
||||
nodeTypes?: NodeTypes;
|
||||
edgeTypes?: EdgeTypes;
|
||||
selectionKey?: KeyDefinition;
|
||||
panActivationKey?: KeyDefinition;
|
||||
deleteKey?: KeyDefinition;
|
||||
fitView?: boolean;
|
||||
nodeOrigin?: NodeOrigin;
|
||||
|
||||
@@ -27,10 +27,12 @@
|
||||
maxZoom,
|
||||
dragging,
|
||||
translateExtent,
|
||||
lib
|
||||
lib,
|
||||
panActivationKeyPressed
|
||||
} = useStore();
|
||||
|
||||
$: viewPort = initialViewport || { x: 0, y: 0, zoom: 1 };
|
||||
$: _panOnDrag = $panActivationKeyPressed || panOnDrag;
|
||||
</script>
|
||||
|
||||
<div
|
||||
@@ -49,7 +51,7 @@
|
||||
zoomOnDoubleClick,
|
||||
zoomOnPinch,
|
||||
panOnScroll,
|
||||
panOnDrag,
|
||||
panOnDrag: _panOnDrag,
|
||||
panOnScrollSpeed: 0.5,
|
||||
panOnScrollMode: panOnScrollMode || PanOnScrollMode.Free,
|
||||
zoomActivationKeyPressed: false,
|
||||
|
||||
@@ -68,6 +68,7 @@ export const getInitialStore = () => ({
|
||||
selectionKeyPressed: writable<boolean>(false),
|
||||
multiselectionKeyPressed: writable<boolean>(false),
|
||||
deleteKeyPressed: writable<boolean>(false),
|
||||
panActivationKeyPressed: writable<boolean>(false),
|
||||
selectionRectMode: writable<string | null>(null),
|
||||
selectionMode: writable<SelectionMode>(SelectionMode.Partial),
|
||||
nodeTypes: writable<NodeTypes>(initialNodeTypes),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import type { SvelteComponentTyped } from 'svelte';
|
||||
import type { SvelteComponent, ComponentType } from 'svelte';
|
||||
import type {
|
||||
EdgeBase,
|
||||
BezierPathOptions,
|
||||
@@ -45,7 +45,7 @@ export type EdgeProps = Omit<Edge, 'sourceHandle' | 'targetHandle'> &
|
||||
targetHandleId?: string | null;
|
||||
};
|
||||
|
||||
export type EdgeTypes = Record<string, typeof SvelteComponentTyped<EdgeProps>>;
|
||||
export type EdgeTypes = Record<string, ComponentType<SvelteComponent<EdgeProps>>>;
|
||||
|
||||
export type DefaultEdgeOptions = DefaultEdgeOptionsBase<Edge>;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
import type { SvelteComponentTyped } from 'svelte';
|
||||
import type { ComponentType, SvelteComponent } from 'svelte';
|
||||
import type { NodeBase, NodeProps } from '@xyflow/system';
|
||||
|
||||
// @todo: currently the helper function only like Node from '@reactflow/core'
|
||||
@@ -14,6 +14,6 @@ export type Node<
|
||||
style?: string;
|
||||
};
|
||||
|
||||
export type NodeTypes = Record<string, typeof SvelteComponentTyped<NodeProps>>;
|
||||
export type NodeTypes = Record<string, ComponentType<SvelteComponent<NodeProps>>>;
|
||||
|
||||
export type DefaultNodeOptions = Partial<Omit<Node, 'id'>>;
|
||||
|
||||
54
packages/svelte/src/routes/figma/+page.svelte
Normal file
54
packages/svelte/src/routes/figma/+page.svelte
Normal file
@@ -0,0 +1,54 @@
|
||||
<script lang="ts">
|
||||
import { writable } from 'svelte/store';
|
||||
import {
|
||||
SvelteFlow,
|
||||
Controls,
|
||||
Background,
|
||||
BackgroundVariant,
|
||||
SelectionMode
|
||||
} from '../../lib/index';
|
||||
|
||||
const onPaneContextMenu = (e: any) => {
|
||||
e.preventDefault();
|
||||
console.log('context menu');
|
||||
};
|
||||
|
||||
const panOnDrag = [1, 2];
|
||||
|
||||
const onMoveStart = (e: any) => console.log('move start', e);
|
||||
const onMove = (e: any) => console.log('move', e);
|
||||
const onMoveEnd = (e: any) => console.log('move end', e);
|
||||
|
||||
const nodes = writable([
|
||||
{
|
||||
id: '1',
|
||||
type: 'input',
|
||||
data: { label: 'Node 1' },
|
||||
position: { x: 250, y: 5 },
|
||||
className: 'light'
|
||||
},
|
||||
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, className: 'light' },
|
||||
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light' },
|
||||
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 }, className: 'light' }
|
||||
]);
|
||||
|
||||
const edges = writable([
|
||||
{ id: 'e1-2', source: '1', target: '2', animated: true },
|
||||
{ id: 'e1-3', source: '1', target: '3' }
|
||||
]);
|
||||
</script>
|
||||
|
||||
<SvelteFlow
|
||||
{nodes}
|
||||
{edges}
|
||||
fitView
|
||||
selectionMode={SelectionMode.Partial}
|
||||
panOnScroll
|
||||
{panOnDrag}
|
||||
{onMoveStart}
|
||||
{onMove}
|
||||
{onMoveEnd}
|
||||
>
|
||||
<Controls />
|
||||
<Background variant={BackgroundVariant.Dots} />
|
||||
</SvelteFlow>
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { isWrappedWithClass } from './utils';
|
||||
|
||||
export type FilterParams = {
|
||||
|
||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@@ -200,8 +200,8 @@ importers:
|
||||
packages/svelte:
|
||||
dependencies:
|
||||
'@svelte-put/shortcut':
|
||||
specifier: ^2.0.0
|
||||
version: registry.npmjs.org/@svelte-put/shortcut@2.0.0
|
||||
specifier: ^3.0.0
|
||||
version: registry.npmjs.org/@svelte-put/shortcut@3.0.0
|
||||
'@xyflow/system':
|
||||
specifier: workspace:*
|
||||
version: link:../system
|
||||
@@ -1797,10 +1797,10 @@ packages:
|
||||
version: 2.0.0
|
||||
dev: true
|
||||
|
||||
registry.npmjs.org/@svelte-put/shortcut@2.0.0:
|
||||
resolution: {integrity: sha512-dDyxIFlRz+W6wxwQtl2jUen0rX8ofV2VBWaJdz0QehLb0IMDzP3aWM9W4k8cAZQIGmTT0adr1+Gt7HPPUugcpQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@svelte-put/shortcut/-/shortcut-2.0.0.tgz}
|
||||
registry.npmjs.org/@svelte-put/shortcut@3.0.0:
|
||||
resolution: {integrity: sha512-nZg3pwpTi9wUsvQPlqOzEsxZcF2jmY5j+VBq/20IUjjd2OpM92XqZAga0PCCjE6OuEobOt58UMnC2QZgOvk0tQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@svelte-put/shortcut/-/shortcut-3.0.0.tgz}
|
||||
name: '@svelte-put/shortcut'
|
||||
version: 2.0.0
|
||||
version: 3.0.0
|
||||
dev: false
|
||||
|
||||
registry.npmjs.org/@sveltejs/adapter-auto@2.1.0(@sveltejs/kit@1.22.6):
|
||||
|
||||
Reference in New Issue
Block a user