migrate some components

This commit is contained in:
peterkogo
2024-11-13 13:33:49 +01:00
parent 880ed8886b
commit 28e4fad342
31 changed files with 505 additions and 459 deletions
@@ -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}
@@ -34,5 +34,5 @@ export type NodeWrapperProps = Pick<
zIndex: number;
node: InternalNode;
initialized: boolean;
nodeClickDistance?: number;
nodeClickDistance: number;
};