bud fixes for dnd

This commit is contained in:
paul
2025-03-04 11:45:26 +05:30
parent 03a4984cbc
commit 1ee137085e
6 changed files with 134 additions and 148 deletions

View File

@@ -673,9 +673,7 @@ class Canvas extends React.Component {
this.setState({ isWidgetDragging: false })
console.log("Drop outside1")
if (!draggedElement || !draggedElement.getAttribute("data-drag-start-within")) {
console.log("Drop outside")
// if the drag is starting from outside (eg: file drop) or if drag doesn't exist
return
@@ -710,12 +708,6 @@ class Canvas extends React.Component {
// y: (e.activatorEvent.pageY - canvasRect.top) / (this.state.zoom),
// }
// FIXME: error in canvasRect.top
// console.log("final position: ", finalPosition, draggedElementInitialX, clientX, canvasRect, "Top: ",
// canvasRect.top, clientY, draggedElementInitialY)
if (container === WidgetContainer.SIDEBAR) {
if (!widgetClass) {

View File

@@ -1105,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,
@@ -1128,10 +1128,11 @@ class Widget extends React.Component {
return (
<WidgetDnd id={this.__id}
<WidgetDnd widgetId={this.__id}
disabled={false && this.state.dragEnabled}
data-draggable-type={this.getWidgetType()} // helps with droppable
dragElementType={this.getWidgetType()}
droppableTags={this.droppableTags}
// onDragOver={(e) => this.handleDragOver(e, draggedElement)}
// onDrop={(e) => {this.handleDropEvent(e, draggedElement, widgetClass); onDragEnd()}}
@@ -1140,7 +1141,7 @@ class Widget extends React.Component {
// onDragStart={(e) => this.handleDragStart(e, onDragStart)}
// onDragEnd={(e) => this.handleDragEnd(onDragEnd)}
// style={outerStyle}
style={outerStyle}
>
<div data-widget-id={this.__id}

View File

@@ -3,8 +3,7 @@ import { useDragDropManager, useDroppable, useDraggable } from '@dnd-kit/react'
import { useDragContext } from '../../components/draggable/draggableContext'
// FIXME: fix the issue of self drop
function WidgetDnd({droppableTags,
function WidgetDnd({widgetId, droppableTags, onDrop,
...props}) {
const dndRef = useRef(null)
@@ -14,7 +13,7 @@ function WidgetDnd({droppableTags,
const { draggedElement, setOverElement, widgetClass } = useDragContext()
const { ref: dropRef, isDropTarget, droppable} = useDroppable({
id: props.id,
id: widgetId,
// accept: (draggable) => {
// const allowDrop = (droppableTags && droppableTags !== null && (Object.keys(droppableTags).length === 0 ||
@@ -27,7 +26,7 @@ function WidgetDnd({droppableTags,
})
const { ref: dragRef, draggable } = useDraggable({
id: dragElementType,
id: widgetId,
feedback: "default",
type: dragElementType,
disabled: props.disabled,
@@ -68,66 +67,75 @@ function WidgetDnd({droppableTags,
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 the current widget is being dragged
onDragStart(dndRef?.current, widgetClass)
}
dndRef.current.style.zIndex = 10
if (target && target?.id !== props?.id){
return
}else if (droppable.isDropTarget){
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
}
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(dndRef.current)
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 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 (draggable.isDragSource){
// onDragStart(dndRef?.current, widgetClass)
// // TODO
// dndRef.current.style.zIndex = 10
// }
if (target && target?.id !== props?.id){
return
if (droppable.isDropTarget){
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})
}
// 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
@@ -139,31 +147,34 @@ function WidgetDnd({droppableTags,
const {target} = e.operation
if (target && target?.id !== props?.id){
return
}
if (draggable.isDragSource){
onDragEnd()
setAllowDrop({allow: false, show: false})
}else if (droppable.isDropTarget){
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
}
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()
// e.stopPropagation()
const dragElementType = draggedElement.getAttribute("data-draggable-type")
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))
))
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)
// }
if (onDrop && dropAllowed && (droppable.isDropTarget && !draggable.isDragSource)) {
onDrop(e, draggedElement, widgetClass)
}
}
}
@@ -208,21 +219,16 @@ function WidgetDnd({droppableTags,
return (
<div ref={handleRef} data-drag-start-within
{...props}
draggable
data-draggable-type={dragElementType}
className={`${props.className} tw-relative` || ''} {...props} style={{zIndex: 10}}>
className={`${props.className} tw-relative tw-h-fit tw-w-fit tw-outline-none`}
>
{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 &&
(droppable.isDropTarget && !draggable.isDragSource) &&
<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

View File

@@ -43,49 +43,44 @@ export function SidebarWidgetCard({ name, img, url, license, widgetClass, innerR
widgetClass,
}}
>
{/* <DraggableWrapper data-container={"sidebar"}
dragElementType={widgetClass.widgetType}
dragWidgetClass={widgetClass}
className="tw-cursor-pointer tw-w-fit tw-bg-white tw-h-fit"> */}
<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-blue-500 tw-shadow-md">
<div className="tw-h-[200px] tw-pointer-events-none tw-w-full tw-overflow-hidden">
<img src={img} alt={name} className="tw-object-contain tw-h-full tw-w-full tw-select-none" />
</div>
<span className="tw-text-center tw-text-black tw-text-lg">{name}</span>
<div className="tw-flex tw-text-lg tw-place tw-px-4">
<a href={url} className="tw-text-gray-600" target="_blank" rel="noopener noreferrer">
{urlIcon}
</a>
{license?.name &&
<div className="tw-ml-auto tw-text-sm">
{
license.url ?
<a href={license.url} target="_blank" rel="noreferrer noopener"
className="tw-p-[1px] tw-px-2 tw-text-blue-500 tw-border-[1px]
tw-border-solid tw-rounded-sm tw-border-blue-500
tw-shadow-md tw-text-center tw-no-underline">
{license.name}
</a>
:
<div className="tw-p-[1px] tw-px-2 tw-text-blue-500 tw-border-[1px]
tw-border-solid tw-rounded-sm tw-border-blue-500
tw-shadow-md tw-text-center">
{license.name}
</div>
}
</div>
}
</div>
<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-blue-500 tw-shadow-md">
<div className="tw-h-[200px] tw-pointer-events-none tw-w-full tw-overflow-hidden">
<img src={img} alt={name} className="tw-object-contain tw-h-full tw-w-full tw-select-none" />
</div>
{/* </DraggableWrapper> */}
<span className="tw-text-center tw-text-black tw-text-lg">{name}</span>
<div className="tw-flex tw-text-lg tw-place tw-px-4">
<a href={url} className="tw-text-gray-600" target="_blank" rel="noopener noreferrer">
{urlIcon}
</a>
{license?.name &&
<div className="tw-ml-auto tw-text-sm">
{
license.url ?
<a href={license.url} target="_blank" rel="noreferrer noopener"
className="tw-p-[1px] tw-px-2 tw-text-blue-500 tw-border-[1px]
tw-border-solid tw-rounded-sm tw-border-blue-500
tw-shadow-md tw-text-center tw-no-underline">
{license.name}
</a>
:
<div className="tw-p-[1px] tw-px-2 tw-text-blue-500 tw-border-[1px]
tw-border-solid tw-rounded-sm tw-border-blue-500
tw-shadow-md tw-text-center">
{license.name}
</div>
}
</div>
}
</div>
</div>
</Draggable>
)

View File

@@ -4,14 +4,14 @@ import { CSS } from "@dnd-kit/utilities"
import { useDragContext } from "../draggableContext"
function Draggable(props) {
function Draggable({dragElementType, dragWidgetClass = null, elementMetaData, ...props}) {
const draggableRef = useRef(null);
const { ref } = useDraggable({
id: props.dragElementType,
const { ref, draggable } = useDraggable({
id: dragElementType,
feedback: props.draggableType || "default",
type: props.dragElementType
type: dragElementType
// data: { title: props.children }
})
@@ -33,7 +33,6 @@ function Draggable(props) {
}, [manager])
const { dragElementType, dragWidgetClass = null, elementMetaData } = props
// const style = transform ? {
// transform: CSS.Translate.toString(transform),
// } : undefined
@@ -48,11 +47,10 @@ function Draggable(props) {
const {source} = event.operation
if (!source || (source && source.id !== props.dragElementType)){
return
} if (!source || (source && source.id !== props.dragElementType)){
if (!draggable.isDragSource){
return
}
// event.dataTransfer.setData("text/plain", "")
// onDragStart(draggableRef?.current, dragWidgetClass)
onDragStart(draggableRef?.current, dragWidgetClass, elementMetaData)
@@ -63,7 +61,7 @@ function Draggable(props) {
// console.log("Drag end: ", e, e.target.closest('div'))
const {source} = event.operation
if (!source || (source && source.id !== props.dragElementType)){
if (!draggable.isDragSource){
return
}
@@ -74,13 +72,12 @@ function Draggable(props) {
// TODO: remove element meta data from props
return (
<div
{...props}
ref={handleRef}
className={`${props.className}`}
// style={!disableStyle ? style : null} //enable this to show like the original item is moving, if commented out the original item will not have css effects
draggable
data-drag-start-within // this attribute indicates that the drag is occurring from within the project and not a outside file drop
data-draggable-type={dragElementType}
{...props}
>
{props.children}

View File

@@ -23,9 +23,8 @@ function Droppable(props) {
}
})
const manager = useDragDropManager()
const manager = useDragDropManager()
// const {}
const [allowDrop, setAllowDrop] = useState({show: false, allow: false}) // indicator if the draggable can be dropped on the droppable
@@ -41,7 +40,7 @@ function Droppable(props) {
manager?.monitor?.removeEventListener("dragend", handleDragLeave)
manager?.monitor?.removeEventListener("dragmove", handleDragOver)
}
}, [manager, draggedElement])
}, [manager, draggedElement, widgetClass])
const handleRef = (node) => {
@@ -138,6 +137,8 @@ function Droppable(props) {
(droppableTags.exclude?.length > 0 && !droppableTags.exclude?.includes(dragElementType))
))
console.log("Widget class1: ", widgetClass, draggedElement)
if (onDrop && dropAllowed) {
onDrop(e, draggedElement, widgetClass)
}
@@ -159,24 +160,18 @@ function Droppable(props) {
return (
<div ref={handleRef} className={props.className || ''}>
{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>
} */}
{
allowDrop.show &&
<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-[999]
tw-absolute tw-top-0 tw-left-0 tw-w-full tw-h-full tw-z-[0]
tw-border-2 tw-border-dashed tw-rounded-lg tw-pointer-events-none
`}>
</div>
}
</div>
)
}