DiagramNode = (props) => {
  const {
    id, content, coordinates, type, inputs, outputs, data, onPositionChange, onPortRegister, onNodeRemove,
    onDragNewSegment, onMount, onSegmentFail, onSegmentConnect, render, className, disableDrag,
  } = props;
  const registerPort = usePortRegistration(inputs, outputs, onPortRegister); // get the port registration method
  const { ref, onDragStart, onDrag } = useDrag({ throttleBy: 14 }); // get the drag n drop methods
  const dragStartPoint = useRef(coordinates); // keeps the drag start point in a persistent reference

  if (!disableDrag) {
    // when drag starts, save the starting coordinates into the `dragStartPoint` ref
    onDragStart(() => {
      dragStartPoint.current = coordinates;
    });

    // whilst dragging calculates the next coordinates and perform the `onPositionChange` callback
    onDrag((event, info) => {
      if (onPositionChange) {
        event.stopImmediatePropagation();
        event.stopPropagation();
        const nextCoords = [
          dragStartPoint.current[0] - info.offset[0],
          dragStartPoint.current[1] - info.offset[1],
        ];
        onPositionChange(id, nextCoords);
      }
    });
  }

  // on component unmount, remove its references
  useNodeUnregistration(onNodeRemove, inputs, outputs, id);

  // perform the onMount callback when the node is allowed to register
  useNodeRegistration(ref, onMount, id);

  const classList = useMemo(() => classNames('bi bi-diagram-node', {
    [`bi-diagram-node-${type}`]: !!type && !render,
  }, className), [type, className]);

  // generate ports
  const options = { registerPort, onDragNewSegment, onSegmentFail, onSegmentConnect };
  const InputPorts = inputs.map(portGenerator(options, 'input'));
  const OutputPorts = outputs.map(portGenerator(options, 'output'));
  const customRenderProps = { id, render, content, type, inputs: InputPorts, outputs: OutputPorts, data, className };

  return (
    <div className={classList} ref={ref} style={getDiagramNodeStyle(coordinates, disableDrag)}>
      {render && typeof render === 'function' && render(customRenderProps)}
      {!render && (
        <>
          {content}
          <div className="bi-port-wrapper">
            <div className="bi-input-ports">
              {InputPorts}
            </div>
            <div className="bi-output-ports">
              {OutputPorts}
            </div>
          </div>
        </>
      )}
    </div>
  );
}
A Diagram Node component displays a single diagram node, handles the drag n drop business logic and fires the
related callback. Displays input and output ports if existing and takes care of firing the `onPortRegister` callback
when a port is ready (aka rendered),