Fixing scrollbar flickering in annotator mode (#1968)

<!-- This is an auto-generated description by cubic. -->
## Summary by cubic
Fixes scrollbar flickering in annotator mode by constraining draggable
inputs within the container and suppressing scroll during drag for
smoother movement.

- **Bug Fixes**
- Added containerRef to DraggableTextInput and elementRef to calculate
bounds.
- Constrained drag coordinates to container size and accounted for
scale.
- Prevented default and stopped propagation on mousemove to avoid scroll
jitter.
  - Passed containerRef from Annotator to DraggableTextInput.

<sup>Written for commit 959605ddaa5faf23252ee797bf206c6dff46a069.
Summary will update automatically on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
This commit is contained in:
Mohamed Aziz Mejri
2025-12-16 20:21:33 +01:00
committed by GitHub
parent 3fd45ec253
commit 2e31c508da
2 changed files with 25 additions and 4 deletions

View File

@@ -26,6 +26,7 @@ interface DraggableTextInputProps {
spanRef: React.MutableRefObject<HTMLSpanElement[]>;
inputRef: React.MutableRefObject<HTMLInputElement[]>;
color: string;
containerRef?: React.RefObject<HTMLDivElement | null>;
}
export const DraggableTextInput = ({
@@ -40,15 +41,33 @@ export const DraggableTextInput = ({
spanRef,
inputRef,
color,
containerRef,
}: DraggableTextInputProps) => {
const [isDragging, setIsDragging] = useState(false);
const dragOffset = useRef({ x: 0, y: 0 });
const elementRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
if (isDragging) {
const newX = e.clientX - dragOffset.current.x;
const newY = e.clientY - dragOffset.current.y;
e.preventDefault();
e.stopPropagation();
if (isDragging && containerRef?.current && elementRef.current) {
const containerRect = containerRef.current.getBoundingClientRect();
const elementRect = elementRef.current.getBoundingClientRect();
let newX = e.clientX - dragOffset.current.x;
let newY = e.clientY - dragOffset.current.y;
// Constrain within container bounds
newX = Math.max(
0,
Math.min(newX, containerRect.width - elementRect.width),
);
newY = Math.max(
0,
Math.min(newY, containerRect.height - elementRect.height),
);
// Calculate adjusted coordinates for the canvas
const adjustedX = newX / scale;
const adjustedY = newY / scale;
@@ -69,10 +88,11 @@ export const DraggableTextInput = ({
document.removeEventListener("mouseup", handleMouseUp);
};
}
}, [isDragging, input.id, onMove, scale]);
}, [isDragging, input.id, onMove, scale, containerRef]);
return (
<div
ref={elementRef}
className="absolute z-[999]"
style={{
left: `${input.x}px`,

View File

@@ -377,6 +377,7 @@ export const Annotator = ({
spanRef={spanRef}
inputRef={inputRef}
color={input.color}
containerRef={containerRef}
/>
))}