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:
@@ -125,11 +125,10 @@ export default function MainConverter() {
|
|||||||
|
|
||||||
// Handle value change from draggable bars
|
// Handle value change from draggable bars
|
||||||
const handleValueChange = useCallback((value: number, unit: string) => {
|
const handleValueChange = useCallback((value: number, unit: string) => {
|
||||||
// Convert the dragged unit's value back to the currently selected unit
|
// When dragging a bar, switch to that unit as the source
|
||||||
const convertedValue = convertUnit(value, unit, selectedUnit);
|
setInputValue(value.toString());
|
||||||
setInputValue(convertedValue.toString());
|
setSelectedUnit(unit);
|
||||||
// Keep selectedUnit the same - user is still inputting in that unit
|
}, []);
|
||||||
}, [selectedUnit]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full max-w-6xl mx-auto space-y-6">
|
<div className="w-full max-w-6xl mx-auto space-y-6">
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ export default function VisualComparison({
|
|||||||
onValueChange,
|
onValueChange,
|
||||||
}: VisualComparisonProps) {
|
}: VisualComparisonProps) {
|
||||||
const [draggingUnit, setDraggingUnit] = useState<string | null>(null);
|
const [draggingUnit, setDraggingUnit] = useState<string | null>(null);
|
||||||
const [draggedPercentage, setDraggedPercentage] = useState<number | null>(null);
|
|
||||||
const dragStartX = useRef<number>(0);
|
const dragStartX = useRef<number>(0);
|
||||||
const dragStartWidth = useRef<number>(0);
|
const dragStartWidth = useRef<number>(0);
|
||||||
const activeBarRef = useRef<HTMLDivElement | null>(null);
|
const activeBarRef = useRef<HTMLDivElement | null>(null);
|
||||||
@@ -101,9 +100,6 @@ export default function VisualComparison({
|
|||||||
let newPercentage = dragStartWidth.current + deltaPercentage;
|
let newPercentage = dragStartWidth.current + deltaPercentage;
|
||||||
newPercentage = Math.max(3, Math.min(100, newPercentage));
|
newPercentage = Math.max(3, Math.min(100, newPercentage));
|
||||||
|
|
||||||
// Update the visual percentage immediately
|
|
||||||
setDraggedPercentage(newPercentage);
|
|
||||||
|
|
||||||
// Find the conversion result for this unit
|
// Find the conversion result for this unit
|
||||||
const conversion = conversions.find(c => c.unit === draggingUnit);
|
const conversion = conversions.find(c => c.unit === draggingUnit);
|
||||||
if (!conversion) return;
|
if (!conversion) return;
|
||||||
@@ -121,7 +117,6 @@ export default function VisualComparison({
|
|||||||
|
|
||||||
const handleMouseUp = useCallback(() => {
|
const handleMouseUp = useCallback(() => {
|
||||||
setDraggingUnit(null);
|
setDraggingUnit(null);
|
||||||
setDraggedPercentage(null);
|
|
||||||
activeBarRef.current = null;
|
activeBarRef.current = null;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -148,9 +143,6 @@ export default function VisualComparison({
|
|||||||
let newPercentage = dragStartWidth.current + deltaPercentage;
|
let newPercentage = dragStartWidth.current + deltaPercentage;
|
||||||
newPercentage = Math.max(3, Math.min(100, newPercentage));
|
newPercentage = Math.max(3, Math.min(100, newPercentage));
|
||||||
|
|
||||||
// Update the visual percentage immediately
|
|
||||||
setDraggedPercentage(newPercentage);
|
|
||||||
|
|
||||||
const conversion = conversions.find(c => c.unit === draggingUnit);
|
const conversion = conversions.find(c => c.unit === draggingUnit);
|
||||||
if (!conversion) return;
|
if (!conversion) return;
|
||||||
|
|
||||||
@@ -165,7 +157,6 @@ export default function VisualComparison({
|
|||||||
|
|
||||||
const handleTouchEnd = useCallback(() => {
|
const handleTouchEnd = useCallback(() => {
|
||||||
setDraggingUnit(null);
|
setDraggingUnit(null);
|
||||||
setDraggedPercentage(null);
|
|
||||||
activeBarRef.current = null;
|
activeBarRef.current = null;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -199,8 +190,6 @@ export default function VisualComparison({
|
|||||||
{withPercentages.map(item => {
|
{withPercentages.map(item => {
|
||||||
const isDragging = draggingUnit === item.unit;
|
const isDragging = draggingUnit === item.unit;
|
||||||
const isDraggable = !!onValueChange;
|
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 (
|
return (
|
||||||
<div key={item.unit} className="space-y-1.5">
|
<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"
|
draggingUnit ? "transition-none" : "transition-all duration-500 ease-out"
|
||||||
)}
|
)}
|
||||||
style={{
|
style={{
|
||||||
width: `${displayPercentage}%`,
|
width: `${item.percentage}%`,
|
||||||
backgroundColor: color,
|
backgroundColor: color,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{/* Percentage label overlay */}
|
{/* Percentage label overlay */}
|
||||||
<div className="absolute inset-0 flex items-center px-3 text-xs font-bold pointer-events-none">
|
<div className="absolute inset-0 flex items-center px-3 text-xs font-bold pointer-events-none">
|
||||||
<span className="text-foreground drop-shadow-sm">
|
<span className="text-foreground drop-shadow-sm">
|
||||||
{Math.round(displayPercentage)}%
|
{Math.round(item.percentage)}%
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user