migrate some components
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
<svelte:options immutable />
|
||||
|
||||
<script lang="ts">
|
||||
import { setContext, onDestroy, createEventDispatcher } from 'svelte';
|
||||
import { setContext, onDestroy } from 'svelte';
|
||||
import { get, writable } from 'svelte/store';
|
||||
import cc from 'classcat';
|
||||
import { errorMessages, Position } from '@xyflow/system';
|
||||
@@ -11,42 +9,48 @@
|
||||
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
|
||||
import type { NodeWrapperProps } from './types';
|
||||
import { getNodeInlineStyleDimensions } from './utils';
|
||||
import type { NodeEventMap } from '$lib/types';
|
||||
import type { NodeEvents } from '$lib/types';
|
||||
|
||||
interface $$Props extends NodeWrapperProps {}
|
||||
|
||||
export let node: $$Props['node'];
|
||||
export let id: $$Props['id'];
|
||||
export let data: $$Props['data'] = {};
|
||||
export let selected: $$Props['selected'] = false;
|
||||
export let draggable: $$Props['draggable'] = undefined;
|
||||
export let selectable: $$Props['selectable'] = undefined;
|
||||
export let connectable: $$Props['connectable'] = true;
|
||||
export let deletable: $$Props['deletable'] = true;
|
||||
export let hidden: $$Props['hidden'] = false;
|
||||
export let dragging: boolean = false;
|
||||
export let resizeObserver: $$Props['resizeObserver'] = null;
|
||||
export let style: $$Props['style'] = undefined;
|
||||
export let type: $$Props['type'] = 'default';
|
||||
export let isParent: $$Props['isParent'] = false;
|
||||
export let positionX: $$Props['positionX'];
|
||||
export let positionY: $$Props['positionY'];
|
||||
export let sourcePosition: $$Props['sourcePosition'] = undefined;
|
||||
export let targetPosition: $$Props['targetPosition'] = undefined;
|
||||
export let zIndex: $$Props['zIndex'];
|
||||
export let measuredWidth: $$Props['measuredWidth'] = undefined;
|
||||
export let measuredHeight: $$Props['measuredHeight'] = undefined;
|
||||
export let initialWidth: $$Props['initialWidth'] = undefined;
|
||||
export let initialHeight: $$Props['initialHeight'] = undefined;
|
||||
export let width: $$Props['width'] = undefined;
|
||||
export let height: $$Props['height'] = undefined;
|
||||
export let dragHandle: $$Props['dragHandle'] = undefined;
|
||||
export let initialized: $$Props['initialized'] = false;
|
||||
export let parentId: $$Props['parentId'] = undefined;
|
||||
export let nodeClickDistance: $$Props['nodeClickDistance'] = undefined;
|
||||
|
||||
let className: string = '';
|
||||
export { className as class };
|
||||
let {
|
||||
node,
|
||||
id,
|
||||
data = {},
|
||||
selected = false,
|
||||
draggable,
|
||||
selectable,
|
||||
deletable,
|
||||
connectable = true,
|
||||
hidden = false,
|
||||
dragging = false,
|
||||
resizeObserver = null,
|
||||
style,
|
||||
class: className,
|
||||
type = 'default',
|
||||
isParent = false,
|
||||
parentId,
|
||||
positionX,
|
||||
positionY,
|
||||
sourcePosition,
|
||||
targetPosition,
|
||||
zIndex,
|
||||
measuredWidth,
|
||||
measuredHeight,
|
||||
initialWidth,
|
||||
initialHeight,
|
||||
width,
|
||||
height,
|
||||
dragHandle,
|
||||
initialized = false,
|
||||
nodeClickDistance,
|
||||
onnodeclick,
|
||||
onnodedrag,
|
||||
onnodedragstart,
|
||||
onnodedragstop,
|
||||
onnodemouseenter,
|
||||
onnodemouseleave,
|
||||
onnodemousemove,
|
||||
onnodecontextmenu
|
||||
}: NodeWrapperProps & NodeEvents = $props();
|
||||
|
||||
const store = useStore();
|
||||
const {
|
||||
@@ -57,78 +61,85 @@
|
||||
updateNodeInternals
|
||||
} = store;
|
||||
|
||||
let nodeRef: HTMLDivElement;
|
||||
let nodeRef: HTMLDivElement | null = $state(null);
|
||||
let prevNodeRef: HTMLDivElement | null = null;
|
||||
|
||||
const dispatchNodeEvent = createEventDispatcher<NodeEventMap>();
|
||||
const connectableStore = writable(connectable);
|
||||
let prevType: string | undefined = undefined;
|
||||
let prevSourcePosition: Position | undefined = undefined;
|
||||
let prevTargetPosition: Position | undefined = undefined;
|
||||
|
||||
$: nodeType = type || 'default';
|
||||
$: nodeTypeValid = !!$nodeTypes[nodeType];
|
||||
$: nodeComponent = $nodeTypes[nodeType] || DefaultNode;
|
||||
let prevType: string | undefined;
|
||||
let prevSourcePosition: Position | undefined;
|
||||
let prevTargetPosition: Position | undefined;
|
||||
|
||||
$: {
|
||||
if (!nodeTypeValid) {
|
||||
console.warn('003', errorMessages['error003'](type!));
|
||||
}
|
||||
let NodeComponent = $derived($nodeTypes[type] ?? DefaultNode);
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
$effect(() => {
|
||||
const valid = !!$nodeTypes[type];
|
||||
if (!valid) {
|
||||
console.warn('003', errorMessages['error003'](type!));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$: inlineStyleDimensions = getNodeInlineStyleDimensions({
|
||||
width,
|
||||
height,
|
||||
initialWidth,
|
||||
initialHeight,
|
||||
measuredWidth,
|
||||
measuredHeight
|
||||
let inlineStyleDimensions = $derived(
|
||||
getNodeInlineStyleDimensions({
|
||||
width,
|
||||
height,
|
||||
initialWidth,
|
||||
initialHeight,
|
||||
measuredWidth,
|
||||
measuredHeight
|
||||
})
|
||||
);
|
||||
|
||||
$effect(() => {
|
||||
connectableStore.set(!!connectable);
|
||||
});
|
||||
|
||||
$: {
|
||||
connectableStore.set(!!connectable);
|
||||
}
|
||||
|
||||
$: {
|
||||
$effect(() => {
|
||||
// if type, sourcePosition or targetPosition changes,
|
||||
// we need to re-calculate the handle positions
|
||||
const doUpdate =
|
||||
(prevType && nodeType !== prevType) ||
|
||||
(prevType && type !== prevType) ||
|
||||
(prevSourcePosition && sourcePosition !== prevSourcePosition) ||
|
||||
(prevTargetPosition && targetPosition !== prevTargetPosition);
|
||||
|
||||
if (doUpdate) {
|
||||
requestAnimationFrame(() =>
|
||||
updateNodeInternals(
|
||||
new Map([
|
||||
[
|
||||
id,
|
||||
{
|
||||
if (doUpdate && nodeRef !== null) {
|
||||
requestAnimationFrame(() => {
|
||||
if (nodeRef !== null) {
|
||||
updateNodeInternals(
|
||||
new Map([
|
||||
[
|
||||
id,
|
||||
nodeElement: nodeRef,
|
||||
force: true
|
||||
}
|
||||
]
|
||||
])
|
||||
)
|
||||
);
|
||||
{
|
||||
id,
|
||||
nodeElement: nodeRef,
|
||||
force: true
|
||||
}
|
||||
]
|
||||
])
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
prevType = nodeType;
|
||||
prevType = type;
|
||||
prevSourcePosition = sourcePosition;
|
||||
prevTargetPosition = targetPosition;
|
||||
}
|
||||
});
|
||||
|
||||
setContext('svelteflow__node_id', id);
|
||||
setContext('svelteflow__node_connectable', connectableStore);
|
||||
|
||||
$: {
|
||||
if (resizeObserver && (nodeRef !== prevNodeRef || !initialized)) {
|
||||
// TODO: extract this part!
|
||||
$effect(() => {
|
||||
// TODO: HOLY MOLY! changing the order of the initialized breaks effect subscriptions
|
||||
if (resizeObserver && (!initialized || nodeRef !== prevNodeRef)) {
|
||||
prevNodeRef && resizeObserver.unobserve(prevNodeRef);
|
||||
nodeRef && resizeObserver.observe(nodeRef);
|
||||
prevNodeRef = nodeRef;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
if (prevNodeRef) {
|
||||
@@ -143,12 +154,12 @@
|
||||
handleNodeSelection(id);
|
||||
}
|
||||
|
||||
dispatchNodeEvent('nodeclick', { node: node.internals.userNode, event });
|
||||
onnodeclick?.({ node: node.internals.userNode, event });
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
{#if !hidden}
|
||||
<div
|
||||
use:drag={{
|
||||
@@ -160,19 +171,19 @@
|
||||
nodeClickDistance,
|
||||
onNodeMouseDown: handleNodeSelection,
|
||||
onDrag: (event, _, targetNode, nodes) => {
|
||||
dispatchNodeEvent('nodedrag', { event, targetNode, nodes });
|
||||
onnodedrag?.({ event, targetNode, nodes });
|
||||
},
|
||||
onDragStart: (event, _, targetNode, nodes) => {
|
||||
dispatchNodeEvent('nodedragstart', { event, targetNode, nodes });
|
||||
onnodedragstart?.({ event, targetNode, nodes });
|
||||
},
|
||||
onDragStop: (event, _, targetNode, nodes) => {
|
||||
dispatchNodeEvent('nodedragstop', { event, targetNode, nodes });
|
||||
onnodedragstop?.({ event, targetNode, nodes });
|
||||
},
|
||||
store
|
||||
}}
|
||||
bind:this={nodeRef}
|
||||
data-id={id}
|
||||
class={cc(['svelte-flow__node', `svelte-flow__node-${nodeType}`, className])}
|
||||
class={cc(['svelte-flow__node', `svelte-flow__node-${type}`, className])}
|
||||
class:dragging
|
||||
class:selected
|
||||
class:draggable
|
||||
@@ -184,14 +195,13 @@
|
||||
style:transform="translate({positionX}px, {positionY}px)"
|
||||
style:visibility={initialized ? 'visible' : 'hidden'}
|
||||
style="{style ?? ''};{inlineStyleDimensions.width}{inlineStyleDimensions.height}"
|
||||
on:click={onSelectNodeHandler}
|
||||
on:mouseenter={(event) => dispatchNodeEvent('nodemouseenter', { node, event })}
|
||||
on:mouseleave={(event) => dispatchNodeEvent('nodemouseleave', { node, event })}
|
||||
on:mousemove={(event) => dispatchNodeEvent('nodemousemove', { node, event })}
|
||||
on:contextmenu={(event) => dispatchNodeEvent('nodecontextmenu', { node, event })}
|
||||
onclick={onSelectNodeHandler}
|
||||
onmouseenter={onnodemouseenter ? (event) => onnodemouseenter({ node, event }) : undefined}
|
||||
onmouseleave={onnodemouseleave ? (event) => onnodemouseleave({ node, event }) : undefined}
|
||||
onmousemove={onnodemousemove ? (event) => onnodemousemove({ node, event }) : undefined}
|
||||
oncontextmenu={onnodecontextmenu ? (event) => onnodecontextmenu({ node, event }) : undefined}
|
||||
>
|
||||
<svelte:component
|
||||
this={nodeComponent}
|
||||
<NodeComponent
|
||||
{data}
|
||||
{id}
|
||||
{selected}
|
||||
@@ -204,7 +214,7 @@
|
||||
{draggable}
|
||||
{dragHandle}
|
||||
{parentId}
|
||||
type={nodeType}
|
||||
{type}
|
||||
isConnectable={$connectableStore}
|
||||
positionAbsoluteX={positionX}
|
||||
positionAbsoluteY={positionY}
|
||||
|
||||
Reference in New Issue
Block a user