File size: 5,850 Bytes
bc20498 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
<svelte:options immutable />
<script>import { setContext, onDestroy, createEventDispatcher } from 'svelte';
import { get, writable } from 'svelte/store';
import cc from 'classcat';
import { errorMessages, Position } from '@xyflow/system';
import drag from '../../actions/drag';
import { useStore } from '../../store';
import DefaultNode from '../nodes/DefaultNode.svelte';
import { getNodeInlineStyleDimensions } from './utils';
export let node;
export let id;
export let data = {};
export let selected = false;
export let draggable = undefined;
export let selectable = undefined;
export let connectable = true;
export let deletable = true;
export let hidden = false;
export let dragging = false;
export let resizeObserver = null;
export let style = undefined;
export let type = 'default';
export let isParent = false;
export let positionX;
export let positionY;
export let sourcePosition = undefined;
export let targetPosition = undefined;
export let zIndex;
export let measuredWidth = undefined;
export let measuredHeight = undefined;
export let initialWidth = undefined;
export let initialHeight = undefined;
export let width = undefined;
export let height = undefined;
export let dragHandle = undefined;
export let initialized = false;
export let parentId = undefined;
export let nodeClickDistance = undefined;
let className = '';
export { className as class };
const store = useStore();
const { nodeTypes, nodeDragThreshold, selectNodesOnDrag, handleNodeSelection, updateNodeInternals } = store;
let nodeRef;
let prevNodeRef = null;
const dispatchNodeEvent = createEventDispatcher();
const connectableStore = writable(connectable);
let prevType = undefined;
let prevSourcePosition = undefined;
let prevTargetPosition = undefined;
$: nodeType = type || 'default';
$: nodeTypeValid = !!$nodeTypes[nodeType];
$: nodeComponent = $nodeTypes[nodeType] || DefaultNode;
$: {
if (!nodeTypeValid) {
console.warn('003', errorMessages['error003'](type));
}
}
$: inlineStyleDimensions = getNodeInlineStyleDimensions({
width,
height,
initialWidth,
initialHeight,
measuredWidth,
measuredHeight
});
$: {
connectableStore.set(!!connectable);
}
$: {
// if type, sourcePosition or targetPosition changes,
// we need to re-calculate the handle positions
const doUpdate = (prevType && nodeType !== prevType) ||
(prevSourcePosition && sourcePosition !== prevSourcePosition) ||
(prevTargetPosition && targetPosition !== prevTargetPosition);
if (doUpdate) {
requestAnimationFrame(() => updateNodeInternals(new Map([
[
id,
{
id,
nodeElement: nodeRef,
force: true
}
]
])));
}
prevType = nodeType;
prevSourcePosition = sourcePosition;
prevTargetPosition = targetPosition;
}
setContext('svelteflow__node_id', id);
setContext('svelteflow__node_connectable', connectableStore);
$: {
if (resizeObserver && (nodeRef !== prevNodeRef || !initialized)) {
prevNodeRef && resizeObserver.unobserve(prevNodeRef);
nodeRef && resizeObserver.observe(nodeRef);
prevNodeRef = nodeRef;
}
}
onDestroy(() => {
if (prevNodeRef) {
resizeObserver?.unobserve(prevNodeRef);
}
});
function onSelectNodeHandler(event) {
if (selectable && (!get(selectNodesOnDrag) || !draggable || get(nodeDragThreshold) > 0)) {
// this handler gets called by XYDrag on drag start when selectNodesOnDrag=true
// here we only need to call it when selectNodesOnDrag=false
handleNodeSelection(id);
}
dispatchNodeEvent('nodeclick', { node: node.internals.userNode, event });
}
</script>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
{#if !hidden}
<div
use:drag={{
nodeId: id,
isSelectable: selectable,
disabled: false,
handleSelector: dragHandle,
noDragClass: 'nodrag',
nodeClickDistance,
onNodeMouseDown: handleNodeSelection,
onDrag: (event, _, targetNode, nodes) => {
dispatchNodeEvent('nodedrag', { event, targetNode, nodes });
},
onDragStart: (event, _, targetNode, nodes) => {
dispatchNodeEvent('nodedragstart', { event, targetNode, nodes });
},
onDragStop: (event, _, targetNode, nodes) => {
dispatchNodeEvent('nodedragstop', { event, targetNode, nodes });
},
store
}}
bind:this={nodeRef}
data-id={id}
class={cc(['svelte-flow__node', `svelte-flow__node-${nodeType}`, className])}
class:dragging
class:selected
class:draggable
class:connectable
class:selectable
class:nopan={draggable}
class:parent={isParent}
style:z-index={zIndex}
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 })}
>
<svelte:component
this={nodeComponent}
{data}
{id}
{selected}
{selectable}
{deletable}
{sourcePosition}
{targetPosition}
{zIndex}
{dragging}
{draggable}
{dragHandle}
{parentId}
type={nodeType}
isConnectable={$connectableStore}
positionAbsoluteX={positionX}
positionAbsoluteY={positionY}
{width}
{height}
/>
</div>
{/if}
|