# Grid Snapping Fix ## Problem Widgets were not snapping to grid cells despite the snap logic being implemented. ## Root Cause The drag event handlers were expecting `data.clientX` and `data.clientY` directly from the `@neodrag/solid` library, but the library actually provides: ```javascript { offsetX: number, // Offset relative to draggable element offsetY: number, // Offset relative to draggable element event: MouseEvent, // The actual mouse/touch event rootNode: HTMLElement, currentNode: HTMLElement } ``` The actual mouse coordinates are in `data.event.clientX` and `data.event.clientY`, not directly on the data object. ## Solution ### 1. Updated DragEventData Type ```typescript // Before type DragEventData = { clientX: number; clientY: number; offsetX?: number; offsetY?: number; deltaX?: number; deltaY?: number; }; // After type DragEventData = { offsetX: number; offsetY: number; event: MouseEvent | TouchEvent; rootNode: HTMLElement; currentNode: HTMLElement; }; ``` ### 2. Updated Event Handlers All three drag handlers (`handleDragStart`, `handleDrag`, `handleDragEnd`) now extract clientX/clientY from the event: ```typescript const event = data.event; const clientX = "clientX" in event ? event.clientX : (event as TouchEvent).touches[0].clientX; const clientY = "clientY" in event ? event.clientY : (event as TouchEvent).touches[0].clientY; ``` This also adds touch event support for mobile devices. ## What Now Works 1. ✅ Drag events properly receive mouse coordinates 2. ✅ Snap detection calculates correct distances 3. ✅ Visual feedback shows when hovering over cells 4. ✅ Widgets snap to grid cells on drop 5. ✅ Widgets resize to fit cells when snapped 6. ✅ Touch events supported for mobile ## Testing 1. Start dev server: `npm run dev` 2. Select a grid template (e.g., "Simple 2x2 Grid") 3. Add a widget 4. Drag the widget over a grid cell 5. You should see: - Grid cell highlights with blue glow - "Drop to snap" indicator appears - Console logs showing snap detection 6. Release the widget - it should snap to the cell ## Console Output (Expected) When dragging near a cell: ``` [Snap Debug] DRAG START { widgetId: "...", clientX: 450, clientY: 320, gridCellsCount: 4 } [Snap Debug] Drag start positions: { dragStartPointerPos: {...}, dragStartWidgetPos: {...} } [Snap Debug] Finding target: { widgetRect: {...}, widgetCenter: {...}, cellsCount: 4, threshold: 30 } [Snap Debug] Checking cell: { cellId: "cell-1", cellCenter: {...}, distance: 15.2, withinThreshold: true } [Snap Debug] Cell is candidate: { cellId: "cell-1", overlap: 0.45, score: -7.3 } [Snap Debug] Best cell: "cell-1" ``` ## Files Modified - `/src/components/WidgetRenderer.tsx` - Fixed event handling in all drag handlers