added dropstyle to widgets, shows dotted lines
This commit is contained in:
@@ -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 */}
|
||||
<div data-canvas className="tw-w-full tw-h-full tw-absolute tw-top-0 tw-select-none
|
||||
tw-bg-green-300"
|
||||
"
|
||||
ref={this.canvasRef}>
|
||||
<div className="tw-relative tw-w-full tw-h-full">
|
||||
{
|
||||
|
||||
@@ -129,7 +129,7 @@ const CanvasToolBar = memo(({ isOpen, widgetType, attrs = {} }) => {
|
||||
return (
|
||||
<div
|
||||
className={`tw-absolute tw-top-20 tw-right-5 tw-bg-white ${toolbarOpen ? "tw-w-[280px]" : "tw-w-0"
|
||||
} tw-px-4 tw-p-2 tw-h-[600px] tw-rounded-md tw-z-20 tw-shadow-lg
|
||||
} tw-px-4 tw-p-2 tw-h-[600px] tw-rounded-md tw-z-[1000] tw-shadow-lg
|
||||
tw-transition-transform tw-duration-75
|
||||
tw-flex tw-flex-col tw-gap-2 tw-overflow-y-auto`}
|
||||
>
|
||||
|
||||
@@ -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 (
|
||||
<WidgetDraggable widgetRef={this.elementRef}>
|
||||
<WidgetDraggable widgetRef={this.elementRef}
|
||||
enableDrag={this.state.dragEnabled}
|
||||
onDrop={this.handleDrop}
|
||||
onDragEnter={({dragElement, showDrop}) => {
|
||||
this.setState({
|
||||
showDroppableStyle: showDrop
|
||||
})
|
||||
}
|
||||
}
|
||||
onDragLeave={ () => {
|
||||
this.setState({
|
||||
showDroppableStyle: {
|
||||
allow: false,
|
||||
show: false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
>
|
||||
|
||||
<div data-widget-id={this.__id}
|
||||
ref={this.elementRef}
|
||||
className="tw-absolute tw-shadow-xl tw-w-fit tw-h-fit"
|
||||
@@ -533,6 +563,25 @@ class Widget extends React.Component {
|
||||
>
|
||||
|
||||
{this.renderContent()}
|
||||
|
||||
{
|
||||
// show drop style on drag hover
|
||||
this.state.showDroppableStyle.show &&
|
||||
<div className={`${this.state.showDroppableStyle.allow ? "tw-border-blue-600" : "tw-border-red-600"}
|
||||
tw-absolute tw-top-[-5px] tw-left-[-5px] tw-w-full tw-h-full tw-z-[2]
|
||||
tw-border-2 tw-border-dashed tw-rounded-lg tw-pointer-events-none
|
||||
|
||||
`}
|
||||
style={
|
||||
{
|
||||
width: "calc(100% + 10px)",
|
||||
height: "calc(100% + 10px)",
|
||||
}
|
||||
}
|
||||
>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div className={`tw-absolute tw-bg-transparent tw-scale-[1.1] tw-opacity-100
|
||||
tw-w-full tw-h-full tw-top-0
|
||||
${this.state.selected ? 'tw-border-2 tw-border-solid tw-border-blue-500' : 'tw-hidden'}`}>
|
||||
@@ -548,22 +597,38 @@ class Widget extends React.Component {
|
||||
<div
|
||||
className="tw-w-2 tw-h-2 tw-absolute tw--left-1 tw--top-1 tw-bg-blue-500"
|
||||
style={{ cursor: Cursor.NW_RESIZE }}
|
||||
onMouseDown={(e) => this.startResizing("nw", e)}
|
||||
onMouseDown={(e) => {
|
||||
this.startResizing("nw", e)
|
||||
this.setState({dragEnabled: false})
|
||||
}}
|
||||
onMouseLeave={() => this.setState({dragEnabled: true})}
|
||||
/>
|
||||
<div
|
||||
className="tw-w-2 tw-h-2 tw-absolute tw--right-1 tw--top-1 tw-bg-blue-500"
|
||||
style={{ cursor: Cursor.SW_RESIZE }}
|
||||
onMouseDown={(e) => this.startResizing("ne", e)}
|
||||
onMouseDown={(e) => {
|
||||
this.startResizing("ne", e)
|
||||
this.setState({dragEnabled: false})
|
||||
}}
|
||||
onMouseLeave={() => this.setState({dragEnabled: true})}
|
||||
/>
|
||||
<div
|
||||
className="tw-w-2 tw-h-2 tw-absolute tw--left-1 tw--bottom-1 tw-bg-blue-500"
|
||||
style={{ cursor: Cursor.SW_RESIZE }}
|
||||
onMouseDown={(e) => this.startResizing("sw", e)}
|
||||
onMouseDown={(e) => {
|
||||
this.startResizing("sw", e)
|
||||
this.setState({dragEnabled: false})
|
||||
}}
|
||||
onMouseLeave={() => this.setState({dragEnabled: true})}
|
||||
/>
|
||||
<div
|
||||
className="tw-w-2 tw-h-2 tw-absolute tw--right-1 tw--bottom-1 tw-bg-blue-500"
|
||||
style={{ cursor: Cursor.SE_RESIZE }}
|
||||
onMouseDown={(e) => this.startResizing("se", e)}
|
||||
onMouseDown={(e) => {
|
||||
this.startResizing("se", e)
|
||||
this.setState({dragEnabled: false})
|
||||
}}
|
||||
onMouseLeave={() => this.setState({dragEnabled: true})}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -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 (
|
||||
<div className={`${props.className} tw-w-fit tw-h-fit`}
|
||||
<div className={`${props.className} tw-w-fit tw-h-fit tw-bg-blue`}
|
||||
onDragOver={handleDragOver}
|
||||
onDrop={handleDropEvent}
|
||||
onDragEnter={handleDragEnter}
|
||||
onDragLeave={handleDragLeave}
|
||||
|
||||
onDragStart={handleDragStart}
|
||||
onDragEnd={handleDragEnd}
|
||||
draggable
|
||||
draggable={enableDrag}
|
||||
style={{ opacity: isDragging ? 0 : 1}} // hide the initial position when dragging
|
||||
>
|
||||
{
|
||||
showDroppable.show &&
|
||||
<div className={`${showDroppable.allow ? "tw-border-green-600" : "tw-border-red-600"}
|
||||
tw-absolute tw-top-0 tw-left-0 tw-w-full tw-h-full tw-z-[2]
|
||||
tw-border-2 tw-border-dashed tw-rounded-lg
|
||||
`}>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
{props.children}
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ export function DraggableWidgetCard({ name, img, url, innerRef}){
|
||||
// <Draggable className="tw-cursor-pointer" id={name}>
|
||||
<DraggableWrapper data-container={"sidebar"} dragElementType={"widget"} className="tw-cursor-pointer tw-w-fit tw-h-fit">
|
||||
|
||||
<div ref={innerRef} className="tw-select-none tw-h-[240px] tw-w-[280px] tw-flex tw-flex-col
|
||||
<div ref={innerRef} className="tw-select-none tw-h-[200px] tw-w-[230px] tw-flex tw-flex-col
|
||||
tw-rounded-md tw-overflow-hidden
|
||||
tw-gap-2 tw-text-gray-600 tw-bg-[#ffffff44] tw-border-solid tw-border-[1px]
|
||||
tw-border-[#888] ">
|
||||
|
||||
@@ -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 (
|
||||
<DragContext.Provider value={{ draggedElement, onDragStart, onDragEnd }}>
|
||||
<DragContext.Provider value={{ draggedElement, overElement, setOverElement, onDragStart, onDragEnd }}>
|
||||
{children}
|
||||
</DragContext.Provider>
|
||||
)
|
||||
|
||||
@@ -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 &&
|
||||
<div className={`${showDroppable.allow ? "tw-border-green-600" : "tw-border-red-600"}
|
||||
tw-absolute tw-top-0 tw-left-0 tw-w-full tw-h-full tw-z-[2]
|
||||
tw-border-2 tw-border-dashed tw-rounded-lg
|
||||
tw-border-2 tw-border-dashed tw-rounded-lg tw-pointer-events-none
|
||||
`}>
|
||||
</div>
|
||||
}
|
||||
{props.children}
|
||||
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -44,8 +44,8 @@ function Sidebar({tabs}){
|
||||
|
||||
return (
|
||||
<div className={`tw-relative tw-duration-[0.3s] tw-transition-all
|
||||
tw-max-w-[400px] tw-flex tw-h-full tw-z-10
|
||||
${sidebarOpen ? "tw-bg-white tw-min-w-[400px] tw-w-[400px] tw-shadow-lg":
|
||||
tw-max-w-[350px] tw-flex tw-h-full tw-z-10
|
||||
${sidebarOpen ? "tw-bg-white tw-min-w-[350px] tw-w-[350px] tw-shadow-lg":
|
||||
"tw-bg-primaryBg tw-min-w-[80px] tw-w-[80px]"}
|
||||
`}
|
||||
ref={sideBarRef}
|
||||
|
||||
Reference in New Issue
Block a user