SNAP_FIX.md 2.8 KB

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:

{
  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

// 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:

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