working on dnd aaaaa..... screammmmm
This commit is contained in:
@@ -665,9 +665,9 @@ class Canvas extends React.Component {
|
||||
* Handles drop event to canvas from the sidebar and on canvas widget movement
|
||||
* @param {DragEvent} e
|
||||
*/
|
||||
handleDropEvent = (e, draggedElement, widgetClass = null) => {
|
||||
handleDropEvent = (e, draggedElement, widgetClass = null, initialPos={x: 0, y: 0}) => {
|
||||
|
||||
console.log("event: ", e, draggedElement, widgetClass)
|
||||
console.log("event: ", e, draggedElement, widgetClass, initialPos)
|
||||
|
||||
// e.preventDefault()
|
||||
|
||||
@@ -689,24 +689,21 @@ class Canvas extends React.Component {
|
||||
// const {x: draggedElementInitialX, y: draggedElementInitialY} = draggedElement.getBoundingClientRect()
|
||||
|
||||
const { clientX, clientY } = e.nativeEvent
|
||||
|
||||
const { initial } = e.operation.shape
|
||||
console.log("event: ", e)
|
||||
// const { x: clientX, y: clientY} = e.delta;
|
||||
// const {clientX: draggedElementInitialX, clientY: draggedElementInitialY} = e.activatorEvent
|
||||
|
||||
// console.log("wirking: ", clientX, clientY, e, draggedElementInitialX, draggedElementInitialY)
|
||||
|
||||
|
||||
// TODO: + initial cursor position - final cursor position
|
||||
let finalPosition = {
|
||||
x: (clientX - canvasRect.left) / this.state.zoom,
|
||||
y: (clientY - canvasRect.top) / this.state.zoom,
|
||||
x: ((clientX - canvasRect.left) / this.state.zoom) - (initial.left) / this.state.zoom,
|
||||
y: ((clientY - canvasRect.top) / this.state.zoom) - (initial.top) / this.state.zoom,
|
||||
}
|
||||
// let finalPosition = {
|
||||
// x: ((draggedElementInitialX + clientX) - canvasRect.left) / (this.state.zoom),
|
||||
// y: ((draggedElementInitialY + clientY) - canvasRect.top) / (this.state.zoom),
|
||||
// }
|
||||
// let finalPosition = {
|
||||
// x: (e.activatorEvent.pageX - canvasRect.left) / (this.state.zoom),
|
||||
// y: (e.activatorEvent.pageY - canvasRect.top) / (this.state.zoom),
|
||||
// }
|
||||
|
||||
console.log("container: ", container)
|
||||
|
||||
if (container === WidgetContainer.SIDEBAR) {
|
||||
|
||||
@@ -719,26 +716,29 @@ class Canvas extends React.Component {
|
||||
this.createWidget(widgetClass, ({ id, widgetRef }) => {
|
||||
widgetRef.current.setPos(finalPosition.x, finalPosition.y)
|
||||
// widgetRef.current.setPos(10, 10)
|
||||
console.log("hell ya ", widgetRef.current.setPos, finalPosition)
|
||||
|
||||
})
|
||||
|
||||
} else if ([WidgetContainer.CANVAS, WidgetContainer.WIDGET].includes(container)) {
|
||||
|
||||
// snaps to center
|
||||
finalPosition = {
|
||||
x: (clientX - canvasRect.left) / this.state.zoom - (elementWidth / 2) / this.state.zoom,
|
||||
y: (clientY - canvasRect.top) / this.state.zoom - (elementHeight / 2) / this.state.zoom,
|
||||
}
|
||||
// finalPosition = {
|
||||
// x: (clientX - canvasRect.left) / this.state.zoom - (elementWidth / 2) / this.state.zoom,
|
||||
// y: (clientY - canvasRect.top) / this.state.zoom - (elementHeight / 2) / this.state.zoom,
|
||||
// }
|
||||
|
||||
let widgetId = draggedElement.getAttribute("data-widget-id")
|
||||
|
||||
const widgetObj = this.getWidgetById(widgetId)
|
||||
|
||||
console.log("current pos: ", finalPosition, widgetId, widgetObj)
|
||||
|
||||
// console.log("WidgetObj: ", widgetObj)
|
||||
if (container === WidgetContainer.CANVAS) {
|
||||
|
||||
widgetObj.current.setPos(finalPosition.x, finalPosition.y)
|
||||
|
||||
console.log("current pos: ", finalPosition)
|
||||
|
||||
} else if (container === WidgetContainer.WIDGET) {
|
||||
|
||||
// if the widget was inside another widget move it outside
|
||||
|
||||
@@ -68,8 +68,8 @@ class Widget extends React.Component {
|
||||
}
|
||||
|
||||
// This indicates if the draggable can be dropped on this widget, set this to null to disable drops
|
||||
this.droppableTags = {}
|
||||
|
||||
this.droppableTags = {}
|
||||
|
||||
|
||||
this.state = {
|
||||
zIndex: 0,
|
||||
@@ -91,7 +91,7 @@ class Widget extends React.Component {
|
||||
|
||||
pos: { x: 0, y: 0 },
|
||||
size: { width: 100, height: 100 },
|
||||
fitContent: {width: false, height: false},
|
||||
fitContent: { width: false, height: false },
|
||||
positionType: PosType.ABSOLUTE,
|
||||
|
||||
widgetOuterStyling: {
|
||||
@@ -117,7 +117,7 @@ class Widget extends React.Component {
|
||||
this.setAttrValue("styling.backgroundColor", value)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
label: "Styling"
|
||||
},
|
||||
layout: {
|
||||
@@ -181,7 +181,7 @@ class Widget extends React.Component {
|
||||
this.setPos = this.setPos.bind(this)
|
||||
this.setAttrValue = this.setAttrValue.bind(this)
|
||||
this.setWidgetName = this.setWidgetName.bind(this)
|
||||
|
||||
|
||||
this.setWidgetInnerStyle = this.setWidgetInnerStyle.bind(this)
|
||||
this.setWidgetOuterStyle = this.setWidgetOuterStyle.bind(this)
|
||||
|
||||
@@ -201,11 +201,11 @@ class Widget extends React.Component {
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
if (this.state.attrs.layout){
|
||||
if (this.state.attrs.layout) {
|
||||
this.setLayout(this.state.attrs.layout.value)
|
||||
// console.log("prior layout: ", this.state.attrs.layout.value)
|
||||
}
|
||||
|
||||
|
||||
if (this.state.attrs.styling.backgroundColor)
|
||||
this.setWidgetInnerStyle('backgroundColor', this.state.attrs.styling?.backgroundColor.value || "#fff")
|
||||
|
||||
@@ -276,9 +276,9 @@ class Widget extends React.Component {
|
||||
label: "Fit width",
|
||||
tool: Tools.CHECK_BUTTON,
|
||||
value: this.state.fitContent.width,
|
||||
onChange: (value) => {
|
||||
onChange: (value) => {
|
||||
this.updateState((prev) => ({
|
||||
fitContent: {...prev.fitContent, width: value}
|
||||
fitContent: { ...prev.fitContent, width: value }
|
||||
}))
|
||||
}
|
||||
},
|
||||
@@ -286,9 +286,9 @@ class Widget extends React.Component {
|
||||
label: "Fit height",
|
||||
tool: Tools.CHECK_BUTTON,
|
||||
value: this.state.fitContent.height,
|
||||
onChange: (value) => {
|
||||
onChange: (value) => {
|
||||
this.updateState((prev) => ({
|
||||
fitContent: {...prev.fitContent, height: value}
|
||||
fitContent: { ...prev.fitContent, height: value }
|
||||
}))
|
||||
}
|
||||
},
|
||||
@@ -316,15 +316,15 @@ class Widget extends React.Component {
|
||||
return this.constructor.widgetType
|
||||
}
|
||||
|
||||
getRequirements(){
|
||||
getRequirements() {
|
||||
return this.constructor.requirements
|
||||
}
|
||||
|
||||
getImports(){
|
||||
getImports() {
|
||||
return this.constructor.requiredImports
|
||||
}
|
||||
|
||||
generateCode(){
|
||||
generateCode() {
|
||||
throw new NotImplementedError("generateCode() must be implemented by the subclass")
|
||||
}
|
||||
|
||||
@@ -406,11 +406,11 @@ class Widget extends React.Component {
|
||||
return this.elementRef.current
|
||||
}
|
||||
|
||||
hideDroppableIndicator(){
|
||||
hideDroppableIndicator() {
|
||||
console.log("hide drop indicator")
|
||||
this.setState({
|
||||
showDroppableStyle: {
|
||||
allow: false,
|
||||
allow: false,
|
||||
show: false
|
||||
}
|
||||
}, () => {
|
||||
@@ -423,7 +423,7 @@ class Widget extends React.Component {
|
||||
* @param {string} path - eg: styling.backgroundColor
|
||||
* @returns
|
||||
*/
|
||||
removeAttr = (path) =>{
|
||||
removeAttr = (path) => {
|
||||
|
||||
const newAttrs = removeKeyFromObject(path, this.state.attrs)
|
||||
|
||||
@@ -444,16 +444,16 @@ class Widget extends React.Component {
|
||||
const keys = path.split('.')
|
||||
const lastKey = keys.pop()
|
||||
|
||||
|
||||
|
||||
// Traverse the state and update the nested value immutably
|
||||
let newAttrs = { ...this.state.attrs }
|
||||
let nestedObject = newAttrs
|
||||
|
||||
|
||||
keys.forEach(key => {
|
||||
nestedObject[key] = { ...nestedObject[key] } // Ensure immutability
|
||||
nestedObject = nestedObject[key]
|
||||
})
|
||||
|
||||
|
||||
nestedObject[lastKey].value = value
|
||||
|
||||
this.updateState({ attrs: newAttrs })
|
||||
@@ -486,7 +486,7 @@ class Widget extends React.Component {
|
||||
* this is a helper function to remove any non-serializable data associated with attrs
|
||||
* eg: {"styling.backgroundColor": "#ffff", "layout": {layout: "flex", direction: "", grid: }}
|
||||
*/
|
||||
serializeAttrsValues(){
|
||||
serializeAttrsValues() {
|
||||
|
||||
const serializeValues = (obj, currentPath = "") => {
|
||||
const result = {}
|
||||
@@ -534,28 +534,28 @@ class Widget extends React.Component {
|
||||
* inform the child about the parent layout changes
|
||||
* @param {Layouts} parentLayout
|
||||
*/
|
||||
setParentLayout(parentLayout){
|
||||
setParentLayout(parentLayout) {
|
||||
|
||||
if (!parentLayout){
|
||||
if (!parentLayout) {
|
||||
// if parent layout is null (i,e the widget is on the canvas)
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
const {layout, direction, gap} = parentLayout
|
||||
const { layout, direction, gap } = parentLayout
|
||||
|
||||
|
||||
let updates = {
|
||||
parentLayout: parentLayout,
|
||||
}
|
||||
|
||||
if (layout === Layouts.FLEX || layout === Layouts.GRID){
|
||||
if (layout === Layouts.FLEX || layout === Layouts.GRID) {
|
||||
|
||||
updates = {
|
||||
...updates,
|
||||
positionType: PosType.NONE
|
||||
}
|
||||
|
||||
}else if (layout === Layouts.PLACE){
|
||||
} else if (layout === Layouts.PLACE) {
|
||||
updates = {
|
||||
...updates,
|
||||
positionType: PosType.ABSOLUTE
|
||||
@@ -565,11 +565,11 @@ class Widget extends React.Component {
|
||||
this.setState(updates)
|
||||
}
|
||||
|
||||
getParentLayout(){
|
||||
getParentLayout() {
|
||||
return this.state.parentLayout
|
||||
}
|
||||
|
||||
getLayout(){
|
||||
getLayout() {
|
||||
|
||||
return this.state?.attrs?.layout?.value || Layouts.FLEX
|
||||
}
|
||||
@@ -586,18 +586,18 @@ class Widget extends React.Component {
|
||||
gap: `${gap}px`,
|
||||
flexWrap: "wrap",
|
||||
gridTemplateColumns: "repeat(auto-fill, minmax(100px, 1fr))",
|
||||
gridTemplateRows: "repeat(auto-fill, minmax(100px, 1fr))",
|
||||
gridTemplateRows: "repeat(auto-fill, minmax(100px, 1fr))",
|
||||
// gridAutoRows: 'minmax(100px, auto)', // Rows with minimum height of 100px, and grow to fit content
|
||||
// gridAutoCols: 'minmax(100px, auto)', // Cols with minimum height of 100px, and grow to fit content
|
||||
}
|
||||
|
||||
if (align === "start"){
|
||||
if (align === "start") {
|
||||
widgetStyle["alignItems"] = "flex-start"
|
||||
}else if (align === "center"){
|
||||
} else if (align === "center") {
|
||||
widgetStyle["alignItems"] = "center"
|
||||
}else if (align === "end"){
|
||||
} else if (align === "end") {
|
||||
widgetStyle["alignItems"] = "flex-end"
|
||||
}else{
|
||||
} else {
|
||||
widgetStyle["alignItems"] = "unset"
|
||||
}
|
||||
|
||||
@@ -606,7 +606,7 @@ class Widget extends React.Component {
|
||||
})
|
||||
|
||||
this.setAttrValue("layout", value)
|
||||
this.props.onLayoutUpdate({parentId: this.__id, parentLayout: value})// inform children about the layout update
|
||||
this.props.onLayoutUpdate({ parentId: this.__id, parentLayout: value })// inform children about the layout update
|
||||
|
||||
}
|
||||
|
||||
@@ -623,7 +623,7 @@ class Widget extends React.Component {
|
||||
* @param {string} key - The string in react Style format
|
||||
* @param {string} value - Value of the style
|
||||
*/
|
||||
setWidgetOuterStyle(key, value){
|
||||
setWidgetOuterStyle(key, value) {
|
||||
const widgetStyle = {
|
||||
...this.state.widgetOuterStyling,
|
||||
[key]: value
|
||||
@@ -641,7 +641,7 @@ class Widget extends React.Component {
|
||||
* @param {string} value - Value of the style
|
||||
*/
|
||||
setWidgetInnerStyle(key, value) {
|
||||
|
||||
|
||||
const widgetStyle = {
|
||||
...this.state.widgetInnerStyling,
|
||||
[key]: value
|
||||
@@ -663,7 +663,7 @@ class Widget extends React.Component {
|
||||
const fitWidth = this.state.fitContent?.width
|
||||
const fitHeight = this.state.fitContent?.height
|
||||
|
||||
if (fitWidth && fitHeight){
|
||||
if (fitWidth && fitHeight) {
|
||||
message.warning("both width and height are set to fit-content, unset it to start resizing")
|
||||
return
|
||||
}
|
||||
@@ -715,7 +715,7 @@ class Widget extends React.Component {
|
||||
*
|
||||
* serialize data for saving
|
||||
*/
|
||||
serialize(){
|
||||
serialize() {
|
||||
// NOTE: when serializing make sure, you are only passing serializable objects not functions or other
|
||||
return ({
|
||||
zIndex: this.state.zIndex,
|
||||
@@ -737,27 +737,27 @@ class Widget extends React.Component {
|
||||
* @param {object} data
|
||||
* @param {() => void | undefined} callback - optional callback that will be called after load
|
||||
*/
|
||||
load(data, callback){
|
||||
load(data, callback) {
|
||||
|
||||
if (Object.keys(data).length === 0) return // no data to load
|
||||
|
||||
data = {...data} // create a shallow copy
|
||||
data = { ...data } // create a shallow copy
|
||||
|
||||
const {attrs, parentLayout, ...restData} = data
|
||||
const { attrs, parentLayout, ...restData } = data
|
||||
|
||||
|
||||
let layoutUpdates = {
|
||||
parentLayout: parentLayout.layout || null
|
||||
}
|
||||
|
||||
if (parentLayout?.layout === Layouts.FLEX || parentLayout?.layout === Layouts.GRID){
|
||||
if (parentLayout?.layout === Layouts.FLEX || parentLayout?.layout === Layouts.GRID) {
|
||||
|
||||
layoutUpdates = {
|
||||
...layoutUpdates,
|
||||
positionType: PosType.NONE
|
||||
}
|
||||
|
||||
}else if (parentLayout?.layout === Layouts.PLACE){
|
||||
} else if (parentLayout?.layout === Layouts.PLACE) {
|
||||
layoutUpdates = {
|
||||
...layoutUpdates,
|
||||
positionType: PosType.ABSOLUTE
|
||||
@@ -769,7 +769,7 @@ class Widget extends React.Component {
|
||||
...layoutUpdates
|
||||
}
|
||||
|
||||
this.setState(newData, () => {
|
||||
this.setState(newData, () => {
|
||||
// Updates attrs
|
||||
let newAttrs = { ...this.state.attrs }
|
||||
|
||||
@@ -791,75 +791,36 @@ class Widget extends React.Component {
|
||||
nestedObject[lastKey].value = value
|
||||
})
|
||||
|
||||
if (newAttrs?.styling?.backgroundColor){
|
||||
if (newAttrs?.styling?.backgroundColor) {
|
||||
// some widgets don't have background color
|
||||
this.setWidgetInnerStyle("backgroundColor", newAttrs.styling.backgroundColor)
|
||||
}
|
||||
|
||||
this.updateState({ attrs: newAttrs }, callback)
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
handleDragStart = (e, callback) => {
|
||||
e.stopPropagation()
|
||||
|
||||
callback(this.elementRef?.current || null)
|
||||
|
||||
// this.props.onWidgetDragStart(this.elementRef?.current)
|
||||
|
||||
// Create custom drag image with full opacity, this will ensure the image isn't taken from part of the canvas
|
||||
const dragImage = this.elementRef?.current.cloneNode(true)
|
||||
dragImage.style.opacity = '1' // Ensure full opacity
|
||||
dragImage.style.position = 'absolute'
|
||||
dragImage.style.top = '-9999px' // Move it out of view
|
||||
|
||||
document.body.appendChild(dragImage)
|
||||
const rect = this.elementRef?.current.getBoundingClientRect()
|
||||
// snap to mouse pos
|
||||
// const offsetX = e.clientX - rect.left
|
||||
// const offsetY = e.clientY - rect.top
|
||||
|
||||
// snap to middle
|
||||
const offsetX = rect.width / 2
|
||||
const offsetY = rect.height / 2
|
||||
|
||||
// Set the custom drag image with correct offset to avoid snapping to the top-left corner
|
||||
e.dataTransfer.setDragImage(dragImage, offsetX, offsetY)
|
||||
|
||||
|
||||
// Remove the custom drag image after some time to avoid leaving it in the DOM
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(dragImage)
|
||||
}, 0)
|
||||
|
||||
handleDragStart = (e, ) => {
|
||||
// NOTE: this line will prevent problem's such as self-drop or dropping inside its own children
|
||||
setTimeout(this.disablePointerEvents, 1)
|
||||
|
||||
this.setState({ isDragging: true })
|
||||
|
||||
}
|
||||
|
||||
handleDragEnter = (e, draggedElement, setOverElement) => {
|
||||
handleDragEnter = (e, draggedElement) => {
|
||||
|
||||
if (!draggedElement || !draggedElement.getAttribute("data-drag-start-within")){
|
||||
console.log("Drahg engerted")
|
||||
|
||||
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 dragEleType = draggedElement.getAttribute("data-draggable-type")
|
||||
|
||||
// console.log("Drag entering...", dragEleType, draggedElement, this.droppableTags)
|
||||
// FIXME: the outer widget shouldn't be swallowed by inner widget
|
||||
if (draggedElement === this.elementRef.current) {
|
||||
// prevent drop on itself, since the widget is invisible when dragging, if dropped on itself, it may consume itself
|
||||
return
|
||||
}
|
||||
|
||||
setOverElement(this.elementRef.current) // provide context to the provider
|
||||
|
||||
let showDrop = {
|
||||
allow: true,
|
||||
show: true
|
||||
@@ -891,7 +852,7 @@ class Widget extends React.Component {
|
||||
|
||||
handleDragOver = (e, draggedElement) => {
|
||||
|
||||
if (!draggedElement || !draggedElement.getAttribute("data-drag-start-within")){
|
||||
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
|
||||
}
|
||||
@@ -902,29 +863,19 @@ class Widget extends React.Component {
|
||||
}
|
||||
|
||||
// console.log("Drag over: ", e.dataTransfer.getData("text/plain"), e.dataTransfer)
|
||||
const dragEleType = draggedElement.getAttribute("data-draggable-type")
|
||||
|
||||
const allowDrop = (this.droppableTags && this.droppableTags !== null && (Object.keys(this.droppableTags).length === 0 ||
|
||||
(this.droppableTags.include?.length > 0 && this.droppableTags.include?.includes(dragEleType)) ||
|
||||
(this.droppableTags.exclude?.length > 0 && !this.droppableTags.exclude?.includes(dragEleType))
|
||||
))
|
||||
|
||||
if (allowDrop) {
|
||||
e.preventDefault() // NOTE: this is necessary to allow drop to take place
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handleDropEvent = (e, draggedElement, widgetClass = null) => {
|
||||
|
||||
if (!draggedElement || !draggedElement.getAttribute("data-drag-start-within")){
|
||||
console.log("Dropped: ", 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
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
|
||||
// FIXME: sometimes the elements showDroppableStyle is not gone, when dropping on the same widget
|
||||
this.setState({
|
||||
showDroppableStyle: {
|
||||
@@ -934,9 +885,9 @@ class Widget extends React.Component {
|
||||
})
|
||||
|
||||
|
||||
if (draggedElement === this.elementRef.current){
|
||||
if (draggedElement === this.elementRef.current) {
|
||||
// prevent drop on itself, since the widget is invisible when dragging, if dropped on itself, it may consume itself
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
let currentElement = e.currentTarget
|
||||
@@ -965,7 +916,7 @@ class Widget extends React.Component {
|
||||
|
||||
if (!allowDrop && !swapArea) {
|
||||
// only if both swap and drop is not allowed return, if swap is allowed continue
|
||||
return
|
||||
return
|
||||
}
|
||||
// TODO: check if the drop is allowed
|
||||
if ([WidgetContainer.CANVAS, WidgetContainer.WIDGET].includes(container)) {
|
||||
@@ -983,10 +934,10 @@ class Widget extends React.Component {
|
||||
// console.log("Dropped on Sidebar: ", this.__id)
|
||||
this.props.onCreateWidgetRequest(widgetClass, ({ id, widgetRef }) => {
|
||||
this.props.onAddChildWidget({
|
||||
event: e,
|
||||
parentWidgetId: this.__id,
|
||||
dragElementID: id
|
||||
}) // if dragged from the sidebar create the widget first
|
||||
event: e,
|
||||
parentWidgetId: this.__id,
|
||||
dragElementID: id
|
||||
}) // if dragged from the sidebar create the widget first
|
||||
})
|
||||
|
||||
}
|
||||
@@ -994,18 +945,15 @@ class Widget extends React.Component {
|
||||
}
|
||||
|
||||
|
||||
handleDragLeave = (e, draggedElement, overElement) => {
|
||||
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
handleDragLeave = (e) => {
|
||||
|
||||
const rect = this.getBoundingRect()
|
||||
|
||||
const {clientX, clientY} = e
|
||||
|
||||
|
||||
const { clientX, clientY } = e
|
||||
|
||||
const isInBoundingBox = (clientX >= rect.left && clientX <= rect.right &&
|
||||
clientY >= rect.top && clientY <= rect.bottom)
|
||||
|
||||
|
||||
// if (!e.currentTarget.contains(draggedElement)) {
|
||||
if (!isInBoundingBox) {
|
||||
// FIXME: if the mouse pointer is over this widget's child, then droppable style should be invisible
|
||||
@@ -1022,11 +970,9 @@ class Widget extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
handleDragEnd = (callback) => {
|
||||
callback()
|
||||
handleDragEnd = () => {
|
||||
this.setState({ isDragging: false })
|
||||
this.enablePointerEvents()
|
||||
|
||||
// this.props.onWidgetDragEnd(this.elementRef?.current)
|
||||
}
|
||||
|
||||
@@ -1041,40 +987,40 @@ class Widget extends React.Component {
|
||||
this.elementRef.current.style.pointerEvents = "auto"
|
||||
}
|
||||
|
||||
getInnerRenderStyling(){
|
||||
const {width, height, minWidth, minHeight} = this.getRenderSize()
|
||||
getInnerRenderStyling() {
|
||||
const { width, height, minWidth, minHeight } = this.getRenderSize()
|
||||
|
||||
const styling = {
|
||||
...this.state.widgetInnerStyling,
|
||||
width,
|
||||
width,
|
||||
height,
|
||||
minWidth,
|
||||
minWidth,
|
||||
minHeight
|
||||
}
|
||||
return styling
|
||||
}
|
||||
|
||||
getRenderSize(){
|
||||
getRenderSize() {
|
||||
|
||||
let width = isNumeric(this.state.size.width) ? `${this.state.size.width}px` : this.state.size.width
|
||||
let height = isNumeric(this.state.size.height) ? `${this.state.size.height}px` : this.state.size.height
|
||||
|
||||
let fitWidth = this.state.fitContent.width
|
||||
let fitHeight = this.state.fitContent.height
|
||||
|
||||
if (fitWidth){
|
||||
|
||||
if (fitWidth) {
|
||||
width = "max-content"
|
||||
}
|
||||
|
||||
if (fitHeight){
|
||||
if (fitHeight) {
|
||||
height = "max-content"
|
||||
}
|
||||
|
||||
// if fit width is enabled then the minsize is the resizable size
|
||||
let minWidth = fitWidth ? this.state.size.width : this.minSize.width
|
||||
let minHeight = fitHeight ? this.state.size.height : this.minSize.height
|
||||
|
||||
return {width, height, minWidth, minHeight}
|
||||
|
||||
return { width, height, minWidth, minHeight }
|
||||
|
||||
}
|
||||
|
||||
@@ -1095,10 +1041,10 @@ class Widget extends React.Component {
|
||||
* This is an internal methods don't override
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
render() {
|
||||
render() {
|
||||
|
||||
const { width, height, minWidth, minHeight } = this.getRenderSize()
|
||||
|
||||
const {width, height, minWidth, minHeight} = this.getRenderSize()
|
||||
|
||||
// NOTE: first check tkinter behaviour with the width and height
|
||||
|
||||
let outerStyle = {
|
||||
@@ -1110,175 +1056,167 @@ class Widget extends React.Component {
|
||||
left: `${this.state.pos.x}px`,
|
||||
width: width,
|
||||
height: height,
|
||||
minWidth: minWidth,
|
||||
minWidth: minWidth,
|
||||
minHeight: minHeight,
|
||||
opacity: this.state.isDragging ? 0.3 : 1,
|
||||
opacity: this.state.isDragging ? 0.6 : 1,
|
||||
}
|
||||
|
||||
// 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
|
||||
// FIXME: renable pointer events
|
||||
return (
|
||||
|
||||
// <DragContext.Consumer>
|
||||
<DragContext.Consumer>
|
||||
{
|
||||
({ draggedElement, widgetClass, onDragStart, onDragEnd, overElement, setOverElement }) => {
|
||||
({ draggedElement, widgetClass }) => {
|
||||
|
||||
|
||||
return (
|
||||
|
||||
<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()}}
|
||||
return (
|
||||
|
||||
// onDragEnter={(e) => this.handleDragEnter(e, draggedElement, setOverElement)}
|
||||
// onDragLeave={(e) => this.handleDragLeave(e, draggedElement, overElement)}
|
||||
<WidgetDnd widgetId={this.__id}
|
||||
disabled={false && this.state.dragEnabled}
|
||||
data-draggable-type={this.getWidgetType()} // helps with droppable
|
||||
dragElementType={this.getWidgetType()}
|
||||
droppableTags={this.droppableTags}
|
||||
className="tw-shadow-xl tw-w-fit tw-h-fit"
|
||||
initialPos={{ ...this.state.pos }}
|
||||
onDragStart={this.handleDragStart}
|
||||
onDragOver={(e) => {this.handleDragOver(e, draggedElement)}}
|
||||
onDragEnd={(e) => this.handleDragEnd()}
|
||||
|
||||
// onDragStart={(e) => this.handleDragStart(e, onDragStart)}
|
||||
// onDragEnd={(e) => this.handleDragEnd(onDragEnd)}
|
||||
style={outerStyle}
|
||||
onDrop={(e) => {this.handleDropEvent(e, draggedElement, widgetClass)}} // handle by droppable
|
||||
onDragEnter={(e) => this.handleDragEnter(e, draggedElement)} // this is by droppable
|
||||
widgetRef={this.elementRef}
|
||||
|
||||
>
|
||||
<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
|
||||
// onDragOver={(e) => this.handleDragOver(e, draggedElement)}
|
||||
// onDrop={(e) => {this.handleDropEvent(e, draggedElement, widgetClass); onDragEnd()}}
|
||||
|
||||
// data-drag-start-within // this attribute indicates that the drag is occurring from within the project and not a outside file drop
|
||||
// onDragEnter={(e) => this.handleDragEnter(e, draggedElement, setOverElement)}
|
||||
// onDragLeave={(e) => this.handleDragLeave(e, draggedElement, overElement)}
|
||||
|
||||
// draggable={this.state.dragEnabled}
|
||||
// onDragStart={(e) => this.handleDragStart(e, onDragStart)}
|
||||
// onDragEnd={(e) => this.handleDragEnd(onDragEnd)}
|
||||
style={outerStyle}
|
||||
|
||||
// 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)}
|
||||
<div className="tw-relative tw-w-full tw-h-full tw-top-0 tw-left-0"
|
||||
|
||||
// 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]
|
||||
|
||||
<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>
|
||||
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"}
|
||||
<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
|
||||
|
||||
`}
|
||||
style={{
|
||||
width: "calc(100% + 10px)",
|
||||
height: "calc(100% + 10px)",
|
||||
}}
|
||||
>
|
||||
</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,
|
||||
width: "calc(100% + 10px)",
|
||||
height: "calc(100% + 10px)",
|
||||
}}
|
||||
>
|
||||
</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]
|
||||
<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
|
||||
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>
|
||||
</WidgetDnd>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
</DragContext.Consumer>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</WidgetDnd>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
</DragContext.Consumer >
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { useDragDropManager, useDroppable, useDraggable } from '@dnd-kit/react'
|
||||
import { useDragContext } from '../../components/draggable/draggableContext'
|
||||
import WidgetContainer from '../constants/containers'
|
||||
|
||||
|
||||
function WidgetDnd({widgetId, droppableTags, onDrop,
|
||||
// FIXME: widget class is null
|
||||
function WidgetDnd({widgetId, widgetRef, droppableTags, onDrop, onDragStart,
|
||||
onDragEnd, onDragEnter, onDragOver, initialPos,
|
||||
...props}) {
|
||||
|
||||
const dndRef = useRef(null)
|
||||
@@ -27,7 +30,7 @@ function WidgetDnd({widgetId, droppableTags, onDrop,
|
||||
|
||||
const { ref: dragRef, draggable } = useDraggable({
|
||||
id: widgetId,
|
||||
feedback: "default",
|
||||
feedback: "move",
|
||||
type: dragElementType,
|
||||
disabled: props.disabled,
|
||||
|
||||
@@ -38,9 +41,8 @@ function WidgetDnd({widgetId, droppableTags, onDrop,
|
||||
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
|
||||
const {onDragStart: onDragContextStart, onDragEnd: onDragContextEnd, disableStyle=false} = useDragContext()
|
||||
const [allowDrop, setAllowDrop] = useState(false) // indicator if the draggable can be dropped on the droppable
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -49,33 +51,37 @@ function WidgetDnd({widgetId, droppableTags, onDrop,
|
||||
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])
|
||||
}, [manager, draggedElement, widgetClass])
|
||||
|
||||
|
||||
const handleRef = (node) => {
|
||||
dndRef.current = node
|
||||
widgetRef.current = node
|
||||
dropRef(node)
|
||||
dragRef(node)
|
||||
}
|
||||
|
||||
const handleDragEnter = (e) => {
|
||||
|
||||
const {target, source} = e.operation
|
||||
|
||||
|
||||
if (draggable.isDragSource){
|
||||
|
||||
console.log("widget class: ", widgetClass)
|
||||
|
||||
// if the current widget is being dragged
|
||||
onDragStart(dndRef?.current, widgetClass)
|
||||
onDragContextStart(dndRef?.current, widgetClass, {}, initialPos)
|
||||
|
||||
dndRef.current.style.zIndex = 10
|
||||
|
||||
onDragStart(e)
|
||||
|
||||
return
|
||||
|
||||
}else if (droppable.isDropTarget){
|
||||
|
||||
if (!draggedElement || !draggedElement.getAttribute("data-drag-start-within")) {
|
||||
@@ -92,28 +98,14 @@ function WidgetDnd({widgetId, droppableTags, onDrop,
|
||||
(droppableTags.exclude?.length > 0 && !droppableTags.exclude?.includes(dragElementType))
|
||||
))
|
||||
|
||||
console.log("droppable tags: ", dropAllowed)
|
||||
|
||||
|
||||
setAllowDrop({allow: dropAllowed, show: true})
|
||||
|
||||
setAllowDrop(dropAllowed)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
const handleDragOver = (e) => {
|
||||
const {target} = e.operation
|
||||
|
||||
// if (draggable.isDragSource){
|
||||
// onDragStart(dndRef?.current, widgetClass)
|
||||
|
||||
// // TODO
|
||||
// dndRef.current.style.zIndex = 10
|
||||
// }
|
||||
|
||||
|
||||
if (droppable.isDropTarget){
|
||||
if (!draggedElement || !draggedElement.getAttribute("data-drag-start-within")) {
|
||||
@@ -130,28 +122,21 @@ function WidgetDnd({widgetId, droppableTags, onDrop,
|
||||
))
|
||||
|
||||
|
||||
setAllowDrop({allow: dropAllowed, show: true})
|
||||
setAllowDrop(dropAllowed)
|
||||
|
||||
onDragOver(e)
|
||||
}
|
||||
// console.log("Over sir1: ", draggedElement)
|
||||
|
||||
|
||||
|
||||
// if (allowDrop) {
|
||||
// e.preventDefault() // this is necessary to allow drop to take place
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
const handleDropEvent = (e) => {
|
||||
|
||||
const {target} = e.operation
|
||||
|
||||
if (draggable.isDragSource){
|
||||
onDragEnd()
|
||||
onDragContextEnd()
|
||||
onDragEnd(e)
|
||||
|
||||
}else if (droppable.isDropTarget){
|
||||
setAllowDrop({allow: false, show: false})
|
||||
setAllowDrop(false)
|
||||
|
||||
|
||||
if (!draggedElement || !draggedElement.getAttribute("data-drag-start-within")) {
|
||||
@@ -159,11 +144,8 @@ function WidgetDnd({widgetId, droppableTags, onDrop,
|
||||
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))
|
||||
@@ -172,64 +154,27 @@ function WidgetDnd({widgetId, droppableTags, onDrop,
|
||||
if (onDrop && dropAllowed && (droppable.isDropTarget && !draggable.isDragSource)) {
|
||||
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
|
||||
{...props}
|
||||
draggable
|
||||
data-widget-id={widgetId}
|
||||
data-container={WidgetContainer.CANVAS}
|
||||
data-draggable-type={dragElementType}
|
||||
className={`${props.className} tw-relative tw-h-fit tw-w-fit tw-outline-none`}
|
||||
className={`${props.className || ''} tw-relative tw-h-max tw-w-max tw-outline-none`}
|
||||
>
|
||||
|
||||
{props.children}
|
||||
|
||||
{
|
||||
(droppable.isDropTarget && !draggable.isDragSource) &&
|
||||
<div className={`${allowDrop.allow ? "tw-bg-[#82ff1c6e]" : "tw-bg-[#eb5d366e]"}
|
||||
<div className={`${allowDrop.allow ? "tw-bg-[#82ff1c55]" : "tw-bg-[#eb5d3662]"}
|
||||
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
|
||||
`}>
|
||||
|
||||
@@ -59,7 +59,6 @@ function Draggable({dragElementType, dragWidgetClass = null, elementMetaData, ..
|
||||
|
||||
const handleDragEnd = (event) => {
|
||||
// console.log("Drag end: ", e, e.target.closest('div'))
|
||||
const {source} = event.operation
|
||||
|
||||
if (!draggable.isDragSource){
|
||||
return
|
||||
|
||||
@@ -8,7 +8,7 @@ function Droppable(props) {
|
||||
const droppableRef = useRef(null)
|
||||
const { droppableTags, onDrop } = props
|
||||
|
||||
const { draggedElement, overElement, setOverElement, widgetClass } = useDragContext()
|
||||
const { draggedElement, setOverElement, widgetClass, initialPosition } = useDragContext()
|
||||
|
||||
const { ref, isDropTarget, droppable} = useDroppable({
|
||||
id: props.id,
|
||||
@@ -40,7 +40,7 @@ function Droppable(props) {
|
||||
manager?.monitor?.removeEventListener("dragend", handleDragLeave)
|
||||
manager?.monitor?.removeEventListener("dragmove", handleDragOver)
|
||||
}
|
||||
}, [manager, draggedElement, widgetClass])
|
||||
}, [manager, draggedElement, widgetClass, initialPosition])
|
||||
|
||||
|
||||
const handleRef = (node) => {
|
||||
@@ -72,8 +72,6 @@ function Droppable(props) {
|
||||
(droppableTags.exclude?.length > 0 && !droppableTags.exclude?.includes(dragElementType))
|
||||
))
|
||||
|
||||
console.log("droppable tags: ", dropAllowed)
|
||||
|
||||
|
||||
setAllowDrop({allow: dropAllowed, show: true})
|
||||
|
||||
@@ -137,10 +135,9 @@ function Droppable(props) {
|
||||
(droppableTags.exclude?.length > 0 && !droppableTags.exclude?.includes(dragElementType))
|
||||
))
|
||||
|
||||
console.log("Widget class1: ", widgetClass, draggedElement)
|
||||
|
||||
console.log("initial POs: ", initialPosition)
|
||||
if (onDrop && dropAllowed) {
|
||||
onDrop(e, draggedElement, widgetClass)
|
||||
onDrop(e, draggedElement, widgetClass, initialPosition)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +162,7 @@ function Droppable(props) {
|
||||
|
||||
{
|
||||
allowDrop.show &&
|
||||
<div className={`${allowDrop.allow ? "tw-bg-[#82ff1c6e]" : "tw-bg-[#eb5d366e]"}
|
||||
<div className={`${allowDrop.allow ? "tw-bg-[#82ff1c31]" : "tw-bg-[#eb5d3646]"}
|
||||
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
|
||||
`}>
|
||||
|
||||
@@ -12,6 +12,7 @@ export const DragProvider = ({ children }) => {
|
||||
const [draggedElement, setDraggedElement] = useState(null)
|
||||
const [overElement, setOverElement] = useState(null) // the element the dragged items is over
|
||||
|
||||
const [initialPosition, setInitialPosition] = useState({x: 0, y: 0})
|
||||
|
||||
const [dragElementMetaData, setDragElementMetaData] = useState({})
|
||||
|
||||
@@ -19,10 +20,11 @@ export const DragProvider = ({ children }) => {
|
||||
|
||||
const [isDragging, setIsDragging] = useState(false)
|
||||
|
||||
const onDragStart = (element, widgetClass=null, metaData={}, pos={x: 0, y: 0}) => {
|
||||
const onDragStart = (element, widgetClass=null, metaData={}, initialPos={x: 0, y: 0}) => {
|
||||
|
||||
setDraggedElement(element)
|
||||
setIsDragging(true)
|
||||
setInitialPosition(initialPos)
|
||||
setDragElementMetaData(metaData)
|
||||
|
||||
if (widgetClass && !isSubClassOfWidget(widgetClass))
|
||||
@@ -45,7 +47,8 @@ export const DragProvider = ({ children }) => {
|
||||
return (
|
||||
<DragContext.Provider value={{ draggedElement, overElement, setOverElement,
|
||||
widgetClass, onDragStart, onDragEnd, isDragging,
|
||||
dragElementMetaData, setDragElementMetaData,
|
||||
dragElementMetaData, setDragElementMetaData,
|
||||
initialPosition
|
||||
}}>
|
||||
{children}
|
||||
</DragContext.Provider>
|
||||
|
||||
Reference in New Issue
Block a user