diff --git a/frontend/src/AppBuilder/AppCanvas/Container.jsx b/frontend/src/AppBuilder/AppCanvas/Container.jsx
index fed1a3db34..fc163939f6 100644
--- a/frontend/src/AppBuilder/AppCanvas/Container.jsx
+++ b/frontend/src/AppBuilder/AppCanvas/Container.jsx
@@ -56,6 +56,11 @@ export const Container = React.memo(
const [{ isOverCurrent }, drop] = useDrop({
accept: 'box',
+ hover: (item) => {
+ item.canvasRef = realCanvasRef?.current;
+ item.canvasId = id;
+ item.canvasWidth = getContainerCanvasWidth();
+ },
drop: async ({ componentType }, monitor) => {
const didDrop = monitor.didDrop();
if (didDrop) return;
@@ -89,14 +94,15 @@ export const Container = React.memo(
function getContainerCanvasWidth() {
if (canvasWidth !== undefined) {
if (componentType === 'Listview' && listViewMode == 'grid') return canvasWidth / columns - 2;
- return canvasWidth;
+ if (id === 'canvas') return canvasWidth;
+ return canvasWidth - 2;
}
return realCanvasRef?.current?.offsetWidth;
}
const gridWidth = getContainerCanvasWidth() / NO_OF_GRIDS;
useEffect(() => {
- useGridStore.getState().actions.setSubContainerWidths(id, (getContainerCanvasWidth() - 2) / NO_OF_GRIDS);
+ useGridStore.getState().actions.setSubContainerWidths(id, getContainerCanvasWidth() / NO_OF_GRIDS);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [canvasWidth, listViewMode, columns]);
@@ -137,8 +143,7 @@ export const Container = React.memo(
}}
style={{
height: id === 'canvas' ? `${canvasHeight}` : '100%',
- // backgroundSize: '25.3953px 10px',
- backgroundSize: `${gridWidth}px 10px`,
+ backgroundSize: `${gridWidth}px ${10}px`,
backgroundColor:
currentMode === 'view'
? computeViewerBackgroundColor(darkMode, canvasBgColor)
@@ -169,6 +174,7 @@ export const Container = React.memo(
data-parentId={id}
canvas-height={canvasHeight}
onClick={handleCanvasClick}
+ component-type={componentType}
>
state.getHoveredComponentForGrid, shallow);
const getResolvedComponent = useStore((state) => state.getResolvedComponent, shallow);
+ const draggingComponentId = useGridStore((state) => state.draggingComponentId, shallow);
+ const resizingComponentId = useGridStore((state) => state.resizingComponentId, shallow);
+ const [dragParentId, setDragParentId] = useState(null);
+ const [elementGuidelines, setElementGuidelines] = useState([]);
+ const componentsSnappedTo = useRef(null);
+ const prevDragParentId = useRef(null);
+ const newDragParentId = useRef(null);
+ const [isGroupDragging, setIsGroupDragging] = useState(false);
+
+ useEffect(() => {
+ const selectedSet = new Set(selectedComponents);
+ const draggingOrResizingId = draggingComponentId || resizingComponentId;
+ const isGrouped = findHighestLevelofSelection().length > 1;
+ const firstSelectedParent =
+ selectedComponents.length > 0 ? boxList.find((b) => b.id === selectedComponents[0])?.parent : null;
+ const selectedParent = dragParentId || firstSelectedParent;
+
+ const guidelines = boxList
+ .filter((box) => {
+ const isVisible =
+ getResolvedValue(box?.component?.definition?.properties?.visibility?.value) ||
+ getResolvedValue(box?.component?.definition?.styles?.visibility?.value);
+
+ // Early return for non-visible elements
+ if (!isVisible) return false;
+
+ if (isGrouped) {
+ // If component is selected, don't show its guidelines
+ if (selectedSet.has(box.id)) return false;
+ return selectedParent ? box.parent === selectedParent : !box.parent;
+ }
+
+ if (draggingOrResizingId) {
+ if (box.id === draggingOrResizingId) return false;
+ return dragParentId ? box.parent === dragParentId : !box.parent;
+ }
+
+ return true;
+ })
+ .map((box) => `.ele-${box.id}`);
+ setElementGuidelines(guidelines);
+ }, [boxList, dragParentId, draggingComponentId, resizingComponentId, selectedComponents, getResolvedValue]);
useEffect(() => {
setBoxList(
@@ -94,7 +139,7 @@ export default function Grid({ gridWidth, currentLayout }) {
boxList.forEach(({ id, height, width, x, y, gw }) => {
const _canvasWidth = gw ? gw * NO_OF_GRIDS : canvasWidth;
let newWidth = Math.round((width * NO_OF_GRIDS) / _canvasWidth);
- y = Math.round(y / 10) * 10;
+ y = Math.round(y / GRID_HEIGHT) * GRID_HEIGHT;
gw = gw ? gw : gridWidth;
const parent = transformedBoxes[id]?.component?.parent;
@@ -117,7 +162,7 @@ export default function Grid({ gridWidth, currentLayout }) {
}
setComponentLayout({
[id]: {
- height: height ? height : 10,
+ height: height ? height : GRID_HEIGHT,
width: newWidth ? newWidth : 1,
top: y,
left: Math.round(x / gw),
@@ -319,7 +364,7 @@ export default function Grid({ gridWidth, currentLayout }) {
}
// Round y position
- y = Math.max(0, Math.round(y / 10) * 10);
+ y = Math.max(0, Math.round(y / GRID_HEIGHT) * GRID_HEIGHT);
// Adjust height for certain parent components
if (parent) {
const parentElem = document.getElementById(`canvas-${parent}`);
@@ -375,49 +420,10 @@ export default function Grid({ gridWidth, currentLayout }) {
};
}, []);
- const handleDragGridLinesVisibility = (e, events = []) => {
- const { clientX, clientY } = e;
- if (!document.elementFromPoint(clientX, clientY)) return;
-
- const targetElems = document.elementsFromPoint(clientX, clientY);
- const draggedOverElements = targetElems.filter(
- (ele) =>
- !events.some((event) => event.target.id === ele.id) &&
- (ele.classList.contains('target') || ele.classList.contains('real-canvas'))
- );
- const draggedOverElem = draggedOverElements.find((ele) => ele.classList.contains('target'));
- const draggedOverContainer = draggedOverElements.find((ele) => ele.classList.contains('real-canvas'));
- const appCanvas = document.getElementById('real-canvas');
-
- // Show grid line for main canvas
- draggedOverContainer?.classList.remove('hide-grid');
- draggedOverContainer?.classList.add('show-grid');
-
- // Remove 'show-grid' class from all sub-canvases
- const canvasElms = document.getElementsByClassName('sub-canvas');
- Array.from(canvasElms).forEach((element) => {
- element.classList.remove('show-grid');
- element.classList.add('hide-grid');
- });
-
- // Determine the potential new parent
- const parentId = draggedOverContainer?.getAttribute('data-parentId') || draggedOverElem?.id;
-
- // Show grid for the appropriate canvas
- if (parentId) {
- const newParentCanvas = document.getElementById('canvas-' + parentId);
- if (newParentCanvas) {
- appCanvas?.classList?.remove('show-grid');
- newParentCanvas?.classList.remove('hide-grid');
- newParentCanvas?.classList.add('show-grid');
- }
- }
-
- useGridStore.getState().actions.setDragTarget(parentId);
- };
-
const handleDragGroupEnd = (e) => {
try {
+ hideGridLines();
+ setIsGroupDragging(false);
const { events, clientX, clientY } = e;
const initialParent = events[0].target.closest('.real-canvas');
// Get potential new parent using same logic as onDragEnd
@@ -476,7 +482,7 @@ export default function Grid({ gridWidth, currentLayout }) {
// Apply transform to return to original position
ev.target.style.transform = `translate(${Math.round(_left / _gridWidth) * _gridWidth}px, ${
- Math.round(_top / 10) * 10
+ Math.round(_top / GRID_HEIGHT) * GRID_HEIGHT
}px)`;
}
});
@@ -513,7 +519,7 @@ export default function Grid({ gridWidth, currentLayout }) {
// Apply grid snapping and bounds
const snappedX = Math.round(posX / _gridWidth) * _gridWidth;
- const snappedY = Math.round(posY / 10) * 10;
+ const snappedY = Math.round(posY / GRID_HEIGHT) * GRID_HEIGHT;
ev.target.style.transform = `translate(${snappedX}px, ${snappedY}px)`;
return {
@@ -530,6 +536,18 @@ export default function Grid({ gridWidth, currentLayout }) {
}
};
+ React.useEffect(() => {
+ const components = Array.from(document.querySelectorAll('.active-target')).filter(
+ (component) => !selectedComponents.includes(component.getAttribute('widgetid'))
+ );
+ const draggingOrResizing = draggingComponentId || resizingComponentId;
+ if (!draggingOrResizing && components.length > 0) {
+ for (const component of components) {
+ component?.classList?.remove('active-target');
+ }
+ }
+ }, [draggingComponentId, resizingComponentId, isGroupDragging, selectedComponents]);
+
if (mode !== 'edit') return null;
return (
@@ -556,7 +574,7 @@ export default function Grid({ gridWidth, currentLayout }) {
let _gridWidth = useGridStore.getState().subContainerWidths[currentWidget.component?.parent] || gridWidth;
if (currentWidget.component?.parent) {
document.getElementById('canvas-' + currentWidget.component?.parent)?.classList.add('show-grid');
- useGridStore.getState().actions.setDragTarget(currentWidget.component?.parent);
+ setDragParentId(currentWidget.component?.parent);
} else {
document.getElementById('real-canvas').classList.add('show-grid');
}
@@ -611,12 +629,12 @@ export default function Grid({ gridWidth, currentLayout }) {
// When clicked on widget boundary/resizer, select the component
setSelectedComponents([e.target.id]);
}
-
+ showGridLines();
if (!isComponentVisible(e.target.id)) {
return false;
}
useGridStore.getState().actions.setResizingComponentId(e.target.id);
- e.setMin([gridWidth, 10]);
+ e.setMin([gridWidth, GRID_HEIGHT]);
}}
onResizeEnd={(e) => {
try {
@@ -628,7 +646,7 @@ export default function Grid({ gridWidth, currentLayout }) {
document.getElementById('canvas-' + currentWidget.component?.parent)?.classList.remove('show-grid');
let _gridWidth = useGridStore.getState().subContainerWidths[currentWidget.component?.parent] || gridWidth;
let width = Math.round(e?.lastEvent?.width / _gridWidth) * _gridWidth;
- const height = Math.round(e?.lastEvent?.height / 10) * 10;
+ const height = Math.round(e?.lastEvent?.height / GRID_HEIGHT) * GRID_HEIGHT;
const currentWidth = currentWidget.width * _gridWidth;
const diffWidth = e.lastEvent?.width - currentWidth;
@@ -656,16 +674,16 @@ export default function Grid({ gridWidth, currentLayout }) {
transformY = transformY < 0 ? 0 : transformY > maxY ? maxY : transformY;
transformX = transformX < 0 ? 0 : transformX > maxLeft ? maxLeft : transformX;
- const roundedTransformY = Math.round(transformY / 10) * 10;
- transformY = transformY % 10 === 5 ? roundedTransformY - 10 : roundedTransformY;
+ const roundedTransformY = Math.round(transformY / GRID_HEIGHT) * GRID_HEIGHT;
+ transformY = transformY % GRID_HEIGHT === 5 ? roundedTransformY - GRID_HEIGHT : roundedTransformY;
e.target.style.transform = `translate(${Math.round(transformX / _gridWidth) * _gridWidth}px, ${
- Math.round(transformY / 10) * 10
+ Math.round(transformY / GRID_HEIGHT) * GRID_HEIGHT
}px)`;
if (!maxWidthHit || e.width < e.target.clientWidth) {
e.target.style.width = `${Math.round(e.lastEvent.width / _gridWidth) * _gridWidth}px`;
}
if (!maxHeightHit || e.height < e.target.clientHeight) {
- e.target.style.height = `${Math.round(e.lastEvent.height / 10) * 10}px`;
+ e.target.style.height = `${Math.round(e.lastEvent.height / GRID_HEIGHT) * GRID_HEIGHT}px`;
}
const resizeData = {
id: e.target.id,
@@ -681,12 +699,11 @@ export default function Grid({ gridWidth, currentLayout }) {
} catch (error) {
console.error('ResizeEnd error ->', error);
}
- useGridStore.getState().actions.setDragTarget();
+ setDragParentId(null);
toggleCanvasUpdater();
}}
onResizeGroupStart={({ events }) => {
- const parentElm = events[0].target.closest('.real-canvas');
- parentElm.classList.add('show-grid');
+ showGridLines();
}}
onResizeGroup={({ events }) => {
const parentElm = events[0].target.closest('.real-canvas');
@@ -709,8 +726,7 @@ export default function Grid({ gridWidth, currentLayout }) {
const { events } = e;
const newBoxs = [];
- const parentElm = events[0].target.closest('.real-canvas');
- parentElm.classList.remove('show-grid');
+ hideGridLines();
// TODO: Logic needs to be relooked post go live P2
groupResizeDataRef.current.forEach((ev) => {
@@ -721,9 +737,9 @@ export default function Grid({ gridWidth, currentLayout }) {
let width = Math.round(ev.width / _gridWidth) * _gridWidth;
width = width < _gridWidth ? _gridWidth : width;
let posX = Math.round(ev.drag.translate[0] / _gridWidth) * _gridWidth;
- let posY = Math.round(ev.drag.translate[1] / 10) * 10;
- let height = Math.round(ev.height / 10) * 10;
- height = height < 10 ? 10 : height;
+ let posY = Math.round(ev.drag.translate[1] / GRID_HEIGHT) * GRID_HEIGHT;
+ let height = Math.round(ev.height / GRID_HEIGHT) * GRID_HEIGHT;
+ height = height < GRID_HEIGHT ? GRID_HEIGHT : height;
ev.target.style.width = `${width}px`;
ev.target.style.height = `${height}px`;
@@ -751,7 +767,7 @@ export default function Grid({ gridWidth, currentLayout }) {
let posX = currentWidget?.layouts[currentLayout].left * _gridWidth;
let posY = currentWidget?.layouts[currentLayout].top;
let height = currentWidget?.layouts[currentLayout].height;
- height = height < 10 ? 10 : height;
+ height = height < GRID_HEIGHT ? GRID_HEIGHT : height;
ev.target.style.width = `${width}px`;
ev.target.style.height = `${height}px`;
ev.target.style.transform = `translate(${posX}px, ${posY}px)`;
@@ -766,6 +782,11 @@ export default function Grid({ gridWidth, currentLayout }) {
}}
checkInput
onDragStart={(e) => {
+ // This is to prevent parent component from being dragged and the stop the propagation of the event
+ if (getHoveredComponentForGrid() !== e.target.id) {
+ return false;
+ }
+ newDragParentId.current = boxList.find((box) => box.id === e.target.id)?.parent;
e?.moveable?.controlBox?.removeAttribute('data-off-screen');
const box = boxList.find((box) => box.id === e.target.id);
// Prevent drag if shift is pressed for SUBCONTAINER_WIDGETS
@@ -808,10 +829,6 @@ export default function Grid({ gridWidth, currentLayout }) {
return false;
}
}
- // This is to prevent parent component from being dragged and the stop the propagation of the event
- if (getHoveredComponentForGrid() !== e.target.id) {
- return false;
- }
}}
onDragEnd={(e) => {
try {
@@ -819,6 +836,9 @@ export default function Grid({ gridWidth, currentLayout }) {
useGridStore.getState().actions.setDraggingComponentId(null);
isDraggingRef.current = false;
}
+ prevDragParentId.current = null;
+ newDragParentId.current = null;
+ setDragParentId(null);
if (!e.lastEvent) {
return;
@@ -905,14 +925,14 @@ export default function Grid({ gridWidth, currentLayout }) {
}
e.target.style.transform = `translate(${Math.round(left / _gridWidth) * _gridWidth}px, ${
- Math.round(top / 10) * 10
+ Math.round(top / GRID_HEIGHT) * GRID_HEIGHT
}px)`;
if (draggedOverElemId === currentParentId || isParentChangeAllowed) {
handleDragEnd([
{
id: e.target.id,
x: left,
- y: Math.round(top / 10) * 10,
+ y: Math.round(top / GRID_HEIGHT) * GRID_HEIGHT,
parent: isParentChangeAllowed ? draggedOverElemId : undefined,
},
]);
@@ -923,28 +943,34 @@ export default function Grid({ gridWidth, currentLayout }) {
} catch (error) {
console.log('draggedOverElemId->error', error);
}
- // Hide all sub-canvases
- var canvasElms = document.getElementsByClassName('sub-canvas');
- var elementsArray = Array.from(canvasElms);
- elementsArray.forEach(function (element) {
- element.classList.remove('show-grid');
- element.classList.add('hide-grid');
- });
- document.getElementById('real-canvas')?.classList.remove('show-grid');
+ hideGridLines();
toggleCanvasUpdater();
}}
onDrag={(e) => {
// Since onDrag is called multiple times when dragging, hence we are using isDraggingRef to prevent setting state again and again
if (!isDraggingRef.current) {
useGridStore.getState().actions.setDraggingComponentId(e.target.id);
+ showGridLines();
isDraggingRef.current = true;
}
- const parentComponent = boxList.find((box) => box.id === boxList.find((b) => b.id === e.target.id)?.parent);
+ const currentWidget = boxList.find((box) => box.id === e.target.id);
+ const currentParentId =
+ currentWidget?.component?.parent === null ? 'canvas' : currentWidget?.component?.parent;
+ const _gridWidth = useGridStore.getState().subContainerWidths[dragParentId] || gridWidth;
+ const _dragParentId = newDragParentId.current === null ? 'canvas' : newDragParentId.current;
- let top = e.translate[1];
- let left = e.translate[0];
+ // Snap to grid
+ let left = Math.round(e.translate[0] / _gridWidth) * _gridWidth;
+ let top = Math.round(e.translate[1] / GRID_HEIGHT) * GRID_HEIGHT;
+
+ // This logic is to handle the case when the dragged element is over a new canvas
+ if (_dragParentId !== currentParentId) {
+ left = e.translate[0];
+ top = e.translate[1];
+ }
// Special case for Modal
+ const parentComponent = boxList.find((box) => box.id === boxList.find((b) => b.id === e.target.id)?.parent);
if (parentComponent?.component?.component === 'Modal') {
const elemContainer = e.target.closest('.real-canvas');
const containerHeight = elemContainer.clientHeight;
@@ -962,8 +988,32 @@ export default function Grid({ gridWidth, currentLayout }) {
`translate: ${e.translate[0]} | Round: ${Math.round(e.translate[0] / gridWidth) * gridWidth} | ${gridWidth}`
);
- handleDragGridLinesVisibility(e, [{ target: e.target }]);
+ // This block is to show grid lines on the canvas when the dragged element is over a new canvas
+ if (document.elementFromPoint(e.clientX, e.clientY)) {
+ const targetElems = document.elementsFromPoint(e.clientX, e.clientY);
+ const draggedOverElements = targetElems.filter(
+ (ele) =>
+ (ele.id !== e.target.id && ele.classList.contains('target')) || ele.classList.contains('real-canvas')
+ );
+ const draggedOverElem = draggedOverElements.find((ele) => ele.classList.contains('target'));
+ const draggedOverContainer = draggedOverElements.find((ele) => ele.classList.contains('real-canvas'));
+ // Determine potential new parent
+ let newParentId = draggedOverContainer?.getAttribute('data-parentId') || draggedOverElem?.id;
+
+ if (newParentId === e.target.id) {
+ newParentId = boxList.find((box) => box.id === e.target.id)?.component?.parent;
+ } else if (parentComponent?.component?.component === 'Modal') {
+ // Never update parentId for Modal
+ newParentId = parentComponent?.id;
+ }
+
+ if (newParentId !== prevDragParentId.current) {
+ setDragParentId(newParentId === 'canvas' ? null : newParentId);
+ newDragParentId.current = newParentId === 'canvas' ? null : newParentId;
+ prevDragParentId.current = newParentId;
+ }
+ }
// Postion ghost element exactly as same at dragged element
if (document.getElementById(`moveable-drag-ghost`)) {
document.getElementById(`moveable-drag-ghost`).style.transform = `translate(${left}px, ${top}px)`;
@@ -978,31 +1028,26 @@ export default function Grid({ gridWidth, currentLayout }) {
parentElm?.classList?.add('show-grid');
}
- handleDragGridLinesVisibility(ev, events);
-
events.forEach((ev) => {
- let left = ev.translate[0];
- let top = ev.translate[1];
+ const currentWidget = boxList.find(({ id }) => id === ev.target.id);
+ const _gridWidth =
+ useGridStore.getState().subContainerWidths?.[currentWidget?.component?.parent] || gridWidth;
+
+ let left = Math.round(ev.translate[0] / _gridWidth) * _gridWidth;
+ let top = Math.round(ev.translate[1] / GRID_HEIGHT) * GRID_HEIGHT;
ev.target.style.transform = `translate(${left}px, ${top}px)`;
});
updateNewPosition(events);
}}
onDragGroupStart={({ events }) => {
- const parentElm = events[0]?.target?.closest('.real-canvas');
- parentElm?.classList?.add('show-grid');
+ showGridLines();
+ setIsGroupDragging(true);
}}
onDragGroupEnd={(e) => {
handleDragGroupEnd(e);
toggleCanvasUpdater();
}}
- //snap settgins
- snappable={true}
- snapThreshold={10}
- isDisplaySnapDigit={false}
- bounds={CANVAS_BOUNDS}
- displayAroundControls={true}
- controlPadding={20}
onClickGroup={(e) => {
const targetId =
e.inputEvent.target.id || e.inputEvent.target.closest('.moveable-box')?.getAttribute('widgetid');
@@ -1018,6 +1063,42 @@ export default function Grid({ gridWidth, currentLayout }) {
}
}
}}
+ //snap settgins
+ snappable={true}
+ snapGap={false}
+ isDisplaySnapDigit={false}
+ snapThreshold={GRID_HEIGHT}
+ // Guidelines configuration
+ elementGuidelines={elementGuidelines}
+ snapDirections={{
+ top: true,
+ right: true,
+ bottom: true,
+ left: true,
+ center: false,
+ middle: false,
+ }}
+ elementSnapDirections={{
+ top: true,
+ left: true,
+ bottom: true,
+ right: true,
+ center: false,
+ middle: false,
+ }}
+ onSnap={(e) => {
+ const components = e.elements;
+ if (isArray(componentsSnappedTo.current)) {
+ for (const component of componentsSnappedTo.current) {
+ component?.element?.classList?.remove('active-target');
+ }
+ }
+ componentsSnappedTo.current = components;
+ for (const component of components) {
+ component.element.classList.add('active-target');
+ }
+ }}
+ snapGridAll={true}
/>
>
);
diff --git a/frontend/src/AppBuilder/AppCanvas/Grid/gridUtils.js b/frontend/src/AppBuilder/AppCanvas/Grid/gridUtils.js
index 817f9a5ca9..4bfd030a3c 100644
--- a/frontend/src/AppBuilder/AppCanvas/Grid/gridUtils.js
+++ b/frontend/src/AppBuilder/AppCanvas/Grid/gridUtils.js
@@ -391,3 +391,25 @@ export function hasParentWithClass(child, className) {
return false;
}
+
+export function showGridLines() {
+ var canvasElms = document.getElementsByClassName('sub-canvas');
+ var elementsArray = Array.from(canvasElms);
+ elementsArray.forEach(function (element) {
+ element.classList.remove('hide-grid');
+ element.classList.add('show-grid');
+ });
+ document.getElementById('real-canvas')?.classList.remove('hide-grid');
+ document.getElementById('real-canvas')?.classList.add('show-grid');
+}
+
+export function hideGridLines() {
+ var canvasElms = document.getElementsByClassName('sub-canvas');
+ var elementsArray = Array.from(canvasElms);
+ elementsArray.forEach(function (element) {
+ element.classList.remove('show-grid');
+ element.classList.add('hide-grid');
+ });
+ document.getElementById('real-canvas')?.classList.remove('show-grid');
+ document.getElementById('real-canvas')?.classList.add('hide-grid');
+}
diff --git a/frontend/src/AppBuilder/RightSideBar/ComponentsManagerTab/DragLayer.jsx b/frontend/src/AppBuilder/RightSideBar/ComponentsManagerTab/DragLayer.jsx
index 7450011b93..77274cd658 100644
--- a/frontend/src/AppBuilder/RightSideBar/ComponentsManagerTab/DragLayer.jsx
+++ b/frontend/src/AppBuilder/RightSideBar/ComponentsManagerTab/DragLayer.jsx
@@ -2,12 +2,14 @@ import React, { useEffect } from 'react';
import { WidgetBox } from '../WidgetBox';
import { useDrag, useDragLayer } from 'react-dnd';
import { getEmptyImage } from 'react-dnd-html5-backend';
+import { snapToGrid } from '@/AppBuilder/AppCanvas/appCanvasUtils';
+import { NO_OF_GRIDS } from '@/AppBuilder/AppCanvas/appCanvasConstants';
export const DragLayer = ({ index, component }) => {
const [{ isDragging }, drag, preview] = useDrag(
() => ({
type: 'box',
- item: { componentType: component.component },
+ item: { componentType: component.component, component },
collect: (monitor) => ({ isDragging: monitor.isDragging() }),
}),
[component.component]
@@ -18,7 +20,6 @@ export const DragLayer = ({ index, component }) => {
}, []);
const size = component.defaultSize || { width: 30, height: 40 };
-
return (
<>
{isDragging &&
}
@@ -30,32 +31,39 @@ export const DragLayer = ({ index, component }) => {
};
const CustomDragLayer = ({ size }) => {
- const { currentOffset } = useDragLayer((monitor) => ({
+ const { currentOffset, item } = useDragLayer((monitor) => ({
currentOffset: monitor.getSourceClientOffset(),
+ item: monitor.getItem(),
}));
if (!currentOffset) return null;
- const canvasWidth = document.getElementsByClassName('real-canvas')[0]?.getBoundingClientRect()?.width;
-
+ const canvasWidth = item?.canvasWidth;
+ const canvasBounds = item?.canvasRef?.getBoundingClientRect();
const height = size.height;
- const width = (canvasWidth * size.width) / 43;
+ const width = (canvasWidth * size.width) / NO_OF_GRIDS;
+
+ // Calculate position relative to the current canvas (parent or child)
+ const left = currentOffset.x - (canvasBounds?.left || 0);
+ const top = currentOffset.y - (canvasBounds?.top || 0);
+
+ const [x, y] = snapToGrid(canvasWidth, left, top);
return (