Reworked edge rerendering

This commit is contained in:
peterkogo
2024-12-11 15:22:44 +01:00
parent 1c67bf848f
commit 24735aa003
8 changed files with 79 additions and 124 deletions
@@ -11,51 +11,55 @@
import type { SvelteFlowStore } from '$lib/store/types';
const {
id,
type = 'default',
edge,
store,
onedgeclick,
onedgecontextmenu,
onedgemouseenter,
onedgemouseleave
}: { store: SvelteFlowStore; edge: EdgeLayouted } & EdgeEvents = $props();
let {
source,
target,
data = {},
style,
zIndex,
animated = false,
selected = false,
selectable,
deletable,
hidden,
label,
labelStyle,
markerStart,
markerEnd,
sourceHandle,
targetHandle,
sourceX,
sourceY,
targetX,
targetY,
sourcePosition,
targetPosition,
ariaLabel,
animated,
selected,
label,
labelStyle,
data = {},
style,
interactionWidth,
type = 'default',
sourceHandle,
targetHandle,
markerStart,
markerEnd,
selectable: edgeSelectable,
deletable,
hidden,
zIndex,
class: className,
onedgeclick,
onedgecontextmenu,
onedgemouseenter,
onedgemouseleave
}: { store: SvelteFlowStore } & EdgeLayouted & EdgeEvents = $props();
ariaLabel
} = $derived(edge);
const { id } = edge;
setContext('svelteflow__edge_id', id);
let edgeType = $derived(type ?? 'default');
let EdgeComponent = $derived(store.edgeTypes[edgeType] ?? BezierEdgeInternal);
let selectable = $derived(edgeSelectable ?? store.elementsSelectable);
let EdgeComponent = $derived(store.edgeTypes[type] ?? BezierEdgeInternal);
let markerStartUrl = $derived(
markerStart ? `url('#${getMarkerId(markerStart, store.flowId)}')` : undefined
);
let markerEndUrl = $derived(
markerEnd ? `url('#${getMarkerId(markerEnd, store.flowId)}')` : undefined
);
let isSelectable = $derived(selectable ?? store.elementsSelectable);
const handleEdgeSelect = useHandleEdgeSelect();
@@ -88,7 +92,7 @@
class={cc(['svelte-flow__edge', className])}
class:animated
class:selected
class:selectable={isSelectable}
class:selectable
data-id={id}
{onclick}
oncontextmenu={onedgecontextmenu
@@ -130,9 +134,9 @@
{data}
{style}
{interactionWidth}
selectable={isSelectable}
{selectable}
deletable={deletable ?? true}
type={edgeType}
{type}
sourceHandleId={sourceHandle}
targetHandleId={targetHandle}
markerStart={markerStartUrl}
@@ -4,9 +4,10 @@
import { errorMessages, nodeHasDimensions, Position } from '@xyflow/system';
import drag from '$lib/actions/drag';
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
import type { ConnectableContext, NodeWrapperProps } from './types';
import { getNodeInlineStyleDimensions } from './utils';
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
import type { ConnectableContext, NodeWrapperProps } from './types';
import type { Node, NodeEvents } from '$lib/types';
let {
@@ -25,7 +26,6 @@
}: NodeWrapperProps & NodeEvents = $props();
let {
id,
data = {},
selected = false,
draggable: _draggable,
@@ -48,18 +48,16 @@
dragHandle
} = $derived(node);
let { id } = node;
let draggable = $derived(_draggable ?? store.nodesDraggable);
let selectable = $derived(_selectable ?? store.elementsSelectable);
let connectable = $derived(_connectable ?? store.nodesConnectable);
let initialized = $derived(nodeHasDimensions(node));
// TODO: does this make sense
let flipFlop = false;
let shouldRerenderSignal = $derived.by(() =>
store.adoptNodes.has(id) ? (flipFlop = !flipFlop) : flipFlop
);
function getInternalNode(node: Node, shouldRerender: boolean = false) {
// we also pass store.nodes to this function to rerender when a node changes
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function getInternalNode(node: Node, nodes: Node[]) {
return { ...store.nodeLookup.get(node.id)! };
}
@@ -68,7 +66,7 @@
z: zIndex = 0,
positionAbsolute: { x: positionX, y: positionY }
}
} = $derived(getInternalNode(node, shouldRerenderSignal));
} = $derived(getInternalNode(node, store.nodes));
function isInParentLookup(id: string) {
return store.parentLookup.has(id);
@@ -1,45 +1,13 @@
import type { SvelteFlowStore } from '$lib/store/types';
import type { InternalNode, Node } from '$lib/types';
import type { Node } from '$lib/types';
export type ConnectableContext = {
value: boolean;
};
export type NodeWrapperProps = {
// Pick<
// Node,
// | 'id'
// | 'class'
// | 'connectable'
// | 'data'
// | 'draggable'
// | 'dragging'
// | 'selected'
// | 'selectable'
// | 'deletable'
// | 'style'
// | 'type'
// | 'sourcePosition'
// | 'targetPosition'
// | 'dragHandle'
// | 'hidden'
// | 'width'
// | 'height'
// | 'initialWidth'
// | 'initialHeight'
// | 'parentId'
// > & {
// measuredWidth?: number;
// measuredHeight?: number;
// type: string;
// positionX: number;
// positionY: number;
// 'on:nodeclick'?: (event: MouseEvent) => void;
// isParent?: boolean;
// zIndex: number;
// initialized: boolean;
node: Node;
store: SvelteFlowStore;
nodeClickDistance?: number;
resizeObserver?: ResizeObserver | null;
store: SvelteFlowStore;
};