fix(rundown): match drag overlay rect to the dragged element

dnd-kit measures the drag overlay's first child and uses that rect for
collision detection. A preview smaller than the row it represents shifts
the collision centre and, with closestCenter, the resulting drop position.
The preview now fills the overlay wrapper, which dnd-kit sizes from the
dragged element, keeping drop targeting identical to before the overlay.

Also drops the redundant drag cancel wrapper.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TEnUVARPnSqXijiz8KiLiE
This commit is contained in:
Claude
2026-09-16 18:49:01 +00:00
parent 23d1ebeac1
commit f4e70e6e99
2 changed files with 15 additions and 10 deletions
@@ -44,6 +44,9 @@ export function useRundownDnd({
const activeDataRef = useRef<Data | null>(null); const activeDataRef = useRef<Data | null>(null);
const [activeId, setActiveId] = useState<EntryId | null>(null); const [activeId, setActiveId] = useState<EntryId | null>(null);
/**
* Discards any reference to the dragged element, also used as the drag cancel handler
*/
const clearActive = useCallback(() => { const clearActive = useCallback(() => {
isDraggingRef.current = false; isDraggingRef.current = false;
activeDataRef.current = null; activeDataRef.current = null;
@@ -150,13 +153,6 @@ export function useRundownDnd({
[handleCollapseGroup], [handleCollapseGroup],
); );
/**
* On drag cancel we discard any reference to the dragged element
*/
const handleOnDragCancel = useCallback(() => {
clearActive();
}, [clearActive]);
/** /**
* When we drag over a group, we expand it if it is collapsed * When we drag over a group, we expand it if it is collapsed
*/ */
@@ -183,9 +179,9 @@ export function useRundownDnd({
activeId, activeId,
handleOnDragEnd, handleOnDragEnd,
handleOnDragStart, handleOnDragStart,
handleOnDragCancel, handleOnDragCancel: clearActive,
expandOverGroup, expandOverGroup,
}), }),
[sensors, activeId, handleOnDragEnd, handleOnDragStart, handleOnDragCancel, expandOverGroup], [sensors, activeId, handleOnDragEnd, handleOnDragStart, clearActive, expandOverGroup],
); );
} }
@@ -1,12 +1,21 @@
@use '../blockMixins' as *; @use '../blockMixins' as *;
/**
* The overlay wrapper is sized by dnd-kit to match the element being dragged
* We fill it entirely so that the measured rect used for collision detection
* matches the element the user grabbed
*/
.preview { .preview {
@include block-styling; @include block-styling;
box-sizing: border-box;
min-width: 0;
width: 100%;
height: 100%;
display: grid; display: grid;
grid-template-columns: $block-binder-width 1fr; grid-template-columns: $block-binder-width 1fr;
align-items: center; align-items: center;
height: $secondary-block-height;
background-color: $block-bg; background-color: $block-bg;
box-shadow: $block-box-shadow; box-shadow: $block-box-shadow;
cursor: grabbing; cursor: grabbing;