From 7cd04b6a9bef603de5d7796c3d738843d84aa104 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Thu, 12 Mar 2026 04:30:41 +0100 Subject: [PATCH] fix: DnD drop indicator shows single stable line between adjacent items Normalize 'before' position to previous item's 'after' so inter-item gaps always render from one DOM element, eliminating sub-pixel jump. --- .../web/src/components/layout/SpaceSidebar.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/web/src/components/layout/SpaceSidebar.tsx b/packages/web/src/components/layout/SpaceSidebar.tsx index b93312b3..26a3b944 100644 --- a/packages/web/src/components/layout/SpaceSidebar.tsx +++ b/packages/web/src/components/layout/SpaceSidebar.tsx @@ -893,8 +893,23 @@ export function SpaceSidebar() { position = relY < height * 0.5 ? 'before' : 'after'; } + // Normalize 'before' to previous item's 'after' so the drop indicator + // always renders from a single DOM element, eliminating sub-pixel jump + if (position === 'before') { + const targetIdx = resolvedLayout.findIndex(item => + (item.type === 'space' && item.space.id === targetId) || + (item.type === 'folder' && item.folder.id === targetId) + ); + if (targetIdx > 0) { + const prevItem = resolvedLayout[targetIdx - 1]!; + const prevId = prevItem.type === 'space' ? prevItem.space.id : prevItem.folder.id; + setDropIndicator({ targetId: prevId, position: 'after' }); + return; + } + } + setDropIndicator({ targetId, position }); - }, [dragState]); + }, [dragState, resolvedLayout]); const handleDragEnd = useCallback(() => { setDragState(null);