ArchitectureDrag and Drop

Architecture

Drag and Drop

Learn how the drag and drop functionality is implemented in the workflow.


Drag and Drop Properties

Drag and drop interactions are represented in the workflow through two types of properties:

  • dragging properties: Exist on each element and store whether that element is currently being dragged and its location at that moment.
  • drop properties: Exist across the different workflow types and store the id of any dragged element that is near that drop area.

To understand how that works take a look at the following image.

React Flow workflow diagram showing the initial drag and drop state with nodes Start, A, B, and End in sequence, where node A has dragging set to null and the fork drop area has dropElse set to an empty object

When an element is being moved, the dragging property updates to reflect that.

React Flow workflow diagram showing node A being dragged to position x: 190, y: 220, with a dashed outline marking its original position in the flow, while dropElse remains an empty object

When an element gets close to a drop area, the corresponding drop property stores its id.

React Flow workflow diagram showing node A being dragged to position x: 210, y: 310 and hovering near a drop area, which now has dropElse set to A, indicating the dragged element has been registered by the nearest drop area

When the element is released, it is placed at the position of the drop area.

React Flow workflow diagram showing node A dropped into its new position inside the condition's else branch, with the workflow now reading Start → B → condition with A in the right branch → End

Entering and Leaving Drop Areas

In the workflow view, nodes can either act as drop areas or not. To represent this information each node has a dropArea boolean property.

React Flow workflow diagram showing the dropArea property on each node, where element nodes Start, A, B, and End have dropArea set to false, and all connector nodes between them have dropArea set to true

To detect when an element enters a drop area, the system checks the dropArea property of each node and finds the nearest drop area within range.

React Flow workflow diagram showing node A being dragged with dashed arrows pointing to all nearby drop area nodes, highlighting the nearest one as the active target

The following file implements this functionality.

// src/shared/kits/workflow/mvc/controller/utils/index.ts

// ...

export function createDropAreaChanges(
  node: TypedFlowNode,
  position: {
    x: number;
    y: number;
  },
  workflow: Workflow,
  flows: TypedFlows,
): WorkflowChange[] {
  const id = node.entity.meta.id;
  const changes: WorkflowChange[] = [];
  const currentDropArea = WorkflowUtils.dropArea(workflow, id);
  if (currentDropArea) {
    changes.push(createLeaveDropAreaChange(currentDropArea, id));
  }
  const closestNode = getClosestDropAreaNode(node, position, workflow, flows);
  if (closestNode) {
    changes.push(createEnterDropAreaChange(closestNode, id));
  }
  return changes;
}

// ...

On every drag change, it first checks if the element is currently in a drop area and exits it if so. It then finds the nearest drop area within a specific range and enters it if one is found.