Merge pull request #13272 from ToolJet/revert-13089-snapping-react-moveable

Revert "Add support to show guidelines on component drop"
This commit is contained in:
Johnson Cherian 2025-07-09 00:14:44 +05:30 committed by GitHub
commit 146bf83e67
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 301 additions and 630 deletions

View file

@ -10,9 +10,6 @@
],
"eslint.format.enable": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"json.schemas": [
{
"fileMatch": [

View file

@ -121,7 +121,7 @@
"react-loading-skeleton": "^3.1.1",
"react-markdown": "^9.0.0",
"react-mentions": "^4.4.7",
"react-moveable": "^0.56.0",
"react-moveable": "^0.54.1",
"react-multi-select-component": "^4.3.4",
"react-pdf": "^6.2.2",
"react-phone-input-2": "^2.15.1",
@ -30697,9 +30697,10 @@
}
},
"node_modules/react-moveable": {
"version": "0.56.0",
"resolved": "https://registry.npmjs.org/react-moveable/-/react-moveable-0.56.0.tgz",
"integrity": "sha512-FmJNmIOsOA36mdxbrc/huiE4wuXSRlmon/o+/OrfNhSiYYYL0AV5oObtPluEhb2Yr/7EfYWBHTxF5aWAvjg1SA==",
"version": "0.54.2",
"resolved": "https://registry.npmjs.org/react-moveable/-/react-moveable-0.54.2.tgz",
"integrity": "sha512-NGaVLbn0i9pb3+BWSKGWFqI/Mgm4+WMeWHxXXQ4Qi1tHxWCXrUrbGvpxEpt69G/hR7dez+/m68ex+fabjnvcUg==",
"license": "MIT",
"dependencies": {
"@daybrush/utils": "^1.13.0",
"@egjs/agent": "^2.2.1",
@ -30710,7 +30711,7 @@
"@scena/matrix": "^1.1.1",
"css-to-mat": "^1.1.1",
"framework-utils": "^1.1.0",
"gesto": "^1.19.3",
"gesto": "^1.19.0",
"overlap-area": "^1.1.0",
"react-css-styled": "^1.1.9",
"react-selecto": "^1.25.0"

View file

@ -116,7 +116,7 @@
"react-loading-skeleton": "^3.1.1",
"react-markdown": "^9.0.0",
"react-mentions": "^4.4.7",
"react-moveable": "^0.56.0",
"react-moveable": "^0.54.1",
"react-multi-select-component": "^4.3.4",
"react-pdf": "^6.2.2",
"react-phone-input-2": "^2.15.1",

View file

@ -4,17 +4,32 @@ import cx from 'classnames';
import WidgetWrapper from './WidgetWrapper';
import useStore from '@/AppBuilder/_stores/store';
import { shallow } from 'zustand/shallow';
import { useDrop, useDragLayer } from 'react-dnd';
import { computeViewerBackgroundColor, getSubContainerWidthAfterPadding } from './appCanvasUtils';
import { CANVAS_WIDTHS, NO_OF_GRIDS, GRID_HEIGHT } from './appCanvasConstants';
import { useDrop } from 'react-dnd';
import {
addChildrenWidgetsToParent,
addNewWidgetToTheEditor,
computeViewerBackgroundColor,
getSubContainerWidthAfterPadding,
addDefaultButtonIdToForm,
} from './appCanvasUtils';
import {
CANVAS_WIDTHS,
NO_OF_GRIDS,
WIDGETS_WITH_DEFAULT_CHILDREN,
GRID_HEIGHT,
CONTAINER_FORM_CANVAS_PADDING,
SUBCONTAINER_CANVAS_BORDER_WIDTH,
BOX_PADDING,
} from './appCanvasConstants';
import { useGridStore } from '@/_stores/gridStore';
import NoComponentCanvasContainer from './NoComponentCanvasContainer';
import { RIGHT_SIDE_BAR_TAB } from '../RightSideBar/rightSidebarConstants';
import { isPDFSupported } from '@/_helpers/appUtils';
import toast from 'react-hot-toast';
import { ModuleContainerBlank } from '@/modules/Modules/components';
import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
import useSortedComponents from '../_hooks/useSortedComponents';
import { useDropVirtualMoveableGhost } from '@/AppBuilder/_hooks/useDropVirtualMoveableGhost';
import { useCanvasDropHandler } from './useCanvasDropHandler';
import { findNewParentIdFromMousePosition } from './Grid/gridUtils';
import { noop } from 'lodash';
//TODO: Revisit the logic of height (dropRef)
@ -36,72 +51,112 @@ export const Container = React.memo(
columns,
darkMode,
canvasMaxWidth,
isViewerSidebarPinned,
pageSidebarStyle,
pagePositionType,
componentType,
appType,
}) => {
const { moduleId } = useModuleContext();
const realCanvasRef = useRef(null);
const components = useStore((state) => state.getContainerChildrenMapping(id, moduleId), shallow);
const addComponentToCurrentPage = useStore((state) => state.addComponentToCurrentPage, shallow);
const setActiveRightSideBarTab = useStore((state) => state.setActiveRightSideBarTab, shallow);
const setLastCanvasClickPosition = useStore((state) => state.setLastCanvasClickPosition, shallow);
const canvasBgColor = useStore(
(state) => (id === 'canvas' ? state.getCanvasBackgroundColor('canvas', darkMode) : ''),
shallow
);
const isPagesSidebarHidden = useStore((state) => state.getPagesSidebarVisibility('canvas'), shallow);
const currentMode = useStore((state) => state.modeStore.modules[moduleId].currentMode, shallow);
const currentLayout = useStore((state) => state.currentLayout, shallow);
const setFocusedParentId = useStore((state) => state.setFocusedParentId, shallow);
// Initialize ghost moveable hook
const { activateMoveableGhost, deactivateMoveableGhost } = useDropVirtualMoveableGhost();
// // Monitor drag layer to update ghost position continuously
const { isDragging } = useDragLayer((monitor) => ({
isDragging: monitor.isDragging(),
}));
// // // Cleanup ghost when drag ends
useEffect(() => {
if (!isDragging) {
deactivateMoveableGhost();
}
}, [id, isDragging, deactivateMoveableGhost]);
const setShowModuleBorder = useStore((state) => state.setShowModuleBorder, shallow) || noop;
const isContainerReadOnly = useMemo(() => {
return (index !== 0 && (componentType === 'Listview' || componentType === 'Kanban')) || currentMode === 'view';
}, [index, componentType, currentMode]);
const setCurrentDragCanvasId = useGridStore((state) => state.actions.setCurrentDragCanvasId);
const { handleDrop } = useCanvasDropHandler({
appType,
});
const [{ isOverCurrent }, drop] = useDrop({
accept: 'box',
hover: (item, monitor) => {
const clientOffset = monitor.getClientOffset();
hover: (item) => {
item.canvasRef = realCanvasRef?.current;
item.canvasId = id;
item.canvasWidth = getContainerCanvasWidth();
},
drop: async ({ componentType, component }, monitor) => {
setShowModuleBorder(false);
if (currentMode === 'view' || (appType === 'module' && componentType !== 'ModuleContainer')) return;
const appCanvasWidth = realCanvasRef?.current?.offsetWidth || 0;
const didDrop = monitor.didDrop();
if (didDrop) return;
if (clientOffset) {
const canvasId = findNewParentIdFromMousePosition(clientOffset.x, clientOffset.y, id);
if (canvasId === id) {
setCurrentDragCanvasId(id);
const moduleInfo = component?.moduleId
? {
moduleId: component.moduleId,
versionId: component.versionId,
environmentId: component.environmentId,
moduleName: component.displayName,
moduleContainer: component.moduleContainer,
}
: undefined;
let addedComponent;
if (WIDGETS_WITH_DEFAULT_CHILDREN.includes(componentType)) {
let parentComponent = addNewWidgetToTheEditor(
componentType,
monitor,
currentLayout,
realCanvasRef,
id,
moduleInfo
);
const childComponents = addChildrenWidgetsToParent(componentType, parentComponent?.id, currentLayout);
if (componentType === 'Form') {
parentComponent = addDefaultButtonIdToForm(parentComponent, childComponents);
}
addedComponent = [parentComponent, ...childComponents];
await addComponentToCurrentPage(addedComponent);
} else {
const newComponent = addNewWidgetToTheEditor(
componentType,
monitor,
currentLayout,
realCanvasRef,
id,
moduleInfo
);
addedComponent = [newComponent];
await addComponentToCurrentPage(addedComponent);
}
// Calculate width based on the app canvas's grid
let width = (appCanvasWidth * item.component?.defaultSize?.width) / NO_OF_GRIDS;
const componentSize = {
width,
height: item.component?.defaultSize?.height,
};
if (clientOffset && id === 'canvas') {
activateMoveableGhost(componentSize, clientOffset, realCanvasRef);
setActiveRightSideBarTab(RIGHT_SIDE_BAR_TAB.CONFIGURATION);
const canvas = document.querySelector('.canvas-container');
const sidebar = document.querySelector('.editor-sidebar');
const droppedElem = document.getElementById(addedComponent?.[0]?.id);
if (!canvas || !sidebar || !droppedElem) return;
const droppedRect = droppedElem.getBoundingClientRect();
const sidebarRect = sidebar.getBoundingClientRect();
const isOverlapping = droppedRect.right > sidebarRect.left && droppedRect.left < sidebarRect.right;
if (isOverlapping) {
const overlap = droppedRect.right - sidebarRect.left;
canvas.scrollTo({
left: canvas.scrollLeft + overlap,
behavior: 'smooth',
});
}
},
drop: (item, monitor) => {
handleDrop(item, id);
},
collect: (monitor) => ({
isOverCurrent: monitor.isOver({ shallow: true }),
}),
});
const showEmptyContainer =
@ -120,12 +175,34 @@ export const Container = React.memo(
}
const gridWidth = getContainerCanvasWidth() / NO_OF_GRIDS;
useEffect(() => {
useGridStore.getState().actions.setSubContainerWidths(id, gridWidth);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [canvasWidth, listViewMode, columns]);
const getCanvasWidth = useCallback(() => {
// if (
// id === 'canvas' &&
// !isPagesSidebarHidden &&
// isViewerSidebarPinned &&
// currentLayout !== 'mobile' &&
// pagePositionType == 'side' &&
// appType !== 'module'
// ) {
// return `calc(100% - ${pageSidebarStyle === 'icon' ? '85px' : '226px'})`;
// }
// if (
// id === 'canvas' &&
// !isPagesSidebarHidden &&
// !isViewerSidebarPinned &&
// currentLayout !== 'mobile' &&
// pagePositionType == 'side'
// ) {
// return `calc(100% - ${'44px'})`;
// }
return '100%';
}, [id, isPagesSidebarHidden, isViewerSidebarPinned, currentLayout, pagePositionType, pageSidebarStyle]);
const handleCanvasClick = useCallback(
(e) => {
const realCanvas = e.target.closest('.real-canvas');
@ -174,8 +251,8 @@ export const Container = React.memo(
currentMode === 'view'
? computeViewerBackgroundColor(darkMode, canvasBgColor)
: id === 'canvas'
? canvasBgColor
: '#f0f0f0',
? canvasBgColor
: '#f0f0f0',
width: '100%',
maxWidth: (() => {
// For Main Canvas

View file

@ -1,5 +1,5 @@
// import '@/Editor/wdyr';
import React, { useEffect, useState, useRef, useCallback, useMemo } from 'react';
import React, { useEffect, useState, useRef, useCallback } from 'react';
// eslint-disable-next-line import/no-unresolved
import Moveable from 'react-moveable';
import { shallow } from 'zustand/shallow';
@ -10,8 +10,10 @@ import { useGridStore, useIsGroupHandleHoverd, useOpenModalWidgetId } from '@/_s
import toast from 'react-hot-toast';
import {
individualGroupableProps,
getMouseDistanceFromParentDiv,
findChildrenAndGrandchildren,
findHighestLevelofSelection,
getOffset,
hasParentWithClass,
getPositionForGroupDrag,
adjustWidth,
@ -23,8 +25,7 @@ import {
computeScrollDelta,
computeScrollDeltaOnDrag,
getDraggingWidgetWidth,
positionGhostElement,
findNewParentIdFromMousePosition,
positionDragGhostWidget,
} from './gridUtils';
import { dragContextBuilder, getAdjustedDropPosition } from './helpers/dragEnd';
import useStore from '@/AppBuilder/_stores/store';
@ -32,8 +33,6 @@ import './Grid.css';
import { useGroupedTargetsScrollHandler } from './hooks/useGroupedTargetsScrollHandler';
import { DROPPABLE_PARENTS, NO_OF_GRIDS, SUBCONTAINER_WIDGETS } from '../appCanvasConstants';
import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
import { useElementGudelines } from './hooks/useElementGudelines';
const CANVAS_BOUNDS = { left: 0, top: 0, right: 0, position: 'css' };
const RESIZABLE_CONFIG = {
edge: ['nw', 'n', 'ne', 'w', 'e', 'sw', 's', 'se'],
@ -74,15 +73,10 @@ export default function Grid({ gridWidth, currentLayout }) {
const getTemporaryLayouts = useStore((state) => state.getTemporaryLayouts, shallow);
const updateContainerAutoHeight = useStore((state) => state.updateContainerAutoHeight, shallow);
const [canvasBounds, setCanvasBounds] = useState(CANVAS_BOUNDS);
const draggingComponentId = useGridStore((state) => state.draggingComponentId, shallow);
const resizingComponentId = useGridStore((state) => state.resizingComponentId, shallow);
const [dragParentId, setDragParentId] = useState(null);
const virtualTarget = useGridStore((state) => state.virtualTarget, shallow);
const { elementGuidelines } = useElementGudelines(
boxList,
selectedComponents,
dragParentId,
getResolvedValue,
virtualTarget
);
const [elementGuidelines, setElementGuidelines] = useState([]);
const componentsSnappedTo = useRef(null);
const prevDragParentId = useRef(null);
const newDragParentId = useRef(null);
@ -90,39 +84,42 @@ export default function Grid({ gridWidth, currentLayout }) {
const checkIfAnyWidgetVisibilityChanged = useStore((state) => state.checkIfAnyWidgetVisibilityChanged(), shallow);
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 [isVerticalExpansionRestricted, setIsVerticalExpansionRestricted] = useState(false);
const toggleRightSidebar = useStore((state) => state.toggleRightSidebar, shallow);
const draggingComponentId = useStore((state) => state.draggingComponentId, shallow);
const resizingComponentId = useStore((state) => state.resizingComponentId, shallow);
const snapContainer = useMemo(() => {
if (currentDragCanvasId) {
return `#canvas-${currentDragCanvasId}`;
}
if (dragParentId) {
return `#canvas-${dragParentId}`;
}
return '#real-canvas';
}, [currentDragCanvasId, dragParentId]);
const getMoveableTarget = () => {
if (virtualTarget) {
return '#moveable-ghost-element';
}
return groupedTargets?.length > 1 ? groupedTargets : '.target';
};
// Set moveable reference in grid store for access by other components
useEffect(() => {
if (moveableRef.current) {
useGridStore.getState().setMoveableRef(moveableRef.current);
}
return () => {
useGridStore.getState().setMoveableRef(null);
};
}, []);
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(
@ -344,12 +341,13 @@ export default function Grid({ gridWidth, currentLayout }) {
});
}, [selectedComponents]);
const groupedTargets = [...findHighestLevelofSelection().map((component) => '.ele-' + component.id)];
useEffect(() => {
if (moveableRef.current) {
moveableRef.current.updateTarget();
}
}, [temporaryHeight]);
useEffect(() => {
reloadGrid();
// eslint-disable-next-line react-hooks/exhaustive-deps
@ -536,8 +534,9 @@ export default function Grid({ gridWidth, currentLayout }) {
const _top = originalBox.top;
// Apply transform to return to original position
ev.target.style.transform = `translate(${Math.round(_left / _gridWidth) * _gridWidth}px, ${Math.round(_top / GRID_HEIGHT) * GRID_HEIGHT
}px)`;
ev.target.style.transform = `translate(${Math.round(_left / _gridWidth) * _gridWidth}px, ${
Math.round(_top / GRID_HEIGHT) * GRID_HEIGHT
}px)`;
}
});
@ -600,16 +599,18 @@ export default function Grid({ gridWidth, currentLayout }) {
const components = Array.from(document.querySelectorAll('.active-target')).filter(
(component) => !selectedComponents.includes(component.getAttribute('widgetid'))
);
const draggingOrResizingComponentId = draggingComponentId || resizingComponentId;
if (!draggingOrResizingComponentId && components.length > 0 && !virtualTarget) {
const draggingOrResizing = draggingComponentId || resizingComponentId;
if (!draggingOrResizing && components.length > 0) {
for (const component of components) {
component?.classList?.remove('active-target');
}
}
}, [draggingComponentId, resizingComponentId, isGroupDragging, selectedComponents, virtualTarget]);
}, [draggingComponentId, resizingComponentId, isGroupDragging, selectedComponents]);
useGroupedTargetsScrollHandler(groupedTargets, boxList, moveableRef);
if (mode !== 'edit') return null;
return (
<>
<Moveable
@ -622,9 +623,9 @@ export default function Grid({ gridWidth, currentLayout }) {
multiComponentHandle: groupedTargets.length > 1,
}}
flushSync={flushSync}
target={getMoveableTarget()}
target={groupedTargets?.length > 1 ? groupedTargets : '.target'}
origin={false}
individualGroupable={virtualTarget ? false : groupedTargets.length <= 1}
individualGroupable={groupedTargets.length <= 1}
draggable={!shouldFreeze && mode !== 'view'}
resizable={
!shouldFreeze
@ -638,7 +639,7 @@ export default function Grid({ gridWidth, currentLayout }) {
onResize={(e) => {
const temporaryLayouts = getTemporaryLayouts();
if (resizingComponentId !== e.target.id) {
useStore.getState().setResizingComponentId(e.target.id);
useGridStore.getState().actions.setResizingComponentId(e.target.id);
showGridLines();
}
@ -647,8 +648,12 @@ export default function Grid({ gridWidth, currentLayout }) {
let _gridWidth = useGridStore.getState().subContainerWidths[currentWidget.component?.parent] || gridWidth;
// Show grid during resize
showGridLines();
if (currentWidget.component?.parent) {
document.getElementById('canvas-' + currentWidget.component?.parent)?.classList.add('show-grid');
setDragParentId(currentWidget.component?.parent);
} else {
document.getElementById('real-canvas').classList.add('show-grid');
}
handleActivateTargets(currentWidget.component?.parent);
const currentWidth = currentWidget.width * _gridWidth;
@ -692,7 +697,6 @@ export default function Grid({ gridWidth, currentLayout }) {
e.target.style.transform = `translate(${transformX}px, ${transformY}px)`;
if (e.width > 0) e.target.style.width = `${e.width}px`;
if (e.height > 0) e.target.style.height = `${e.height}px`;
positionGhostElement(e.target, 'resize-ghost-widget');
}}
onResizeStart={(e) => {
if (
@ -711,7 +715,7 @@ export default function Grid({ gridWidth, currentLayout }) {
}}
onResizeEnd={(e) => {
try {
useStore.getState().setResizingComponentId(null);
useGridStore.getState().actions.setResizingComponentId(null);
const currentWidget = boxList.find(({ id }) => {
return id === e.target.id;
});
@ -748,8 +752,9 @@ export default function Grid({ gridWidth, currentLayout }) {
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 / GRID_HEIGHT) * GRID_HEIGHT
}px)`;
e.target.style.transform = `translate(${Math.round(transformX / _gridWidth) * _gridWidth}px, ${
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`;
}
@ -862,9 +867,6 @@ export default function Grid({ gridWidth, currentLayout }) {
}}
checkInput
onDragStart={(e) => {
if (e.target.id === 'moveable-ghost-element') {
return true;
}
// This is to prevent parent component from being dragged and the stop the propagation of the event
if (getHoveredComponentForGrid() !== e.target.id) {
return false;
@ -917,9 +919,6 @@ export default function Grid({ gridWidth, currentLayout }) {
}}
onDragEnd={(e) => {
handleDeactivateTargets();
if (e.target.id === 'moveable-ghost-element') {
return;
}
try {
if (isDraggingRef.current) {
useStore.getState().setDraggingComponentId(null);
@ -932,6 +931,7 @@ export default function Grid({ gridWidth, currentLayout }) {
setDragParentId(null);
if (!e.lastEvent) return;
// Build the drag context from the event
const dragContext = dragContextBuilder({ event: e, widgets: boxList, isModuleEditor });
const { target, source, dragged } = dragContext;
@ -978,21 +978,6 @@ export default function Grid({ gridWidth, currentLayout }) {
toggleCanvasUpdater();
}}
onDrag={(e) => {
if (e.target.id === 'moveable-ghost-element') {
showGridLines();
const _gridWidth = useGridStore.getState().subContainerWidths[currentDragCanvasId] || gridWidth;
let left = e.translate[0];
let top = e.translate[1];
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;
}
// Since onDrag is called multiple times when dragging, hence we are using isDraggingRef to prevent setting state again and again
if (!isDraggingRef.current) {
useStore.getState().setDraggingComponentId(e.target.id);
@ -1061,7 +1046,16 @@ export default function Grid({ gridWidth, currentLayout }) {
// 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)) {
let newParentId = findNewParentIdFromMousePosition(e.clientX, e.clientY, e.target.id);
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;
@ -1089,7 +1083,7 @@ export default function Grid({ gridWidth, currentLayout }) {
`translate: ${e.translate[0]} | Round: ${Math.round(e.translate[0] / gridWidth) * gridWidth} | ${gridWidth}`
);
positionGhostElement(e.target, 'moveable-drag-ghost');
positionDragGhostWidget(e.target);
}}
onDragGroup={(ev) => {
const { events } = ev;
@ -1172,10 +1166,8 @@ export default function Grid({ gridWidth, currentLayout }) {
component.element.classList.add('active-target');
}
}}
// snapGridAll={true}
snapGridAll={true}
scrollable={true}
// snapContainer={snapContainer}
// snapGridWidth={100}
/>
</>
);

View file

@ -530,58 +530,24 @@ export const getDraggingWidgetWidth = (canvasParentId, widgetWidth) => {
return draggingWidgetWidth;
};
/**
* Positions a ghost/feedback element relative to the main canvas
* @param {HTMLElement} targetElement - The element being dragged/resized
* @param {string} ghostElementId - The ID of the ghost element to position
* @param {Object} options - Additional positioning options
* @param {boolean} options.includeSize - Whether to update width/height of ghost element
*/
export const positionGhostElement = (targetElement, ghostElementId) => {
const ghostElement = document.getElementById(ghostElementId);
export const positionDragGhostWidget = (draggedElement) => {
const ghostElement = document.getElementById('moveable-drag-ghost');
if (!ghostElement || !targetElement) return;
if (!ghostElement || !draggedElement) return;
const mainCanvas = document.getElementById('real-canvas');
if (!mainCanvas) return;
const mainCanvasRect = mainCanvas.getBoundingClientRect();
const targetRect = targetElement.getBoundingClientRect();
const draggedRect = draggedElement.getBoundingClientRect();
// Calculate position relative to main canvas
const relativeLeft = targetRect.left - mainCanvasRect.left;
const relativeTop = targetRect.top - mainCanvasRect.top;
const relativeLeft = draggedRect.left - mainCanvasRect.left;
const relativeTop = draggedRect.top - mainCanvasRect.top;
// Apply the position
ghostElement.style.left = `${relativeLeft}px`;
ghostElement.style.top = `${relativeTop}px`;
ghostElement.style.width = `${targetRect.width}px`;
ghostElement.style.height = `${targetRect.height}px`;
};
/**
* Finds the new parent ID based on the current mouse position during drag operations
* @param {number} clientX - The X coordinate of the mouse position
* @param {number} clientY - The Y coordinate of the mouse position
* @param {string} currentTargetId - The ID of the currently dragged element to exclude from search
* @returns {string|null} - The new parent ID or null if no valid parent is found
*/
export const findNewParentIdFromMousePosition = (clientX, clientY, currentTargetId) => {
if (!document.elementFromPoint(clientX, clientY)) {
return null;
}
const targetElems = document.elementsFromPoint(clientX, clientY);
const draggedOverElements = targetElems.filter(
(ele) => (ele.id !== currentTargetId && 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
const newParentId = draggedOverContainer?.getAttribute('data-parentId') || draggedOverElem?.id;
return newParentId || null;
ghostElement.style.width = `${draggedRect.width}px`;
ghostElement.style.height = `${draggedRect.height}px`;
};

View file

@ -1,72 +0,0 @@
import { useEffect, useState } from 'react';
import { findHighestLevelofSelection } from '../gridUtils';
import { useGridStore } from '@/_stores/gridStore';
import useStore from '@/AppBuilder/_stores/store';
export const useElementGudelines = (boxList, selectedComponents, dragParentId, getResolvedValue, virtualTarget) => {
const [elementGuidelines, setElementGuidelines] = useState([]);
const draggingComponentId = useStore((state) => state.draggingComponentId);
const resizingComponentId = useStore((state) => state.resizingComponentId);
const currentDragCanvasId = useGridStore((state) => state.currentDragCanvasId);
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 isAnyModalOpen = document.querySelector('#modal-container') ? true : false;
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;
// Don't show guidelines for components which are outside the modal specially on main canvas
if (virtualTarget && isAnyModalOpen) {
if (box.parent === 'canvas' || !box.parent) return false;
}
// This block is for first time drop using react-dnd
if (virtualTarget && currentDragCanvasId !== null) {
if (currentDragCanvasId === 'canvas') {
if (box.parent && box.parent !== 'canvas') return false;
} else {
// For sub-containers, only show components whose parent matches the canvasId
if (box.parent !== currentDragCanvasId) 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,
currentDragCanvasId,
virtualTarget,
]);
return { elementGuidelines };
};

View file

@ -1,8 +1,9 @@
import React, { memo } from 'react';
import useStore from '@/AppBuilder/_stores/store';
import { shallow } from 'zustand/shallow';
import { ResizeGhostWidget } from './GhostWidgets';
import { DragGhostWidget, ResizeGhostWidget } from './GhostWidgets';
import { ConfigHandle } from './ConfigHandle/ConfigHandle';
import { useGridStore } from '@/_stores/gridStore';
import cx from 'classnames';
import RenderWidget from './RenderWidget';
import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
@ -34,7 +35,7 @@ const WidgetWrapper = memo(
const temporaryLayouts = useStore((state) => state.temporaryLayouts?.[id], shallow);
const isWidgetActive = useStore((state) => state.selectedComponents.find((sc) => sc === id) && !readOnly, shallow);
const isDragging = useStore((state) => state.draggingComponentId === id);
const isResizing = useStore((state) => state.resizingComponentId === id);
const isResizing = useGridStore((state) => state.resizingComponentId === id);
const componentType = useStore(
(state) => state.getComponentDefinition(id, moduleId)?.component?.component,
shallow

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, getMouseDistanceFromParentDiv } from './Grid/gridUtils';
import { findHighestLevelofSelection } from './Grid/gridUtils';
import {
CANVAS_WIDTHS,
NO_OF_GRIDS,
@ -29,32 +29,32 @@ export function snapToGrid(canvasWidth, x, y) {
//TODO: componentTypes should be a key value pair and get the definition directly by passing the componentType
export const addNewWidgetToTheEditor = (
componentType,
eventMonitorObject,
currentLayout,
realCanvasRef,
parentId,
moduleInfo = undefined
) => {
const canvasBoundingRect = realCanvasRef?.getBoundingClientRect();
const canvasBoundingRect = realCanvasRef?.current?.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 { e } = useGridStore.getState().getGhostDragPosition();
const offsetFromTopOfWindow = canvasBoundingRect?.top;
const offsetFromLeftOfWindow = canvasBoundingRect?.left;
const currentOffset = eventMonitorObject?.getSourceClientOffset();
const subContainerWidth = canvasBoundingRect?.width;
const { left: _left, top: _top } = getMouseDistanceFromParentDiv(
e,
parentId === 'canvas' ? 'real-canvas' : parentId,
parentCanvasType
);
let [left, top] = snapToGrid(subContainerWidth, _left, _top);
let left = Math.round(currentOffset?.x - offsetFromLeftOfWindow);
let top = Math.round(currentOffset?.y - offsetFromTopOfWindow);
[left, top] = snapToGrid(subContainerWidth, left, top);
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);
@ -85,7 +85,6 @@ export const addNewWidgetToTheEditor = (
left = Math.max(0, NO_OF_GRIDS - width);
width = Math.min(width, NO_OF_GRIDS);
}
if (currentLayout === 'mobile') {
componentData.definition.others.showOnDesktop.value = `{{false}}`;
componentData.definition.others.showOnMobile.value = `{{true}}`;

View file

@ -1,113 +0,0 @@
import useStore from '@/AppBuilder/_stores/store';
import { useGridStore } from '@/_stores/gridStore';
import { shallow } from 'zustand/shallow';
import { noop } from 'lodash';
import {
addChildrenWidgetsToParent,
addNewWidgetToTheEditor,
addDefaultButtonIdToForm,
} from '../AppCanvas/appCanvasUtils';
import { WIDGETS_WITH_DEFAULT_CHILDREN } from '../AppCanvas/appCanvasConstants';
import { RIGHT_SIDE_BAR_TAB } from '../RightSideBar/rightSidebarConstants';
import { isPDFSupported } from '@/_helpers/appUtils';
import toast from 'react-hot-toast';
import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
import { handleDeactivateTargets, hideGridLines } from '../AppCanvas/Grid/gridUtils';
export const useCanvasDropHandler = ({ appType }) => {
const { moduleId } = useModuleContext();
const addComponentToCurrentPage = useStore((state) => state.addComponentToCurrentPage, shallow);
const setActiveRightSideBarTab = useStore((state) => state.setActiveRightSideBarTab, shallow);
const setShowModuleBorder = useStore((state) => state.setShowModuleBorder, shallow) || noop;
const currentMode = useStore((state) => state.modeStore.modules[moduleId].currentMode, shallow);
const currentLayout = useStore((state) => state.currentLayout, shallow);
const setCurrentDragCanvasId = useGridStore((state) => state.actions.setCurrentDragCanvasId);
const handleDrop = async ({ componentType: draggedComponentType, component }, canvasId) => {
const realCanvasRef =
!canvasId || canvasId === 'canvas'
? document.getElementById(`real-canvas`)
: document.getElementById(`canvas-${canvasId}`);
handleDeactivateTargets();
hideGridLines();
setShowModuleBorder(false); // Hide the module border when dropping
if (currentMode === 'view' || (appType === 'module' && draggedComponentType !== 'ModuleContainer')) {
return;
}
if (draggedComponentType === 'PDF' && !isPDFSupported()) {
toast.error(
'PDF is not supported in this version of browser. We recommend upgrading to the latest version for full support.'
);
return;
}
// IMPORTANT: This logic needs to be changed when we implement the module versioning
const moduleInfo = component?.moduleId
? {
moduleId: component.moduleId,
versionId: component.versionId,
environmentId: component.environmentId,
moduleName: component.displayName,
moduleContainer: component.moduleContainer,
}
: undefined;
let addedComponent;
if (WIDGETS_WITH_DEFAULT_CHILDREN.includes(draggedComponentType)) {
let parentComponent = addNewWidgetToTheEditor(
draggedComponentType,
currentLayout,
realCanvasRef,
canvasId,
moduleInfo
);
const childComponents = addChildrenWidgetsToParent(draggedComponentType, parentComponent?.id, currentLayout);
if (draggedComponentType === 'Form') {
parentComponent = addDefaultButtonIdToForm(parentComponent, childComponents);
}
addedComponent = [parentComponent, ...childComponents];
await addComponentToCurrentPage(addedComponent);
} else {
const newComponent = addNewWidgetToTheEditor(
draggedComponentType,
currentLayout,
realCanvasRef,
canvasId,
moduleInfo
);
addedComponent = [newComponent];
await addComponentToCurrentPage(addedComponent);
}
setActiveRightSideBarTab(RIGHT_SIDE_BAR_TAB.CONFIGURATION);
const canvas = document.querySelector('.canvas-container');
const sidebar = document.querySelector('.editor-sidebar');
const droppedElem = document.getElementById(addedComponent?.[0]?.id);
if (!canvas || !sidebar || !droppedElem) return;
const droppedRect = droppedElem.getBoundingClientRect();
const sidebarRect = sidebar.getBoundingClientRect();
const isOverlapping = droppedRect.right > sidebarRect.left && droppedRect.left < sidebarRect.right;
if (isOverlapping) {
const overlap = droppedRect.right - sidebarRect.left;
canvas.scrollTo({
left: canvas.scrollLeft + overlap,
behavior: 'smooth',
});
}
// Reset canvas ID when dropping
setCurrentDragCanvasId(null);
};
return { handleDrop };
};

View file

@ -1,4 +1,4 @@
import React, { useEffect, useRef } from 'react';
import React, { useEffect } from 'react';
import { WidgetBox } from '../WidgetBox';
import { ModuleWidgetBox } from '@/modules/Modules/components';
import { useDrag, useDragLayer } from 'react-dnd';
@ -9,8 +9,6 @@ import useStore from '@/AppBuilder/_stores/store';
import { shallow } from 'zustand/shallow';
import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext';
import { noop } from 'lodash';
import { useGridStore } from '@/_stores/gridStore';
import { useCanvasDropHandler } from '@/AppBuilder/AppCanvas/useCanvasDropHandler';
export const DragLayer = ({ index, component, isModuleTab = false, disabled = false }) => {
const [isRightSidebarOpen, toggleRightSidebar] = useStore(
@ -20,20 +18,11 @@ export const DragLayer = ({ index, component, isModuleTab = false, disabled = fa
const isRightSidebarPinned = useStore((state) => state.isRightSidebarPinned);
const { isModuleEditor } = useModuleContext();
const setShowModuleBorder = useStore((state) => state.setShowModuleBorder, shallow) || noop;
const { handleDrop } = useCanvasDropHandler({ appType: isModuleTab ? 'module' : 'app' }) || noop;
const [{ isDragging }, drag, preview] = useDrag(
() => ({
type: 'box',
item: { componentType: component.component, component },
collect: (monitor) => ({ isDragging: monitor.isDragging() }),
end: (item, monitor) => {
const clientOffset = monitor.getClientOffset();
const currentDragCanvasId = useGridStore.getState().currentDragCanvasId;
if (clientOffset) {
handleDrop(item, currentDragCanvasId);
}
},
}),
[component.component]
);
@ -57,14 +46,80 @@ export const DragLayer = ({ index, component, isModuleTab = false, disabled = fa
// ? component.module_container.layouts[currentLayout]
// : component.defaultSize || { width: 30, height: 40 };
const size = component.defaultSize || { width: 30, height: 40 };
return (
<>
{isDragging && <CustomDragLayer size={size} />}
<div
ref={disabled ? undefined : drag}
className={`draggable-box${disabled ? ' disabled' : ''}`}
style={{ height: '100%', width: isModuleTab && '100%' }}>
{isModuleTab ? <ModuleWidgetBox module={component} /> : <WidgetBox index={index} component={component} />}
style={{ height: '100%', width: isModuleTab && '100%' }}
>
{isModuleTab ? (
<ModuleWidgetBox module={component} disabled={disabled} />
) : (
<WidgetBox index={index} component={component} />
)}
</div>
</>
);
};
};
const CustomDragLayer = ({ size }) => {
const { currentOffset, item } = useDragLayer((monitor) => ({
currentOffset: monitor.getSourceClientOffset(),
item: monitor.getItem(),
}));
console.log(currentOffset, 'currentOffset');
if (!currentOffset) return null;
const canvasWidth = item?.canvasWidth;
const canvasBounds = item?.canvasRef?.getBoundingClientRect();
const height = size.height;
const appCanvasWidth = document.getElementById('real-canvas')?.offsetWidth || 0;
// Calculate width based on the app canvas's grid
let width = (appCanvasWidth * 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);
// Ensure width doesn't exceed the current container's width
if (width > canvasWidth) {
width = canvasWidth;
}
// Snap width to grid (round to nearest grid unit)
const gridUnitWidth = canvasWidth / NO_OF_GRIDS;
const gridUnits = Math.round(width / gridUnitWidth);
width = gridUnits * gridUnitWidth;
const [x, y] = snapToGrid(canvasWidth, left, top);
return (
<div
style={{
position: 'fixed',
pointerEvents: 'none',
left: canvasBounds?.left || 0,
top: canvasBounds?.top || 0,
height: `${height}px`,
width: `${width}px`,
zIndex: -1,
}}
>
<div
style={{
transform: `translate(${x}px, ${y}px)`,
background: '#D9E2FC',
opacity: '0.7',
height: '100%',
width: '100%',
outline: '1px solid #4af',
}}
></div>
</div>
);
};

View file

@ -1,101 +0,0 @@
import { useRef } from 'react';
import { useGridStore } from '@/_stores/gridStore';
export const useDropVirtualMoveableGhost = () => {
const ghostElementRef = useRef(null);
const isActiveRef = useRef(false);
const getMoveableRef = useGridStore((state) => state.moveableRef);
const setVirtualTarget = useGridStore((state) => state.actions.setVirtualTarget);
const createGhostMoveElement = (componentSize) => {
if (ghostElementRef.current) return;
const ghost = document.createElement('div');
ghost.id = 'moveable-ghost-element';
ghost.className = 'moveable-ghost target';
ghost.style.cssText = `
position: absolute;
width: ${componentSize.width || 100}px;
height: ${componentSize.height || 40}px;
background: #D9E2FC;
opacity: 0.7;
pointer-events: none;
z-index: 9998;
box-sizing: border-box;
top: 0;
left: 0;
`;
const container = document.getElementById('real-canvas');
container.appendChild(ghost);
ghostElementRef.current = ghost;
return ghost;
};
const updateMoveableGhostPosition = (mousePosition, canvasRef) => {
if (!ghostElementRef.current || !canvasRef?.current || !mousePosition) return;
const canvasRect = canvasRef.current.getBoundingClientRect();
const relativeX = mousePosition.x - canvasRect.left;
const relativeY = mousePosition.y - canvasRect.top;
ghostElementRef.current.style.transform = `translate(${relativeX}px, ${relativeY}px)`;
};
const activateMoveableGhost = (componentSize, mousePosition, canvasRef) => {
if (isActiveRef.current) return;
isActiveRef.current = true;
const ghost = createGhostMoveElement(componentSize, canvasRef);
if (ghost && mousePosition) {
updateMoveableGhostPosition(mousePosition, canvasRef);
// Trigger moveable drag on the ghost element to show guidelines
const moveableInstance = getMoveableRef;
if (moveableInstance && ghost) {
try {
const fakeEvent = new MouseEvent('mousedown', {
clientX: mousePosition.x,
clientY: mousePosition.y,
bubbles: true,
cancelable: true,
view: window,
button: 0,
buttons: 1,
});
moveableInstance.waitToChangeTarget().then((e) => {
moveableInstance.dragStart(fakeEvent, ghost);
});
setVirtualTarget(ghost);
} catch (error) {
console.warn('Failed to trigger moveable dragStart:', error);
}
}
}
};
const deactivateMoveableGhost = () => {
if (!isActiveRef.current) return;
isActiveRef.current = false;
const moveableInstance = getMoveableRef;
if (moveableInstance && ghostElementRef.current) {
try {
setVirtualTarget(null);
ghostElementRef.current.remove();
ghostElementRef.current = null;
} catch (error) {
console.warn('Failed to trigger moveable dragEnd:', error);
}
}
};
return {
activateMoveableGhost,
deactivateMoveableGhost,
};
};

View file

@ -1,107 +0,0 @@
import { useRef } from 'react';
import { useGridStore } from '@/_stores/gridStore';
import { NO_OF_GRIDS, GRID_HEIGHT } from '@/AppBuilder/AppCanvas/appCanvasConstants';
import { snapToGrid } from '@/AppBuilder/AppCanvas/appCanvasUtils';
export const useGhostMoveable = () => {
const ghostElementRef = useRef(null);
const isActiveRef = useRef(false);
const getMoveableRef = useGridStore((state) => state.moveableRef);
const setVirtualTarget = useGridStore((state) => state.actions.setVirtualTarget);
const createGhostElement = (componentSize) => {
if (ghostElementRef.current) return;
const ghost = document.createElement('div');
ghost.id = 'moveable-ghost-element';
ghost.className = 'moveable-ghost target';
ghost.style.cssText = `
position: absolute;
width: ${componentSize.width || 100}px;
height: ${componentSize.height || 40}px;
background: #D9E2FC;
opacity: 0.7;
pointer-events: none;
z-index: 9998;
box-sizing: border-box;
top: 0;
left: 0;
`;
const container = document.getElementById('real-canvas');
container.appendChild(ghost);
ghostElementRef.current = ghost;
return ghost;
};
const updateGhostPosition = (mousePosition, canvasRef) => {
if (!ghostElementRef.current || !canvasRef?.current || !mousePosition) return;
const canvasRect = canvasRef.current.getBoundingClientRect();
const relativeX = mousePosition.x - canvasRect.left;
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;
ghostElementRef.current.style.transform = `translate(${relativeX}px, ${relativeY}px)`;
};
const activateGhost = (componentSize, mousePosition, canvasRef) => {
if (isActiveRef.current) return;
isActiveRef.current = true;
const ghost = createGhostElement(componentSize, canvasRef);
if (ghost && mousePosition) {
updateGhostPosition(mousePosition, canvasRef);
// Trigger moveable drag on the ghost element to show guidelines
const moveableInstance = getMoveableRef;
if (moveableInstance && ghost) {
try {
const fakeEvent = new MouseEvent('mousedown', {
clientX: mousePosition.x,
clientY: mousePosition.y,
bubbles: true,
cancelable: true,
view: window,
button: 0,
buttons: 1,
});
moveableInstance.waitToChangeTarget().then((e) => {
moveableInstance.dragStart(fakeEvent, ghost);
});
setVirtualTarget(ghost);
} catch (error) {
console.warn('Failed to trigger moveable dragStart:', error);
}
}
}
};
const deactivateGhost = () => {
if (!isActiveRef.current) return;
isActiveRef.current = false;
const moveableInstance = getMoveableRef;
if (moveableInstance && ghostElementRef.current) {
try {
setVirtualTarget(null);
ghostElementRef.current.remove();
ghostElementRef.current = null;
} catch (error) {
console.warn('Failed to trigger moveable dragEnd:', error);
}
}
};
return {
activateGhost,
deactivateGhost,
};
};

View file

@ -10,12 +10,10 @@ const initialState = {
lastCanvasClickPosition: null,
temporaryLayouts: {},
draggingComponentId: null,
resizingComponentId: null,
reorderContainerChildren: {
containerId: null,
triggerUpdate: 0,
},
shouldPreventDrop: false,
};
export const createGridSlice = (set, get) => ({
@ -37,7 +35,6 @@ export const createGridSlice = (set, get) => ({
get().toggleCanvasUpdater();
}, 200),
setDraggingComponentId: (id) => set(() => ({ draggingComponentId: id })),
setResizingComponentId: (id) => set(() => ({ resizingComponentId: id })),
moveComponentPosition: (direction) => {
const { setComponentLayout, currentLayout, getSelectedComponentsDefinition, debouncedToggleCanvasUpdater } = get();
let layouts = {};
@ -473,7 +470,4 @@ export const createGridSlice = (set, get) => ({
reorderContainerChildren: { containerId, triggerUpdate: state.reorderContainerChildren.triggerUpdate + 1 },
}));
},
setShouldPreventDrop: (shouldPreventDrop) => {
set(() => ({ shouldPreventDrop }));
},
});

View file

@ -12,15 +12,11 @@ const initialState = {
idGroupDragged: false,
openModalWidgetId: null,
subContainerWidths: {},
moveableRef: null,
virtualTarget: null,
currentDragCanvasId: null,
ghostDragPosition: null,
};
export const useGridStore = create(
zustandDevTools(
(set, get) => ({
(set) => ({
...initialState,
actions: {
setResizingComponentId: (id) => set({ resizingComponentId: id }),
@ -30,22 +26,7 @@ export const useGridStore = create(
setOpenModalWidgetId: (openModalWidgetId) => set({ openModalWidgetId }),
setSubContainerWidths: (id, width) =>
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) => ({
dynamicElementGuidelines: [...state.dynamicElementGuidelines, selector],
})),
removeFromElementGuidelines: (selector) =>
set((state) => ({
dynamicElementGuidelines: state.dynamicElementGuidelines.filter((item) => item !== selector),
})),
clearDynamicElementGuidelines: () => set({ dynamicElementGuidelines: [] }),
setMoveableRef: (ref) => set({ moveableRef: ref }),
getGhostDragPosition: () => get().ghostDragPosition,
}),
{ name: 'Grid Store' }
)

View file

@ -116,6 +116,7 @@ const BaseColorSwatches = ({
);
};
const ColorPickerInputBox = () => {
console.log('onReset', onReset);
return (
<div
className="row mx-0 color-picker-input d-flex"