feat(svelte): add event handlers and props, rename class names
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
export let interactionWidth: $$Props['interactionWidth'] = 20;
|
||||
</script>
|
||||
|
||||
<path d={path} fill="none" class="react-flow__edge-path" />
|
||||
<path d={path} fill="none" class="svelte-flow__edge-path" />
|
||||
|
||||
{#if interactionWidth}
|
||||
<path
|
||||
@@ -19,14 +19,14 @@
|
||||
fill="none"
|
||||
stroke-opacity={0}
|
||||
stroke-width={interactionWidth}
|
||||
class="react-flow__edge-interaction"
|
||||
class="svelte-flow__edge-interaction"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if label}
|
||||
<EdgeLabelRenderer>
|
||||
<div
|
||||
class="react-flow__edge-label"
|
||||
class="svelte-flow__edge-label"
|
||||
style:transform={`translate(-50%, -50%) translate(${labelX}px,${labelY}px)`}
|
||||
>
|
||||
{label}
|
||||
@@ -35,7 +35,7 @@
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.react-flow__edge-label {
|
||||
.svelte-flow__edge-label {
|
||||
position: absolute;
|
||||
background: white;
|
||||
}
|
||||
|
||||
@@ -7,15 +7,15 @@
|
||||
</script>
|
||||
|
||||
{#if $connectionPath}
|
||||
<svg width={$width} height={$height} class="react-flow__connectionline">
|
||||
<g class={cc(['react-flow__connection', $connection.status])}>
|
||||
<path d={$connectionPath} fill="none" class="react-flow__connection-path" />
|
||||
<svg width={$width} height={$height} class="svelte-flow__connectionline">
|
||||
<g class={cc(['svelte-flow__connection', $connection.status])}>
|
||||
<path d={$connectionPath} fill="none" class="svelte-flow__connection-path" />
|
||||
</g>
|
||||
</svg>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.react-flow__connectionline {
|
||||
.svelte-flow__connectionline {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@@ -26,12 +26,12 @@
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.react-flow__connection {
|
||||
.svelte-flow__connection {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.react-flow__edge-path,
|
||||
.react-flow__connection-path {
|
||||
.svelte-flow__edge-path,
|
||||
.svelte-flow__connection-path {
|
||||
stroke: #b1b1b7;
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
type $$Props = {};
|
||||
</script>
|
||||
|
||||
<div use:portal={'.react-flow__edgelabel-renderer'}>
|
||||
<div use:portal={'.svelte-flow__edgelabel-renderer'}>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import type { SvelteComponentTyped } from 'svelte';
|
||||
import { createEventDispatcher, type SvelteComponentTyped } from 'svelte';
|
||||
import { Position } from '@reactflow/system';
|
||||
|
||||
import { useStore } from '$lib/store';
|
||||
@@ -24,11 +24,23 @@
|
||||
export let selected: $$Props['selected'] = false;
|
||||
export let label: $$Props['label'] = undefined;
|
||||
|
||||
const { edgeTypes } = useStore();
|
||||
const { edgeTypes, edges } = useStore();
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const edgeComponent: typeof SvelteComponentTyped<EdgeProps> = $edgeTypes[type!] || BezierEdge;
|
||||
|
||||
function onClick() {
|
||||
const edge = $edges.find(e => e.id === id);
|
||||
dispatch('edge:click', edge);
|
||||
}
|
||||
</script>
|
||||
|
||||
<g class="react-flow__edge" class:animated data-id={id}>
|
||||
<g
|
||||
class="svelte-flow__edge"
|
||||
class:animated
|
||||
data-id={id}
|
||||
on:click={onClick}
|
||||
>
|
||||
<svelte:component
|
||||
this={edgeComponent}
|
||||
{id}
|
||||
@@ -47,12 +59,12 @@
|
||||
</g>
|
||||
|
||||
<style>
|
||||
.react-flow__edge {
|
||||
.svelte-flow__edge {
|
||||
pointer-events: visibleStroke;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.react-flow__edge :global(path) {
|
||||
.svelte-flow__edge :global(path) {
|
||||
stroke: #ccc;
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import cc from 'classcat';
|
||||
import { Position, type Connection, type HandleProps } from '@reactflow/system';
|
||||
import { isMouseEvent } from '@reactflow/utils';
|
||||
@@ -18,6 +19,8 @@
|
||||
const isTarget = type === 'target';
|
||||
const nodeId = getContext<string>('rf_nodeid');
|
||||
const handleId = id || null;
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
|
||||
const {
|
||||
connectionMode,
|
||||
@@ -31,11 +34,16 @@
|
||||
updateConnection
|
||||
} = useStore();
|
||||
|
||||
function dispatchEvent(eventName: string) {
|
||||
dispatch(eventName, { nodeId, handleId, type });
|
||||
}
|
||||
|
||||
function onConnectExtended(params: Connection) {
|
||||
addEdge(params);
|
||||
// @todo add props
|
||||
// onConnectAction?.(edgeParams);
|
||||
// onConnect?.(edgeParams);
|
||||
dispatchEvent('connect')
|
||||
}
|
||||
|
||||
function onPointerDown(event: MouseEvent | TouchEvent) {
|
||||
@@ -56,7 +64,9 @@
|
||||
onConnect: onConnectExtended,
|
||||
updateConnection,
|
||||
cancelConnection,
|
||||
panBy
|
||||
panBy,
|
||||
onConnectStart: () => dispatchEvent('connect:start'),
|
||||
onConnectEnd: () => dispatchEvent('connect:end')
|
||||
});
|
||||
}
|
||||
|
||||
@@ -74,8 +84,8 @@
|
||||
data-handlepos={position}
|
||||
data-id={`${nodeId}-${id}-${type}`}
|
||||
class={cc([
|
||||
'react-flow__handle',
|
||||
`react-flow__handle-${position}`,
|
||||
'svelte-flow__handle',
|
||||
`svelte-flow__handle-${position}`,
|
||||
'nodrag',
|
||||
'nopan',
|
||||
position
|
||||
@@ -90,7 +100,7 @@
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.react-flow__handle {
|
||||
.svelte-flow__handle {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
min-width: 5px;
|
||||
|
||||
@@ -43,7 +43,9 @@ export function handlePointerDown({
|
||||
cancelConnection,
|
||||
isValidConnection,
|
||||
edgeUpdaterType,
|
||||
onEdgeUpdateEnd
|
||||
onEdgeUpdateEnd,
|
||||
onConnectStart,
|
||||
onConnectEnd
|
||||
}: {
|
||||
event: MouseEvent | TouchEvent;
|
||||
handleId: string | null;
|
||||
@@ -61,8 +63,10 @@ export function handlePointerDown({
|
||||
panBy: (delta: XYPosition) => void;
|
||||
edgeUpdaterType?: HandleType;
|
||||
onEdgeUpdateEnd?: (evt: MouseEvent | TouchEvent) => void;
|
||||
onConnectStart: () => void;
|
||||
onConnectEnd: () => void;
|
||||
}): void {
|
||||
// when react-flow is used inside a shadow root we can't use document
|
||||
// when svelte-flow is used inside a shadow root we can't use document
|
||||
const doc = getHostForElement(event.target as HTMLElement);
|
||||
let autoPanId = 0;
|
||||
let prevClosestHandle: ConnectionHandle | null;
|
||||
@@ -113,7 +117,9 @@ export function handlePointerDown({
|
||||
});
|
||||
|
||||
// @todo add prop
|
||||
|
||||
// onConnectStart?.(event, { nodeId, handleId, handleType });
|
||||
onConnectStart();
|
||||
|
||||
function onPointerMove(event: MouseEvent | TouchEvent) {
|
||||
const transform = get(transformStore);
|
||||
@@ -166,7 +172,7 @@ export function handlePointerDown({
|
||||
if (connection.source !== connection.target && handleDomNode) {
|
||||
resetRecentHandle(prevActiveHandle);
|
||||
prevActiveHandle = handleDomNode;
|
||||
// @todo: remove the old class names "react-flow__handle-" in the next major version
|
||||
// @todo: remove the old class names "svelte-flow__handle-" in the next major version
|
||||
handleDomNode.classList.add('connecting');
|
||||
handleDomNode.classList.toggle('valid', isValid);
|
||||
}
|
||||
@@ -179,8 +185,8 @@ export function handlePointerDown({
|
||||
|
||||
// it's important to get a fresh reference from the store here
|
||||
// in order to get the latest state of onConnectEnd
|
||||
// @todo add onConnectEnd prop
|
||||
// getState().onConnectEnd?.(event);
|
||||
|
||||
onConnectEnd();
|
||||
|
||||
if (edgeUpdaterType) {
|
||||
onEdgeUpdateEnd?.(event);
|
||||
|
||||
@@ -81,11 +81,11 @@ export function isValidHandle(
|
||||
) {
|
||||
const isTarget = fromType === 'target';
|
||||
const handleDomNode = doc.querySelector(
|
||||
`.react-flow__handle[data-id="${handle?.nodeId}-${handle?.id}-${handle?.type}"]`
|
||||
`.svelte-flow__handle[data-id="${handle?.nodeId}-${handle?.id}-${handle?.type}"]`
|
||||
);
|
||||
const { x, y } = getEventPosition(event);
|
||||
const handleBelow = doc.elementFromPoint(x, y);
|
||||
const handleToCheck = handleBelow?.classList.contains('react-flow__handle')
|
||||
const handleToCheck = handleBelow?.classList.contains('svelte-flow__handle')
|
||||
? handleBelow
|
||||
: handleDomNode;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
$: rect = getRectOfNodes(selectedNodes, $nodeOrigin);
|
||||
</script>
|
||||
|
||||
{#if selectedNodes}
|
||||
{#if selectedNodes && $selectionRectMode === 'nodes'}
|
||||
<div
|
||||
class="selection-wrapper nopan"
|
||||
style={`width: ${rect.width}px; height: ${rect.height}px; transform: translate(${rect.x}px, ${rect.y}px)`}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { onMount, setContext, SvelteComponentTyped } from 'svelte';
|
||||
import { createEventDispatcher, onMount, setContext, SvelteComponentTyped } from 'svelte';
|
||||
import cc from 'classcat';
|
||||
import { type XYPosition, Position, errorMessages } from '@reactflow/system';
|
||||
|
||||
@@ -28,10 +28,9 @@
|
||||
let className: string = '';
|
||||
export { className as class };
|
||||
|
||||
let nodeRef: HTMLDivElement;
|
||||
|
||||
const { nodes, transform, nodeTypes, updateNodePositions, addSelectedNodes } = useStore();
|
||||
|
||||
let nodeRef: HTMLDivElement;
|
||||
const nodeTypeValid = !!$nodeTypes[type!];
|
||||
|
||||
if (!nodeTypeValid) {
|
||||
@@ -44,6 +43,7 @@
|
||||
const isSelectable = true;
|
||||
const selectNodesOnDrag = false;
|
||||
const isDraggable = true;
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
setContext('rf_nodeid', id);
|
||||
|
||||
@@ -55,30 +55,35 @@
|
||||
};
|
||||
});
|
||||
|
||||
function dispatchEvent(eventName: string) {
|
||||
const node = $nodes.find(n => n.id === id);
|
||||
dispatch(eventName, node);
|
||||
}
|
||||
|
||||
function onSelectNodeHandler(event: MouseEvent) {
|
||||
if (isSelectable && (!selectNodesOnDrag || !isDraggable)) {
|
||||
// this handler gets called within the drag start event when selectNodesOnDrag=true
|
||||
addSelectedNodes([id]);
|
||||
}
|
||||
|
||||
// if (onClick) {
|
||||
// const node = store.getState().nodeInternals.get(id)!;
|
||||
// onClick(event, { ...node });
|
||||
// }
|
||||
dispatchEvent('node:click')
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
use:drag={{ nodeId: id, nodes, transform, updateNodePositions }}
|
||||
class={cc(['react-flow__node', `react-flow__node-${type}`, className])}
|
||||
data-id={id}
|
||||
class={cc(['svelte-flow__node', `svelte-flow__node-${type}`, className])}
|
||||
class:initializing={!width && !height}
|
||||
class:dragging
|
||||
class:selected
|
||||
bind:this={nodeRef}
|
||||
on:click={onSelectNodeHandler}
|
||||
style:transform={`translate(${positionAbsolute.x}px, ${positionAbsolute.y}px)`}
|
||||
{style}
|
||||
data-id={id}
|
||||
on:click={onSelectNodeHandler}
|
||||
on:mouseenter={() => dispatchEvent('node:mouseenter')}
|
||||
on:mouseleave={() => dispatchEvent('node:mouseleave')}
|
||||
on:mousemove={() => dispatchEvent('node:mousemove')}
|
||||
>
|
||||
<svelte:component
|
||||
this={nodeComponent}
|
||||
@@ -90,11 +95,14 @@
|
||||
isConnectable={true}
|
||||
xPos={positionAbsolute.x}
|
||||
yPos={positionAbsolute.y}
|
||||
on:connect:start
|
||||
on:connect
|
||||
on:connect:end
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.react-flow__node {
|
||||
.svelte-flow__node {
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
text-align: center;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Node } from '$lib/types';
|
||||
|
||||
export type NodeWrapperProps = Node & {
|
||||
'on:nodeclick'?: (event: MouseEvent) => void;
|
||||
resizeObserver?: ResizeObserver | null;
|
||||
};
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
{#if isVisible}
|
||||
<div
|
||||
class="react-flow__selection"
|
||||
class="svelte-flow__selection"
|
||||
style={`width: ${width}px; height: ${height}px; transform: translate(${x}px, ${y}px)`}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.react-flow__selection {
|
||||
.svelte-flow__selection {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@@ -23,8 +23,8 @@
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.react-flow__selection:focus,
|
||||
.react-flow__selection:focus-visible {
|
||||
.svelte-flow__selection:focus,
|
||||
.svelte-flow__selection:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
export let selected: $$Props['selected'] = false;
|
||||
</script>
|
||||
|
||||
<Handle type="target" position={targetPosition} />
|
||||
<Handle type="target" position={targetPosition} on:connect:start on:connect on:connect:end />
|
||||
{data?.label}
|
||||
<Handle type="source" position={sourcePosition} />
|
||||
<Handle type="source" position={sourcePosition} on:connect:start on:connect on:connect:end />
|
||||
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { Position } from '@reactflow/system';
|
||||
|
||||
import type { NodeProps } from '$lib/types';
|
||||
import { Handle } from '$lib/components/Handle';
|
||||
|
||||
export let data: { label: string } = { label: 'Node' };
|
||||
export let isConnectable: boolean = true;
|
||||
export let sourcePosition: Position = Position.Bottom;
|
||||
interface $$Props extends NodeProps<{ label: string }> {}
|
||||
|
||||
export let id: $$Props['id'];
|
||||
export let data: $$Props['data'] = { label: 'Node' };
|
||||
export let isConnectable: $$Props['isConnectable'] = true;
|
||||
export let targetPosition: $$Props['targetPosition'] = Position.Top;
|
||||
export let sourcePosition: $$Props['sourcePosition'] = Position.Bottom;
|
||||
export let xPos: $$Props['xPos'];
|
||||
export let yPos: $$Props['yPos'];
|
||||
export let selected: $$Props['selected'] = false;
|
||||
</script>
|
||||
|
||||
{data?.label}
|
||||
<Handle type="source" position={sourcePosition} />
|
||||
<Handle type="source" position={sourcePosition} on:connect:start on:connect on:connect:end />
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { Position } from '@reactflow/system';
|
||||
|
||||
import type { NodeProps } from '$lib/types';
|
||||
import { Handle } from '$lib/components/Handle';
|
||||
|
||||
export let data: { label: string } = { label: 'Node' };
|
||||
export let isConnectable: boolean = true;
|
||||
export let targetPosition: Position = Position.Top;
|
||||
interface $$Props extends NodeProps<{ label: string }> {}
|
||||
|
||||
export let id: $$Props['id'];
|
||||
export let data: $$Props['data'] = { label: 'Node' };
|
||||
export let isConnectable: $$Props['isConnectable'] = true;
|
||||
export let targetPosition: $$Props['targetPosition'] = Position.Top;
|
||||
export let sourcePosition: $$Props['sourcePosition'] = Position.Bottom;
|
||||
export let xPos: $$Props['xPos'];
|
||||
export let yPos: $$Props['yPos'];
|
||||
export let selected: $$Props['selected'] = false;
|
||||
</script>
|
||||
|
||||
{data?.label}
|
||||
<Handle type="target" position={targetPosition} />
|
||||
<Handle type="target" position={targetPosition} on:connect:start on:connect on:connect:end />
|
||||
|
||||
Reference in New Issue
Block a user