Merge branch 'dev' into fix/deep-clone-data

This commit is contained in:
Björn Otgaar
2025-12-02 15:06:14 +01:00
17 changed files with 600 additions and 86 deletions

View File

@@ -6,7 +6,12 @@ import { NodeDefaults, type NodeTypes } from '../NodeRegistry'
import addNode from '../utils/AddNode';
/**
* DraggableNodeProps dictates the type properties of a DraggableNode
* Props for a draggable node within the drag-and-drop toolbar.
*
* @property className - Optional custom CSS classes for styling.
* @property children - The visual content or label rendered inside the draggable node.
* @property nodeType - The type of node represented (key from `NodeTypes`).
* @property onDrop - Function called when the node is dropped on the flow pane.
*/
interface DraggableNodeProps {
className?: string;
@@ -16,15 +21,20 @@ interface DraggableNodeProps {
}
/**
* Definition of a node inside the drag and drop toolbar.
* These nodes require an onDrop function that dictates
* how the node is created in the graph.
* A draggable node element used in the drag-and-drop toolbar.
*
* Integrates with the NeoDrag library to handle drag events.
* On drop, it calls the provided `onDrop` function with the node type and drop position.
*
* @param props - The draggable node configuration.
* @returns A React element representing a draggable node.
*/
function DraggableNode({ className, children, nodeType, onDrop }: DraggableNodeProps) {
const draggableRef = useRef<HTMLDivElement>(null);
const [position, setPosition] = useState<XYPosition>({ x: 0, y: 0 });
// @ts-expect-error from the neodrag package — safe to ignore
// The NeoDrag hook enables smooth drag functionality for this element.
// @ts-expect-error: NeoDrag typing incompatibility — safe to ignore.
useDraggable(draggableRef, {
position,
onDrag: ({ offsetX, offsetY }) => {
@@ -48,16 +58,28 @@ function DraggableNode({ className, children, nodeType, onDrop }: DraggableNodeP
}
/**
* DndToolbar defines how the drag and drop toolbar component works
* and includes the default onDrop behavior.
* The drag-and-drop toolbar component for the visual programming interface.
*
* Displays draggable node templates based on entries in `NodeDefaults`.
* Each droppable node can be dragged into the flow pane to instantiate it.
*
* Automatically filters nodes whose `droppable` flag is set to `true`.
*
* @returns A React element representing the drag-and-drop toolbar.
*/
export function DndToolbar() {
const { screenToFlowPosition } = useReactFlow();
/**
* Handles dropping a node onto the flow pane.
* Translates screen coordinates into flow coordinates using React Flow utilities.
*/
const handleNodeDrop = useCallback(
(nodeType: keyof typeof NodeTypes, screenPosition: XYPosition) => {
const flow = document.querySelector('.react-flow');
const flowRect = flow?.getBoundingClientRect();
// Only add the node if it is inside the flow canvas area.
const isInFlow =
flowRect &&
screenPosition.x >= flowRect.left &&
@@ -74,7 +96,7 @@ export function DndToolbar() {
);
// Map over our default settings to see which of them have their droppable data set to true
// Map over the default nodes to get all nodes that can be dropped from the toolbar.
const droppableNodes = Object.entries(NodeDefaults)
.filter(([, data]) => data.droppable)
.map(([type, data]) => ({