From 19ca75c1b936f0004e2d8c4c8caba55a7e74fdc2 Mon Sep 17 00:00:00 2001 From: Christian Vidal Wolf Date: Thu, 16 Apr 2026 11:55:30 +0200 Subject: [PATCH] Fix drag selection with refs --- src/components/ColumnFilterPopover.tsx | 59 ++++++++++++++++---------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/src/components/ColumnFilterPopover.tsx b/src/components/ColumnFilterPopover.tsx index 08a4e3b..b47da32 100644 --- a/src/components/ColumnFilterPopover.tsx +++ b/src/components/ColumnFilterPopover.tsx @@ -37,42 +37,57 @@ export function ColumnFilterPopover({ const isAllSelected = selectedValues.length === uniqueValues.length && uniqueValues.length > 0; + const isDraggingRef = React.useRef(false); + const dragStartRef = React.useRef(null); + const hoveredIndexRef = React.useRef(null); + const selectedValuesRef = React.useRef(selectedValues); + const onSelectAllRef = React.useRef(onSelectAll); + const filteredValuesRef = React.useRef(filteredValues); + + selectedValuesRef.current = selectedValues; + onSelectAllRef.current = onSelectAll; + filteredValuesRef.current = filteredValues; + const handleMouseDown = (index: number) => { + isDraggingRef.current = true; + dragStartRef.current = index; + hoveredIndexRef.current = index; setIsDragging(true); setDragStart(index); + setHoveredIndex(index); }; const handleMouseEnter = (index: number) => { - if (isDragging && dragStart !== null) { + if (isDraggingRef.current && dragStartRef.current !== null) { + hoveredIndexRef.current = index; setHoveredIndex(index); } }; - const handleMouseUp = () => { - if (isDragging && dragStart !== null && hoveredIndex !== null) { - const start = Math.min(dragStart, hoveredIndex); - const end = Math.max(dragStart, hoveredIndex); - const itemsToSelect = filteredValues.slice(start, end + 1).map(v => v); - const newSelected = new Set([...selectedValues]); - itemsToSelect.forEach(v => newSelected.add(v)); - onSelectAll(Array.from(newSelected)); - } - setIsDragging(false); - setDragStart(null); - setHoveredIndex(null); - }; - React.useEffect(() => { const handleGlobalMouseUp = () => { - if (isDragging) { - handleMouseUp(); + if (isDraggingRef.current) { + const start = dragStartRef.current; + const end = hoveredIndexRef.current; + if (start !== null && end !== null) { + const s = Math.min(start, end); + const e = Math.max(start, end); + const itemsToSelect = filteredValuesRef.current.slice(s, e + 1).map(v => v); + const newSelected = new Set([...selectedValuesRef.current]); + itemsToSelect.forEach(v => newSelected.add(v)); + onSelectAllRef.current(Array.from(newSelected)); + } + isDraggingRef.current = false; + dragStartRef.current = null; + hoveredIndexRef.current = null; + setIsDragging(false); + setDragStart(null); + setHoveredIndex(null); } }; - if (isDragging) { - document.addEventListener('mouseup', handleGlobalMouseUp); - return () => document.removeEventListener('mouseup', handleGlobalMouseUp); - } - }, [isDragging, dragStart, hoveredIndex]); + document.addEventListener('mouseup', handleGlobalMouseUp); + return () => document.removeEventListener('mouseup', handleGlobalMouseUp); + }, []); return (