diff --git a/src/canvas/canvas.js b/src/canvas/canvas.js index 0bdd86f..a6aef97 100644 --- a/src/canvas/canvas.js +++ b/src/canvas/canvas.js @@ -573,7 +573,7 @@ class Canvas extends React.Component { const container = draggedElement.getAttribute("data-container") - console.log("dragged element: ", e, draggedElement, container) + console.log("Dropped on canvas",) // const canvasContainerRect = this.getCanvasContainerBoundingRect() const canvasRect = this.canvasRef.current.getBoundingClientRect() @@ -585,6 +585,7 @@ class Canvas extends React.Component { } if (container === "sidebar"){ + // if the widget is being dropped from the sidebar, use the info to create the widget first this.addWidget(Widget, ({id, widgetRef}) => { widgetRef.current.setPos(finalPosition.x, finalPosition.y) }) @@ -640,7 +641,7 @@ class Canvas extends React.Component { > {/* Canvas */}
{ diff --git a/src/canvas/toolbar.js b/src/canvas/toolbar.js index af8fca2..a16578a 100644 --- a/src/canvas/toolbar.js +++ b/src/canvas/toolbar.js @@ -129,7 +129,7 @@ const CanvasToolBar = memo(({ isOpen, widgetType, attrs = {} }) => { return (
diff --git a/src/canvas/widgets/base.js b/src/canvas/widgets/base.js index a68d4f6..3a85939 100644 --- a/src/canvas/widgets/base.js +++ b/src/canvas/widgets/base.js @@ -68,6 +68,12 @@ class Widget extends React.Component { enableRename: false, // will open the widgets editable div for renaming resizing: false, resizeCorner: "", + dragEnabled: true, + + showDroppableStyle: { // shows the droppable indicator + allow: false, + show: false, + }, pos: { x: 0, y: 0 }, size: { width: 100, height: 100 }, @@ -484,8 +490,19 @@ class Widget extends React.Component { }) } - handleDragStart = (event) => { - console.log("dragging event: ", event) + handleDrop = (event, dragElement) => { + console.log("dragging event: ", event, dragElement) + + const container = dragElement.getAttribute("data-container") + + if (container === "canvas"){ + + // this.canvas.getWidgetById + + // this._children.push() + + } + } renderContent() { @@ -514,16 +531,29 @@ class Widget extends React.Component { height: `${this.state.size.height}px`, } - let selectionStyle = { - x: "-5px", - y: "-5px", - width: this.boundingRect.width + 5, - height: this.boundingRect.height + 5 - } - + // console.log("Drag enabled: ", this.state.dragEnabled) // console.log("selected: ", this.state.selected) return ( - + { + this.setState({ + showDroppableStyle: showDrop + }) + } + } + onDragLeave={ () => { + this.setState({ + showDroppableStyle: { + allow: false, + show: false + } + }) + } + } + > +
{this.renderContent()} + + { + // show drop style on drag hover + this.state.showDroppableStyle.show && +
+
+ } +
@@ -548,22 +597,38 @@ class Widget extends React.Component {
this.startResizing("nw", e)} + onMouseDown={(e) => { + this.startResizing("nw", e) + this.setState({dragEnabled: false}) + }} + onMouseLeave={() => this.setState({dragEnabled: true})} />
this.startResizing("ne", e)} + onMouseDown={(e) => { + this.startResizing("ne", e) + this.setState({dragEnabled: false}) + }} + onMouseLeave={() => this.setState({dragEnabled: true})} />
this.startResizing("sw", e)} + onMouseDown={(e) => { + this.startResizing("sw", e) + this.setState({dragEnabled: false}) + }} + onMouseLeave={() => this.setState({dragEnabled: true})} />
this.startResizing("se", e)} + onMouseDown={(e) => { + this.startResizing("se", e) + this.setState({dragEnabled: false}) + }} + onMouseLeave={() => this.setState({dragEnabled: true})} />
diff --git a/src/canvas/widgets/widgetDragDrop.js b/src/canvas/widgets/widgetDragDrop.js index 71ad66b..ea58f70 100644 --- a/src/canvas/widgets/widgetDragDrop.js +++ b/src/canvas/widgets/widgetDragDrop.js @@ -1,14 +1,25 @@ -import { memo, useState } from "react" +import { memo, useEffect, useState } from "react" import { useDragWidgetContext } from "./draggableWidgetContext" import { useDragContext } from "../../components/draggable/draggableContext" -const WidgetDraggable = memo(({ widgetRef, dragElementType="widget", onDrop, droppableTags = ["widget"], ...props }) => { +/** + * @param {} - widgetRef - the widget ref for your widget + * @param {boolean} - enableDraggable - should the widget be draggable + * @param {string} - dragElementType - the widget type of widget so the droppable knows if the widget can be accepted + * @param {() => void} - onDrop - the widget type of widget so the droppable knows if the widget can be accepted + * @param {string[]} - droppableTags - array of widget that can be dropped on the widget + * + */ +const WidgetDraggable = memo(({ widgetRef, enableDrag=true, dragElementType="widget", + onDragEnter, onDragLeave, onDrop, + droppableTags = ["widget"], ...props }) => { // const { draggedElement, onDragStart, onDragEnd } = useDragWidgetContext() - const { draggedElement, onDragStart, onDragEnd } = useDragContext() + const { draggedElement, onDragStart, onDragEnd, overElement, setOverElement } = useDragContext() + // const [dragEnabled, setDragEnabled] = useState(enableDraggable) const [isDragging, setIsDragging] = useState(false) const [showDroppable, setShowDroppable] = useState({ @@ -19,7 +30,6 @@ const WidgetDraggable = memo(({ widgetRef, dragElementType="widget", onDrop, dro const handleDragStart = (e) => { setIsDragging(true) - console.log("Draggable widget ref: ", widgetRef) onDragStart(widgetRef?.current || null) // Create custom drag image with full opacity, this will ensure the image isn't taken from part of the canvas @@ -46,17 +56,32 @@ const WidgetDraggable = memo(({ widgetRef, dragElementType="widget", onDrop, dro const dragEleType = draggedElement.getAttribute("data-draggable-type") + // console.log("Drag entering...", overElement === e.currentTarget) + + setOverElement(e.currentTarget) + + let showDrop = { + allow: true, + show: true + } + if (droppableTags.length === 0 || droppableTags.includes(dragEleType)) { - setShowDroppable({ + showDrop = { allow: true, show: true - }) + } + } else { - setShowDroppable({ + showDrop = { allow: false, show: true - }) + } } + + setShowDroppable(showDrop) + if (onDragEnter) + onDragEnter({element: draggedElement, showDrop}) + } const handleDragOver = (e) => { @@ -70,6 +95,9 @@ const WidgetDraggable = memo(({ widgetRef, dragElementType="widget", onDrop, dro } const handleDropEvent = (e) => { + e.preventDefault() + e.stopPropagation() + // console.log("Dropped") setShowDroppable({ allow: false, @@ -88,6 +116,10 @@ const WidgetDraggable = memo(({ widgetRef, dragElementType="widget", onDrop, dro allow: false, show: false }) + + if (onDragLeave) + onDragLeave() + } } @@ -97,27 +129,18 @@ const WidgetDraggable = memo(({ widgetRef, dragElementType="widget", onDrop, dro } return ( -
- { - showDroppable.show && -
-
- } + > {props.children} - +
) diff --git a/src/components/cards.js b/src/components/cards.js index 7a7281d..567081b 100644 --- a/src/components/cards.js +++ b/src/components/cards.js @@ -32,7 +32,7 @@ export function DraggableWidgetCard({ name, img, url, innerRef}){ // -
diff --git a/src/components/draggable/draggableContext.js b/src/components/draggable/draggableContext.js index 7d77f15..35d8c52 100644 --- a/src/components/draggable/draggableContext.js +++ b/src/components/draggable/draggableContext.js @@ -7,6 +7,7 @@ export const useDragContext = () => useContext(DragContext) // Provider component to wrap around parts of your app that need drag-and-drop functionality export const DragProvider = ({ children }) => { const [draggedElement, setDraggedElement] = useState(null) + const [overElement, setOverElement] = useState(null) // the element the dragged items is over const onDragStart = (element) => { setDraggedElement(element) @@ -17,7 +18,7 @@ export const DragProvider = ({ children }) => { } return ( - + {children} ) diff --git a/src/components/draggable/droppable.js b/src/components/draggable/droppable.js index b7173ab..40765f7 100644 --- a/src/components/draggable/droppable.js +++ b/src/components/draggable/droppable.js @@ -5,7 +5,7 @@ import { useDragContext } from "./draggableContext" const DroppableWrapper = memo(({onDrop, droppableTags=["widget"], ...props}) => { - const { draggedElement } = useDragContext() + const { draggedElement, overElement, setOverElement } = useDragContext() const [showDroppable, setShowDroppable] = useState({ show: false, @@ -17,6 +17,10 @@ const DroppableWrapper = memo(({onDrop, droppableTags=["widget"], ...props}) => const dragElementType = draggedElement.getAttribute("data-draggable-type") + // console.log("Current target: ", e.currentTarget) + + setOverElement(e.currentTarget) + if (droppableTags.length === 0 || droppableTags.includes(dragElementType)){ setShowDroppable({ allow: true, @@ -41,6 +45,7 @@ const DroppableWrapper = memo(({onDrop, droppableTags=["widget"], ...props}) => } const handleDropEvent = (e) => { + e.stopPropagation() setShowDroppable({ allow: false, @@ -69,15 +74,17 @@ const DroppableWrapper = memo(({onDrop, droppableTags=["widget"], ...props}) => onDragEnter={handleDragEnter} onDragLeave={handleDragLeave} > + + {props.children} + { showDroppable.show &&
} - {props.children}
) diff --git a/src/sidebar/sidebar.js b/src/sidebar/sidebar.js index 786cb36..e9147ec 100644 --- a/src/sidebar/sidebar.js +++ b/src/sidebar/sidebar.js @@ -44,8 +44,8 @@ function Sidebar({tabs}){ return (