fix: dragging now switches source unit to update all bars correctly

Fixed dragging behavior so all bars update when you drag:

Problem:
- Dragging a bar would change values but bars wouldn't visually update
- The bar would reset to original length on release
- Other bars wouldn't change at all

Root cause:
- We were converting the dragged value back to the selected unit
- This kept the source unit the same, so relative percentages didn't change
- The logarithmic scale maintained proportions, preventing visual updates

Solution:
- When dragging a bar, switch to that unit as the new source unit
- Set both inputValue and selectedUnit to the dragged unit's value/name
- This changes the conversion base, making all other bars recalculate
- Removed draggedPercentage state (not needed with this approach)
- All bars now use calculated percentages from conversions

How it works now:
- Drag the "feet" bar → becomes the source unit (selectedUnit = 'ft')
- All conversions recalculate from feet
- All bars update their percentages based on new conversion base
- No transitions during drag for instant visual feedback
- Smooth animation when drag ends

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-08 10:50:55 +01:00
parent 4911f0144f
commit 5fb89909f9
2 changed files with 6 additions and 18 deletions

View File

@@ -125,11 +125,10 @@ export default function MainConverter() {
// Handle value change from draggable bars
const handleValueChange = useCallback((value: number, unit: string) => {
// Convert the dragged unit's value back to the currently selected unit
const convertedValue = convertUnit(value, unit, selectedUnit);
setInputValue(convertedValue.toString());
// Keep selectedUnit the same - user is still inputting in that unit
}, [selectedUnit]);
// When dragging a bar, switch to that unit as the source
setInputValue(value.toString());
setSelectedUnit(unit);
}, []);
return (
<div className="w-full max-w-6xl mx-auto space-y-6">

View File

@@ -16,7 +16,6 @@ export default function VisualComparison({
onValueChange,
}: VisualComparisonProps) {
const [draggingUnit, setDraggingUnit] = useState<string | null>(null);
const [draggedPercentage, setDraggedPercentage] = useState<number | null>(null);
const dragStartX = useRef<number>(0);
const dragStartWidth = useRef<number>(0);
const activeBarRef = useRef<HTMLDivElement | null>(null);
@@ -101,9 +100,6 @@ export default function VisualComparison({
let newPercentage = dragStartWidth.current + deltaPercentage;
newPercentage = Math.max(3, Math.min(100, newPercentage));
// Update the visual percentage immediately
setDraggedPercentage(newPercentage);
// Find the conversion result for this unit
const conversion = conversions.find(c => c.unit === draggingUnit);
if (!conversion) return;
@@ -121,7 +117,6 @@ export default function VisualComparison({
const handleMouseUp = useCallback(() => {
setDraggingUnit(null);
setDraggedPercentage(null);
activeBarRef.current = null;
}, []);
@@ -148,9 +143,6 @@ export default function VisualComparison({
let newPercentage = dragStartWidth.current + deltaPercentage;
newPercentage = Math.max(3, Math.min(100, newPercentage));
// Update the visual percentage immediately
setDraggedPercentage(newPercentage);
const conversion = conversions.find(c => c.unit === draggingUnit);
if (!conversion) return;
@@ -165,7 +157,6 @@ export default function VisualComparison({
const handleTouchEnd = useCallback(() => {
setDraggingUnit(null);
setDraggedPercentage(null);
activeBarRef.current = null;
}, []);
@@ -199,8 +190,6 @@ export default function VisualComparison({
{withPercentages.map(item => {
const isDragging = draggingUnit === item.unit;
const isDraggable = !!onValueChange;
// Use dragged percentage if this bar is being dragged, otherwise use calculated percentage
const displayPercentage = isDragging && draggedPercentage !== null ? draggedPercentage : item.percentage;
return (
<div key={item.unit} className="space-y-1.5">
@@ -241,14 +230,14 @@ export default function VisualComparison({
draggingUnit ? "transition-none" : "transition-all duration-500 ease-out"
)}
style={{
width: `${displayPercentage}%`,
width: `${item.percentage}%`,
backgroundColor: color,
}}
/>
{/* Percentage label overlay */}
<div className="absolute inset-0 flex items-center px-3 text-xs font-bold pointer-events-none">
<span className="text-foreground drop-shadow-sm">
{Math.round(displayPercentage)}%
{Math.round(item.percentage)}%
</span>
</div>