This commit is contained in:
Nakul Nagargade 2025-06-26 15:34:45 +05:30
parent 9a0430a94a
commit 268d4a1aef
7 changed files with 46 additions and 71 deletions

View file

@ -105,7 +105,7 @@ export const Container = React.memo(
const canvasId =
closestCanvas?.getAttribute('data-parentId') ||
closestCanvas?.id?.replace('canvas-', '') ||
(closestCanvas?.id === 'real-canvas' ? 'canvas' : null);
(closestCanvas?.id === 'real-canvas' ? 'real-canvas' : null);
// Only update if this container is the most specific one under the mouse
if (canvasId === id) {
@ -126,7 +126,6 @@ export const Container = React.memo(
}
},
drop: (item, monitor) => {
console.log('Container drop', item, monitor.getClientOffset());
handleDrop(item, monitor, id);
},
collect: (monitor) => ({

View file

@ -86,6 +86,7 @@ export default function Grid({ gridWidth, currentLayout }) {
const getExposedValueOfComponent = useStore((state) => state.getExposedValueOfComponent, shallow);
const setReorderContainerChildren = useStore((state) => state.setReorderContainerChildren, shallow);
const currentDragCanvasId = useGridStore((state) => state.currentDragCanvasId, shallow);
const groupedTargets = [...findHighestLevelofSelection().map((component) => '.ele-' + component.id)];
const snapContainer = useMemo(() => {
if (currentDragCanvasId) {
@ -97,12 +98,12 @@ export default function Grid({ gridWidth, currentLayout }) {
return '#real-canvas';
}, [currentDragCanvasId, dragParentId]);
const moveableTarget = useMemo(() => {
const getMoveableTarget = () => {
if (virtualTarget) {
return '#moveable-ghost-element';
}
return groupedTargets?.length > 1 ? groupedTargets : '.target';
}, [virtualTarget, groupedTargets]);
};
// Set moveable reference in grid store for access by other components
useEffect(() => {
@ -326,8 +327,6 @@ export default function Grid({ gridWidth, currentLayout }) {
});
}, [selectedComponents]);
const groupedTargets = [...findHighestLevelofSelection().map((component) => '.ele-' + component.id)];
useEffect(() => {
reloadGrid();
// eslint-disable-next-line react-hooks/exhaustive-deps
@ -601,7 +600,7 @@ export default function Grid({ gridWidth, currentLayout }) {
multiComponentHandle: groupedTargets.length > 1,
}}
flushSync={flushSync}
target={moveableTarget}
target={getMoveableTarget()}
origin={false}
individualGroupable={virtualTarget ? false : groupedTargets.length <= 1}
draggable={!shouldFreeze && mode !== 'view'}
@ -883,11 +882,8 @@ export default function Grid({ gridWidth, currentLayout }) {
handleActivateNonDraggingComponents();
}}
onDragEnd={(e) => {
console.log('e.lastEvent', moveableRef);
handleDeactivateTargets();
if (e.target.id === 'moveable-ghost-element') {
console.log('e.target', false);
// e.target.remove();
return;
}
try {
@ -953,12 +949,13 @@ export default function Grid({ gridWidth, currentLayout }) {
const _gridWidth = useGridStore.getState().subContainerWidths[currentDragCanvasId] || gridWidth;
let left = e.translate[0];
let top = e.translate[1];
// console.log('e.translate', e.translate);
// if (currentDragCanvasId === 'canvas') {
// console.log('e.translate', e.translate, _gridWidth);
left = Math.round(e.translate[0] / _gridWidth) * _gridWidth;
top = Math.round(e.translate[1] / GRID_HEIGHT) * GRID_HEIGHT;
console.log('e.translate', e.translate, left, top);
if (currentDragCanvasId === 'canvas') {
left = Math.round(e.translate[0] / _gridWidth) * _gridWidth;
top = Math.round(e.translate[1] / GRID_HEIGHT) * GRID_HEIGHT;
}
useGridStore.getState().actions.setGhostDragPosition({ left, top, e });
e.target.style.transform = `translate(${left}px, ${top}px)`;
return false;
}
@ -1152,7 +1149,7 @@ export default function Grid({ gridWidth, currentLayout }) {
}}
// snapGridAll={true}
scrollable={true}
snapContainer={snapContainer}
// snapContainer={snapContainer}
// snapGridWidth={100}
/>
</>

View file

@ -5,7 +5,7 @@ import useStore from '@/AppBuilder/_stores/store';
import { toast } from 'react-hot-toast';
import _, { debounce } from 'lodash';
import { useGridStore } from '@/_stores/gridStore';
import { findHighestLevelofSelection } from './Grid/gridUtils';
import { findHighestLevelofSelection, getMouseDistanceFromParentDiv } from './Grid/gridUtils';
import {
CANVAS_WIDTHS,
NO_OF_GRIDS,
@ -34,26 +34,28 @@ export const addNewWidgetToTheEditor = (
parentId,
moduleInfo = undefined
) => {
const canvasBoundingRect = realCanvasRef?.current?.getBoundingClientRect() || realCanvasRef?.getBoundingClientRect();
const canvasBoundingRect = realCanvasRef?.getBoundingClientRect();
const componentMeta = componentTypes.find((component) => component.component === componentType);
const componentName = computeComponentName(componentType, useStore.getState().getCurrentPageComponents());
const parentCanvasType = realCanvasRef?.getAttribute('component-type');
const componentData = deepClone(componentMeta);
const defaultWidth = componentData.defaultSize.width;
const defaultHeight = componentData.defaultSize.height;
const offsetFromTopOfWindow = canvasBoundingRect?.top;
const offsetFromLeftOfWindow = canvasBoundingRect?.left;
const currentOffset = eventMonitorObject?.getSourceClientOffset();
const { e } = useGridStore.getState().getGhostDragPosition();
const subContainerWidth = canvasBoundingRect?.width;
let left = Math.round(currentOffset?.x - offsetFromLeftOfWindow);
let top = Math.round(currentOffset?.y - offsetFromTopOfWindow);
[left, top] = snapToGrid(subContainerWidth, left, top);
const { left: left3, top: top3 } = getMouseDistanceFromParentDiv(
e,
parentId === 'canvas' ? 'real-canvas' : parentId,
parentCanvasType
);
// [left, top] = snapToGrid(subContainerWidth, left, top);
let [left, top] = snapToGrid(subContainerWidth, left3, top3);
const gridWidth = subContainerWidth / NO_OF_GRIDS;
left = Math.round(left / gridWidth);
// Adjust widget width based on the dropping canvas width
const mainCanvasWidth = useGridStore.getState().subContainerWidths['canvas'];
let width = Math.round((defaultWidth * mainCanvasWidth) / gridWidth);

View file

@ -9,6 +9,7 @@ import { isPDFSupported } from '@/_helpers/appUtils';
import toast from 'react-hot-toast';
import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
import { useGhostMoveable } from '../_hooks/useGhostMoveable';
import { handleDeactivateTargets, hideGridLines } from '../AppCanvas/Grid/gridUtils';
export const useCanvasDropHandler = ({ appType }) => {
const { moduleId } = useModuleContext();
@ -20,20 +21,17 @@ export const useCanvasDropHandler = ({ appType }) => {
const currentLayout = useStore((state) => state.currentLayout, shallow);
const setCurrentDragCanvasId = useGridStore((state) => state.actions.setCurrentDragCanvasId);
const { deactivateGhost } = useGhostMoveable();
const currentDragCanvasId = useGridStore((state) => state.currentDragCanvasId, shallow);
// console.log('currentDragCanvasId', currentDragCanvasId);
const handleDrop = ({ componentType: draggedComponentType, component }, monitor, canvasId) => {
const realCanvasRef =
document.getElementById(`canvas-${currentDragCanvasId}`) || document.getElementById(`real-canvas`);
// Reset canvas ID when dropping
setCurrentDragCanvasId(null);
!canvasId || canvasId === 'canvas'
? document.getElementById(`real-canvas`)
: document.getElementById(`canvas-${canvasId}`);
// Ensure ghost is deactivated before processing drop
deactivateGhost();
handleDeactivateTargets();
hideGridLines();
// Deactivate ghost when dropping
setShowModuleBorder(false); // Hide the module border when dropping
if (currentMode === 'view' || (appType === 'module' && draggedComponentType !== 'ModuleContainer')) {
@ -69,7 +67,7 @@ export const useCanvasDropHandler = ({ appType }) => {
monitor,
currentLayout,
realCanvasRef,
currentDragCanvasId,
canvasId,
moduleInfo
);
const childComponents = addChildrenWidgetsToParent(draggedComponentType, parentComponent?.id, currentLayout);
@ -82,12 +80,14 @@ export const useCanvasDropHandler = ({ appType }) => {
monitor,
currentLayout,
realCanvasRef,
currentDragCanvasId,
canvasId,
moduleInfo
);
addComponentToCurrentPage([newComponent]);
setActiveRightSideBarTab(RIGHT_SIDE_BAR_TAB.CONFIGURATION);
}
// Reset canvas ID when dropping
setCurrentDragCanvasId(null);
};
return handleDrop;

View file

@ -16,7 +16,6 @@ export const DragLayer = ({ index, component, isModuleTab = false }) => {
const { isModuleEditor } = useModuleContext();
const setShowModuleBorder = useStore((state) => state.setShowModuleBorder, shallow) || noop;
const handleDrop = useCanvasDropHandler({ appType: isModuleTab ? 'module' : 'app' }) || noop;
const currentDragCanvasId = useGridStore((state) => state.currentDragCanvasId, shallow);
const [{ isDragging }, drag, preview] = useDrag(
() => ({
@ -25,16 +24,10 @@ export const DragLayer = ({ index, component, isModuleTab = false }) => {
collect: (monitor) => ({ isDragging: monitor.isDragging() }),
end: (item, monitor) => {
const clientOffset = monitor.getClientOffset();
console.log('end', item, monitor.getDropResult(), monitor.getClientOffset());
console.log('currentDragCanvasId', currentDragCanvasId);
const currentDragCanvasId = useGridStore.getState().currentDragCanvasId;
if (clientOffset) {
// const canvas = document.getElementById(`canvas-${currentDragCanvasId}`);
const realCanvas = document.getElementById(`real-canvas`);
handleDrop(item, monitor, realCanvas, currentDragCanvasId);
handleDrop(item, monitor, currentDragCanvasId);
}
// if (didDrop) {
// handleDrop(item, monitor);
// }
},
}),
[component.component]
@ -59,15 +52,7 @@ export const DragLayer = ({ index, component, isModuleTab = false }) => {
return (
<>
{/* {isDragging && <CustomDragLayer size={size} />} */}
<div
ref={drag}
className="draggable-box"
style={{ height: '100%', width: isModuleTab && '100%' }}
// onDragEnd={(e) => {
// const realCanvas = document.getElementById(`real-canvas`);
// handleDrop(e, realCanvas, currentDragCanvasId);
// }}
>
<div ref={drag} className="draggable-box" style={{ height: '100%', width: isModuleTab && '100%' }}>
{isModuleTab ? <ModuleWidgetBox module={component} /> : <WidgetBox index={index} component={component} />}
</div>
</>

View file

@ -44,10 +44,9 @@ export const useGhostMoveable = () => {
const relativeY = mousePosition.y - canvasRect.top;
// Apply grid snapping
const gridWidth = canvasRef.current.offsetWidth / NO_OF_GRIDS;
const snappedX = Math.round(relativeX / gridWidth) * gridWidth;
const snappedY = Math.round(relativeY / GRID_HEIGHT) * GRID_HEIGHT;
console.log(snappedX, snappedY);
// const gridWidth = canvasRef.current.offsetWidth / NO_OF_GRIDS;
// const snappedX = Math.round(relativeX / gridWidth) * gridWidth;
// const snappedY = Math.round(relativeY / GRID_HEIGHT) * GRID_HEIGHT;
ghostElementRef.current.style.transform = `translate(${relativeX}px, ${relativeY}px)`;
};
@ -95,25 +94,14 @@ export const useGhostMoveable = () => {
setVirtualTarget(null);
ghostElementRef.current.remove();
ghostElementRef.current = null;
// End any active drag operation first
// moveableInstance.dragEnd();
} catch (error) {
console.warn('Failed to trigger moveable dragEnd:', error);
}
}
};
// New function to update ghost position during continuous hover
const updateGhostOnHover = (mousePosition, canvasRef) => {
if (isActiveRef.current) {
updateGhostPosition(mousePosition, canvasRef);
}
};
return {
activateGhost,
deactivateGhost,
updateGhostOnHover, // New function for continuous updates
isActive: isActiveRef.current,
};
};

View file

@ -15,11 +15,12 @@ const initialState = {
moveableRef: null,
virtualTarget: null,
currentDragCanvasId: null,
ghostDragPosition: null,
};
export const useGridStore = create(
zustandDevTools(
(set) => ({
(set, get) => ({
...initialState,
actions: {
setResizingComponentId: (id) => set({ resizingComponentId: id }),
@ -31,6 +32,7 @@ export const useGridStore = create(
set((state) => ({ subContainerWidths: { ...state.subContainerWidths, [id]: width } })),
setVirtualTarget: (target) => set({ virtualTarget: target }),
setCurrentDragCanvasId: (canvasId) => set({ currentDragCanvasId: canvasId }),
setGhostDragPosition: (position) => set({ ghostDragPosition: position }),
},
addToElementGuidelines: (selector) =>
set((state) => ({
@ -42,6 +44,8 @@ export const useGridStore = create(
})),
clearDynamicElementGuidelines: () => set({ dynamicElementGuidelines: [] }),
setMoveableRef: (ref) => set({ moveableRef: ref }),
getGhostDragPosition: () => get().ghostDragPosition,
}),
{ name: 'Grid Store' }
)