From 1974801d5993231424fc1743d4cc2888c0d0f2db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Sat, 8 Nov 2025 10:58:48 +0100 Subject: [PATCH] fix: bar stays at new position after drag ends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed issue where bars would snap back to original position on drag release. Problem: - On mouseup/touchend, we cleared draggedPercentage immediately - Conversions hadn't updated yet (async state updates) - Bar switched from draggedPercentage to old item.percentage - Bar visually "snapped back" to original position Solution: Delay clearing drag state until conversions update - On drag end: only clear draggingUnit, keep draggedPercentage - Added useEffect that watches conversions + draggingUnit - When !draggingUnit && draggedPercentage !== null → drag just ended - This means conversions have updated, safe to clear visual state - Now clears draggedPercentage and baseConversionsRef Flow: 1. User releases mouse/touch 2. handleMouseUp/handleTouchEnd: calls onValueChange(..., false) 3. Sets draggingUnit = null (stops active drag) 4. Keeps draggedPercentage (maintains visual position) 5. MainConverter updates inputValue and selectedUnit 6. Conversions recalculate 7. useEffect detects: !draggingUnit && draggedPercentage 8. Clears draggedPercentage → bar smoothly transitions to calculated position Result: Bar stays at dragged position and smoothly settles to final value! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- components/converter/VisualComparison.tsx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/components/converter/VisualComparison.tsx b/components/converter/VisualComparison.tsx index f77f2bb..b158f4f 100644 --- a/components/converter/VisualComparison.tsx +++ b/components/converter/VisualComparison.tsx @@ -137,9 +137,9 @@ export default function VisualComparison({ } } setDraggingUnit(null); - setDraggedPercentage(null); + // Don't clear draggedPercentage yet - let it clear when conversions update activeBarRef.current = null; - baseConversionsRef.current = []; + // baseConversionsRef cleared after conversions update }, [draggingUnit, conversions, onValueChange]); // Touch drag handlers @@ -197,9 +197,9 @@ export default function VisualComparison({ } } setDraggingUnit(null); - setDraggedPercentage(null); + // Don't clear draggedPercentage yet - let it clear when conversions update activeBarRef.current = null; - baseConversionsRef.current = []; + // baseConversionsRef cleared after conversions update }, [draggingUnit, conversions, onValueChange]); // Add/remove global event listeners for drag @@ -219,6 +219,15 @@ export default function VisualComparison({ } }, [draggingUnit, handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]); + // Clear drag state when conversions update after drag ends + useEffect(() => { + if (!draggingUnit && draggedPercentage !== null) { + // Drag has ended, conversions have updated, now clear visual state + setDraggedPercentage(null); + baseConversionsRef.current = []; + } + }, [conversions, draggingUnit, draggedPercentage]); + if (conversions.length === 0) { return (