Drag and Drop

by kassiomaia

HTML

<script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.3.1/d3.min.js"></script>
<div id="container">
</div>

CSS

.tooltip-draggable {
  padding: 0.7rem;
  background-color: white;
  border-radius: 3px;
  border: 2px dashed blue;
}

Babel + JSX

(window.Components = window.Components || {});

(function (React, Components, d3) {
	class SVGViewer extends React.Component {
  	static defaultProps = {
    	elements: [],
    	onStartDragElement: ({ x, y})  => null
    }
  	constructor(props) {
    	super(props)
      
      this.svgContainer = React.createRef()
    }
    
    componentDidMount() {
    	if (this.svgContainer.current) {
      	const { elements, onStartDragElement } = this.props

				const svg = d3.select(this.svgContainer.current)
        	.append('svg')
          .attr("width", window.width)
          .attr("height", window.height);
        
        
        elements.forEach(element => {
        	const instance = svg.append(element.type)
          Object.keys(element.attrs).forEach(attr => {
          	instance.attr(attr, element.attrs[attr])
          })

          instance.call(
          	d3
            	.drag()
            	.on('start', function(evt) {
	          		onStartDragElement({ element, instance, x: evt.x, y: evt.y})
          		}))
        })
      }
    }
  
  	render() {
    	return (
      	<div ref={this.svgContainer}></div>
      )
    }
  }

	Components.SVGViewer = SVGViewer
})(window.React, window.Components, window.d3);

(function (React, Components) {
	
  class Draggable extends React.Component {
  	
    static defaultProps = {
    	enabled: true,
    }
    
		constructor(props) {
    	super(props)
      
      this.draggable = React.createRef()
    }
  
  	render() {
    	const { children, enabled } = this.props
    	return (
      	<div ref={this.draggable} className="draggable" draggable={enabled}>
      	  {children}
      	</div>
      )
    }
  }
  
  Components.Draggable = Draggable
})(window.React, window.Components);

(function (React, ReactDOM, { Button, Draggable, SVGViewer }) {

	
  class TooltipDraggable extends React.Component {  
		
    wrapperDragEvents = ({ draggable: { current} }) => {
    	const { x, y } = this.props
    	if (current) {        
       ...