working on dnd inside a container
This commit is contained in:
@@ -191,8 +191,6 @@ class Canvas extends React.Component {
|
||||
getWidgetFromTarget(target) {
|
||||
// TODO: improve search, currently O(n), but can be improved via this.state.widgets or something
|
||||
|
||||
console.log("Target: ", target, )
|
||||
|
||||
let innerWidget = null
|
||||
for (let [key, ref] of Object.entries(this.widgetRefs)) {
|
||||
|
||||
@@ -200,9 +198,6 @@ class Canvas extends React.Component {
|
||||
innerWidget = ref.current
|
||||
break
|
||||
}
|
||||
|
||||
console.log("ref: ", ref.current)
|
||||
|
||||
// console.log("refs: ", ref)
|
||||
// TODO: remove the ref.current? if there are bugs it would become hard to debug
|
||||
if (ref.current?.getElement()?.contains(target)) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import { DragContext } from "../../components/draggable/draggableContext"
|
||||
import { isNumeric, removeKeyFromObject } from "../../utils/common"
|
||||
import { info } from "autoprefixer"
|
||||
import { message } from "antd"
|
||||
import WidgetDnd from "./widgetDnd"
|
||||
|
||||
|
||||
// TODO: make it possible to apply widgetInnerStyle on load
|
||||
@@ -1104,9 +1105,9 @@ class Widget extends React.Component {
|
||||
...this.state.widgetOuterStyling,
|
||||
cursor: this.cursor,
|
||||
zIndex: this.state.zIndex,
|
||||
position: this.state.positionType, // don't change this if it has to be movable on the canvas
|
||||
top: `${this.state.pos.y}px`,
|
||||
left: `${this.state.pos.x}px`,
|
||||
// position: this.state.positionType, // don't change this if it has to be movable on the canvas
|
||||
// top: `${this.state.pos.y}px`,
|
||||
// left: `${this.state.pos.x}px`,
|
||||
width: width,
|
||||
height: height,
|
||||
minWidth: minWidth,
|
||||
@@ -1115,7 +1116,7 @@ class Widget extends React.Component {
|
||||
}
|
||||
|
||||
// const boundingRect = this.getBoundingRect
|
||||
|
||||
// TODO: rewrite Drag and drop
|
||||
// FIXME: if the parent container has tw-overflow-none, then the resizable indicator are also hidden
|
||||
return (
|
||||
|
||||
@@ -1126,137 +1127,153 @@ class Widget extends React.Component {
|
||||
|
||||
|
||||
return (
|
||||
<div data-widget-id={this.__id}
|
||||
ref={this.elementRef}
|
||||
className="tw-shadow-xl tw-w-fit tw-h-fit"
|
||||
style={outerStyle}
|
||||
data-draggable-type={this.getWidgetType()} // helps with droppable
|
||||
data-container={this.state.widgetContainer} // indicates how the canvas should handle dragging, one is sidebar other is canvas
|
||||
|
||||
data-drag-start-within // this attribute indicates that the drag is occurring from within the project and not a outside file drop
|
||||
<WidgetDnd id={this.__id}
|
||||
disabled={false && this.state.dragEnabled}
|
||||
data-draggable-type={this.getWidgetType()} // helps with droppable
|
||||
dragElementType={this.getWidgetType()}
|
||||
// onDragOver={(e) => this.handleDragOver(e, draggedElement)}
|
||||
// onDrop={(e) => {this.handleDropEvent(e, draggedElement, widgetClass); onDragEnd()}}
|
||||
|
||||
draggable={this.state.dragEnabled}
|
||||
// onDragEnter={(e) => this.handleDragEnter(e, draggedElement, setOverElement)}
|
||||
// onDragLeave={(e) => this.handleDragLeave(e, draggedElement, overElement)}
|
||||
|
||||
onDragOver={(e) => this.handleDragOver(e, draggedElement)}
|
||||
onDrop={(e) => {this.handleDropEvent(e, draggedElement, widgetClass); onDragEnd()}}
|
||||
// onDragStart={(e) => this.handleDragStart(e, onDragStart)}
|
||||
// onDragEnd={(e) => this.handleDragEnd(onDragEnd)}
|
||||
// style={outerStyle}
|
||||
|
||||
onDragEnter={(e) => this.handleDragEnter(e, draggedElement, setOverElement)}
|
||||
onDragLeave={(e) => this.handleDragLeave(e, draggedElement, overElement)}
|
||||
|
||||
onDragStart={(e) => this.handleDragStart(e, onDragStart)}
|
||||
onDragEnd={(e) => this.handleDragEnd(onDragEnd)}
|
||||
>
|
||||
{/* FIXME: Swappable when the parent layout is flex/grid and gap is more, this trick won't work, add bg color to check */}
|
||||
{/* FIXME: Swappable, when the parent layout is gap is 0, it doesn't work well */}
|
||||
<div className="tw-relative tw-w-full tw-h-full tw-top-0 tw-left-0"
|
||||
|
||||
>
|
||||
|
||||
<div className={`tw-absolute tw-top-[-5px] tw-left-[-5px]
|
||||
tw-border-1 tw-opacity-0 tw-border-solid tw-border-black
|
||||
tw-w-full tw-h-full tw-bg-red-400
|
||||
tw-scale-[1.1] tw-opacity-1 tw-z-[-1] `}
|
||||
style={{
|
||||
width: "calc(100% + 10px)",
|
||||
height: "calc(100% + 10px)",
|
||||
}}
|
||||
ref={this.swappableAreaRef}
|
||||
// swapable area
|
||||
>
|
||||
{/* helps with swappable: if the mouse is in this area while hovering/dropping, then swap */}
|
||||
</div>
|
||||
|
||||
<div className="tw-relative tw-top-0 tw-left-0 tw-w-full tw-h-full" ref={this.innerAreaRef}
|
||||
>
|
||||
{this.renderContent()}
|
||||
</div>
|
||||
{
|
||||
// show drop style on drag hover
|
||||
draggedElement && 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
|
||||
<div data-widget-id={this.__id}
|
||||
ref={this.elementRef}
|
||||
className="tw-shadow-xl tw-w-fit tw-h-fit"
|
||||
// data-draggable-type={this.getWidgetType()} // helps with droppable
|
||||
// data-container={this.state.widgetContainer} // indicates how the canvas should handle dragging, one is sidebar other is canvas
|
||||
|
||||
`}
|
||||
// data-drag-start-within // this attribute indicates that the drag is occurring from within the project and not a outside file drop
|
||||
|
||||
// draggable={this.state.dragEnabled}
|
||||
|
||||
// onDragOver={(e) => this.handleDragOver(e, draggedElement)}
|
||||
// onDrop={(e) => {this.handleDropEvent(e, draggedElement, widgetClass); onDragEnd()}}
|
||||
|
||||
// onDragEnter={(e) => this.handleDragEnter(e, draggedElement, setOverElement)}
|
||||
// onDragLeave={(e) => this.handleDragLeave(e, draggedElement, overElement)}
|
||||
|
||||
// onDragStart={(e) => this.handleDragStart(e, onDragStart)}
|
||||
// onDragEnd={(e) => this.handleDragEnd(onDragEnd)}
|
||||
>
|
||||
{/* FIXME: Swappable when the parent layout is flex/grid and gap is more, this trick won't work, add bg color to check */}
|
||||
{/* FIXME: Swappable, when the parent layout is gap is 0, it doesn't work well */}
|
||||
<div className="tw-relative tw-w-full tw-h-full tw-top-0 tw-left-0"
|
||||
|
||||
>
|
||||
|
||||
<div className={`tw-absolute tw-top-[-5px] tw-left-[-5px]
|
||||
tw-border-1 tw-opacity-0 tw-border-solid tw-border-black
|
||||
tw-w-full tw-h-full tw-bg-red-400
|
||||
tw-scale-[1.1] tw-opacity-1 tw-z-[-1] `}
|
||||
style={{
|
||||
width: "calc(100% + 10px)",
|
||||
height: "calc(100% + 10px)",
|
||||
}}
|
||||
ref={this.swappableAreaRef}
|
||||
// swapable area
|
||||
>
|
||||
{/* helps with swappable: if the mouse is in this area while hovering/dropping, then swap */}
|
||||
</div>
|
||||
}
|
||||
{/* FIXME: the resize handles get clipped in parent container */}
|
||||
<div className={`tw-absolute tw-z-[-1] tw-bg-transparent tw-top-[-10px] tw-left-[-10px] tw-opacity-100
|
||||
tw-w-full tw-h-full
|
||||
${this.state.selected ? 'tw-border-2 tw-border-solid tw-border-blue-500' : 'tw-hidden'}`}
|
||||
style={{
|
||||
width: "calc(100% + 20px)",
|
||||
height: "calc(100% + 20px)",
|
||||
zIndex: -1,
|
||||
}}
|
||||
>
|
||||
|
||||
<div className={`"tw-relative tw-w-full tw-h-full"`}> {/* ${this.state.isDragging ? "tw-pointer-events-none" : "tw-pointer-events-auto"} */}
|
||||
<EditableDiv value={this.state.widgetName} onChange={this.setWidgetName}
|
||||
maxLength={40}
|
||||
openEdit={this.state.enableRename}
|
||||
className="tw-text-sm tw-w-fit tw-max-w-[160px] tw-text-clip tw-min-w-[150px]
|
||||
tw-overflow-hidden tw-absolute tw--top-6 tw-h-6"
|
||||
/>
|
||||
<div className="tw-relative tw-top-0 tw-left-0 tw-w-full tw-h-full" ref={this.innerAreaRef}
|
||||
>
|
||||
{this.renderContent()}
|
||||
</div>
|
||||
{
|
||||
// show drop style on drag hover
|
||||
draggedElement && 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
|
||||
|
||||
<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) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.props.onWidgetResizing("nw")
|
||||
this.setState({ dragEnabled: false })
|
||||
`}
|
||||
style={{
|
||||
width: "calc(100% + 10px)",
|
||||
height: "calc(100% + 10px)",
|
||||
}}
|
||||
onMouseUp={() => 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) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.props.onWidgetResizing("ne")
|
||||
this.setState({ dragEnabled: false })
|
||||
}}
|
||||
onMouseUp={() => 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) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.props.onWidgetResizing("sw")
|
||||
this.setState({ dragEnabled: false })
|
||||
}}
|
||||
onMouseUp={() => 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) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.props.onWidgetResizing("se")
|
||||
this.setState({ dragEnabled: false })
|
||||
}}
|
||||
onMouseUp={() => this.setState({ dragEnabled: true })}
|
||||
/>
|
||||
>
|
||||
</div>
|
||||
}
|
||||
{/* FIXME: the resize handles get clipped in parent container */}
|
||||
<div className={`tw-absolute tw-z-[-1] tw-bg-transparent tw-top-[-10px] tw-left-[-10px] tw-opacity-100
|
||||
tw-w-full tw-h-full
|
||||
${this.state.selected ? 'tw-border-2 tw-border-solid tw-border-blue-500' : 'tw-hidden'}`}
|
||||
style={{
|
||||
width: "calc(100% + 20px)",
|
||||
height: "calc(100% + 20px)",
|
||||
zIndex: -1,
|
||||
}}
|
||||
>
|
||||
|
||||
<div className={`"tw-relative tw-w-full tw-h-full"`}> {/* ${this.state.isDragging ? "tw-pointer-events-none" : "tw-pointer-events-auto"} */}
|
||||
<EditableDiv value={this.state.widgetName} onChange={this.setWidgetName}
|
||||
maxLength={40}
|
||||
openEdit={this.state.enableRename}
|
||||
className="tw-text-sm tw-w-fit tw-max-w-[160px] tw-text-clip tw-min-w-[150px]
|
||||
tw-overflow-hidden tw-absolute tw--top-6 tw-h-6"
|
||||
/>
|
||||
|
||||
<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) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.props.onWidgetResizing("nw")
|
||||
this.setState({ dragEnabled: false })
|
||||
}}
|
||||
onMouseUp={() => 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) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.props.onWidgetResizing("ne")
|
||||
this.setState({ dragEnabled: false })
|
||||
}}
|
||||
onMouseUp={() => 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) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.props.onWidgetResizing("sw")
|
||||
this.setState({ dragEnabled: false })
|
||||
}}
|
||||
onMouseUp={() => 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) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.props.onWidgetResizing("se")
|
||||
this.setState({ dragEnabled: false })
|
||||
}}
|
||||
onMouseUp={() => this.setState({ dragEnabled: true })}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
</WidgetDnd>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
236
src/canvas/widgets/widgetDnd.js
Normal file
236
src/canvas/widgets/widgetDnd.js
Normal file
@@ -0,0 +1,236 @@
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { useDragDropManager, useDroppable, useDraggable } from '@dnd-kit/react'
|
||||
import { useDragContext } from '../../components/draggable/draggableContext'
|
||||
|
||||
|
||||
// FIXME: fix the issue of self drop
|
||||
function WidgetDnd({droppableTags,
|
||||
...props}) {
|
||||
|
||||
const dndRef = useRef(null)
|
||||
|
||||
const {dragElementType} = props
|
||||
|
||||
const { draggedElement, setOverElement, widgetClass } = useDragContext()
|
||||
|
||||
const { ref: dropRef, isDropTarget, droppable} = useDroppable({
|
||||
id: props.id,
|
||||
// accept: (draggable) => {
|
||||
|
||||
// const allowDrop = (droppableTags && droppableTags !== null && (Object.keys(droppableTags).length === 0 ||
|
||||
// (droppableTags.include?.length > 0 && droppableTags.include?.includes(draggable.type)) ||
|
||||
// (droppableTags.exclude?.length > 0 && !droppableTags.exclude?.includes(draggable.type))
|
||||
// ))
|
||||
|
||||
// return allowDrop
|
||||
// }
|
||||
})
|
||||
|
||||
const { ref: dragRef, draggable } = useDraggable({
|
||||
id: dragElementType,
|
||||
feedback: "default",
|
||||
type: dragElementType,
|
||||
disabled: props.disabled,
|
||||
|
||||
// data: { title: props.children }
|
||||
})
|
||||
|
||||
|
||||
const manager = useDragDropManager()
|
||||
|
||||
// const {}
|
||||
const {onDragStart, onDragEnd, disableStyle=false} = useDragContext()
|
||||
|
||||
const [allowDrop, setAllowDrop] = useState({show: false, allow: false}) // indicator if the draggable can be dropped on the droppable
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
manager?.monitor?.addEventListener("dragstart", handleDragEnter)
|
||||
manager?.monitor?.addEventListener("dragend", handleDropEvent)
|
||||
manager?.monitor?.addEventListener("dragmove", handleDragOver)
|
||||
// manager?.monitor?.addEventListener("dragover", onDragEndhandleDragOver)
|
||||
|
||||
|
||||
return () => {
|
||||
manager?.monitor?.removeEventListener("dragstart", handleDragEnter)
|
||||
manager?.monitor?.removeEventListener("dragend", handleDropEvent)
|
||||
manager?.monitor?.removeEventListener("dragmove", handleDragOver)
|
||||
}
|
||||
}, [manager, draggedElement])
|
||||
|
||||
|
||||
const handleRef = (node) => {
|
||||
dndRef.current = node
|
||||
dropRef(node)
|
||||
dragRef(node)
|
||||
}
|
||||
|
||||
const handleDragEnter = (e) => {
|
||||
|
||||
const {target, source} = e.operation
|
||||
|
||||
console.log("is drag source: ", props.id, draggable.isDragSource)
|
||||
|
||||
|
||||
if (draggable.isDragSource){
|
||||
onDragStart(dndRef?.current, widgetClass)
|
||||
|
||||
}
|
||||
|
||||
if (target && target?.id !== props?.id){
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if (!draggedElement || !draggedElement.getAttribute("data-drag-start-within")) {
|
||||
// if the drag is starting from outside (eg: file drop) or if drag doesn't exist
|
||||
return
|
||||
}
|
||||
|
||||
const dragElementType = draggedElement.getAttribute("data-draggable-type")
|
||||
|
||||
setOverElement(document.getElementById(source.id))
|
||||
|
||||
const dropAllowed = (droppableTags && droppableTags !== null && (Object.keys(droppableTags).length === 0 ||
|
||||
(droppableTags.include?.length > 0 && droppableTags.include?.includes(dragElementType)) ||
|
||||
(droppableTags.exclude?.length > 0 && !droppableTags.exclude?.includes(dragElementType))
|
||||
))
|
||||
|
||||
console.log("droppable tags: ", dropAllowed)
|
||||
|
||||
|
||||
setAllowDrop({allow: dropAllowed, show: true})
|
||||
|
||||
}
|
||||
|
||||
const handleDragOver = (e) => {
|
||||
|
||||
const {target} = e.operation
|
||||
|
||||
if (target && target?.id !== props?.id){
|
||||
return
|
||||
}
|
||||
// console.log("Over sir1: ", draggedElement)
|
||||
|
||||
|
||||
if (!draggedElement || !draggedElement.getAttribute("data-drag-start-within")) {
|
||||
// if the drag is starting from outside (eg: file drop) or if drag doesn't exist
|
||||
return
|
||||
}
|
||||
|
||||
// console.log("Drag over: ", e.dataTransfer.getData("text/plain"), e.dataTransfer)
|
||||
const dragElementType = draggedElement.getAttribute("data-draggable-type")
|
||||
|
||||
const dropAllowed = (droppableTags && droppableTags !== null && (Object.keys(droppableTags).length === 0 ||
|
||||
(droppableTags.include?.length > 0 && droppableTags.include?.includes(dragElementType)) ||
|
||||
(droppableTags.exclude?.length > 0 && !droppableTags.exclude?.includes(dragElementType))
|
||||
))
|
||||
|
||||
|
||||
setAllowDrop({allow: dropAllowed, show: true})
|
||||
|
||||
// if (allowDrop) {
|
||||
// e.preventDefault() // this is necessary to allow drop to take place
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
const handleDropEvent = (e) => {
|
||||
|
||||
const {target} = e.operation
|
||||
|
||||
if (target && target?.id !== props?.id){
|
||||
return
|
||||
}
|
||||
|
||||
setAllowDrop({allow: false, show: false})
|
||||
|
||||
|
||||
if (!draggedElement || !draggedElement.getAttribute("data-drag-start-within")) {
|
||||
// if the drag is starting from outside (eg: file drop) or if drag doesn't exist
|
||||
return
|
||||
}
|
||||
|
||||
// e.stopPropagation()
|
||||
|
||||
const dragElementType = draggedElement.getAttribute("data-draggable-type")
|
||||
|
||||
|
||||
const dropAllowed = (droppableTags && droppableTags !== null && (Object.keys(droppableTags).length === 0 ||
|
||||
(droppableTags.include?.length > 0 && droppableTags.include?.includes(dragElementType)) ||
|
||||
(droppableTags.exclude?.length > 0 && !droppableTags.exclude?.includes(dragElementType))
|
||||
))
|
||||
|
||||
// if (onDrop && dropAllowed) {
|
||||
// onDrop(e, draggedElement, widgetClass)
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
// const handleDragLeave = (e) => {
|
||||
|
||||
// const {target} = e.operation
|
||||
|
||||
// if (target && target.id === props.id){
|
||||
// handleDropEvent(e)
|
||||
// }else{
|
||||
// setAllowDrop({allow: false, show: false})
|
||||
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// const handleDragStart = (event) => {
|
||||
|
||||
// const {source} = event.operation
|
||||
|
||||
// if (!source || (source && source.id !== props.dragElementType)){
|
||||
// return
|
||||
// } if (!source || (source && source.id !== props.dragElementType)){
|
||||
// return
|
||||
// }
|
||||
// // event.dataTransfer.setData("text/plain", "")
|
||||
// // onDragStart(draggableRef?.current, dragWidgetClass)
|
||||
// onDragStart(draggableRef?.current, dragWidgetClass, elementMetaData)
|
||||
|
||||
// }
|
||||
|
||||
// const handleDragEnd = (event) => {
|
||||
// // console.log("Drag end: ", e, e.target.closest('div'))
|
||||
// const {source} = event.operation
|
||||
|
||||
// if (!source || (source && source.id !== props.dragElementType)){
|
||||
// return
|
||||
// }
|
||||
|
||||
// // onDragEnd()
|
||||
// }
|
||||
|
||||
return (
|
||||
<div ref={handleRef} data-drag-start-within
|
||||
draggable
|
||||
data-draggable-type={dragElementType}
|
||||
className={`${props.className} tw-relative` || ''} {...props} style={{zIndex: 10}}>
|
||||
{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-pointer-events-none
|
||||
`}>
|
||||
</div>
|
||||
} */}
|
||||
|
||||
{
|
||||
droppable.isDropTarget &&
|
||||
<div className={`${allowDrop.allow ? "tw-bg-[#82ff1c6e]" : "tw-bg-[#eb5d366e]"}
|
||||
tw-absolute tw-top-0 tw-left-0 tw-w-full tw-h-full tw-z-[3]
|
||||
tw-border-2 tw-border-dashed tw-rounded-lg tw-pointer-events-none
|
||||
`}>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default WidgetDnd
|
||||
@@ -34,6 +34,7 @@ export function SidebarWidgetCard({ name, img, url, license, widgetClass, innerR
|
||||
data-container={"sidebar"}
|
||||
dragElementType={widgetClass.widgetType}
|
||||
dragWidgetClass={widgetClass}
|
||||
draggableType={"clone"}
|
||||
elementMetaData={{
|
||||
name,
|
||||
url,
|
||||
|
||||
@@ -10,7 +10,7 @@ function Draggable(props) {
|
||||
|
||||
const { ref } = useDraggable({
|
||||
id: props.dragElementType,
|
||||
feedback: "clone",
|
||||
feedback: props.draggableType || "default",
|
||||
type: props.dragElementType
|
||||
// data: { title: props.children }
|
||||
})
|
||||
|
||||
47
src/utils/dndkit/plugins.js
Normal file
47
src/utils/dndkit/plugins.js
Normal file
@@ -0,0 +1,47 @@
|
||||
class ZIndexPlugin {
|
||||
constructor(manager, options) {
|
||||
this.manager = manager;
|
||||
this.options = options || {};
|
||||
this.originalZIndexValues = new Map();
|
||||
}
|
||||
|
||||
registerEffect() {
|
||||
const handleDragStart = (event) => {
|
||||
const { active } = event;
|
||||
const draggableElement = document.getElementById(active.id);
|
||||
|
||||
if (draggableElement) {
|
||||
// Store the original z-index
|
||||
this.originalZIndexValues.set(active.id, draggableElement.style.zIndex);
|
||||
|
||||
// Apply the dragged z-index
|
||||
draggableElement.style.zIndex = this.options.draggedZIndex || '9999';
|
||||
}
|
||||
};
|
||||
|
||||
const handleDragEnd = (event) => {
|
||||
const { active } = event;
|
||||
const draggableElement = document.getElementById(active.id);
|
||||
|
||||
if (draggableElement) {
|
||||
// Restore the original z-index
|
||||
const originalZIndex = this.originalZIndexValues.get(active.id) || '';
|
||||
draggableElement.style.zIndex = originalZIndex;
|
||||
this.originalZIndexValues.delete(active.id);
|
||||
}
|
||||
};
|
||||
|
||||
// Listen for drag events
|
||||
this.manager.addEventListener('dragstart', handleDragStart);
|
||||
this.manager.addEventListener('dragend', handleDragEnd);
|
||||
|
||||
// Return cleanup function
|
||||
return () => {
|
||||
this.manager.removeEventListener('dragstart', handleDragStart);
|
||||
this.manager.removeEventListener('dragend', handleDragEnd);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default ZIndexPlugin;
|
||||
|
||||
Reference in New Issue
Block a user