react-draggable
react-draggable copied to clipboard
Does not respect bounds on new props
Bounds seem to be calculated only on drag which presents a couple of issues:
-
If bounds are changed and passed down from a parent component they will not be respected until the element is dragged
-
Scaling operations on children can cause them to be outside of draggable element bounds and will not be recoverable since not able to click on the now invisible element
I think you are expected to change position
manually if bounds are changing over time, here's example:
const right = document.body.clientWidth / 2;
const [position, setPosition] = React.useState({ x: 0, y: 0 });
React.useEffect(() => {
const listen = () => {
const right = document.body.clientWidth / 2; // notice shadowed variable
if (position.x > right) {
setPosition({ x: right, y: position.y });
}
};
window.addEventListener('resize', listen);
return () => window.removeEventListener('resize', listen);
});
return (
<ReactDraggable
position={position}
onDrag={(e, { x, y }) => {
setPosition({ x, y });
}}
bounds={{ left: 0, right }}
>
Stuff to drag
</ReactDraggable>
so when bounds change and your new x
doesn't fit inside right
you have to manually change position.x
and it will cause the component to move
That doesn't feel like a great solution to me. It forces you to roundtrip through Redux state during a drag. I'm currently needing to do an elaborate workaround, something like:
const windowSize = useWindowSize()
const actual = useRef({ x: 0, y: 0 })
const [position, setPosition] = useState(defaultPosition)
const bounds = useMemo(() => {
return constraintsBasedOnWindowSize(windowSize)
}, [windowSize, isExpanded])
const setBoundedPosition = useCallback(position => {
const constrained = constrain(position, bounds)
actual.current = constrained
if (!areEqual(position, constrained)) {
setPosition(constrained)
}
}, [bounds, position])
return (
<Draggable
onDrag={(_, position) => { setBoundedPosition(position) }}
onStop={() => { setPosition(actual.current) }}
position={position}
>
...
</Draggable>
)
which is very much a workaround for behaviour I would hope the library to take care of.
Related issue: https://github.com/react-grid-layout/react-draggable/issues/363
There's an interesting workaround suggested there: https://github.com/react-grid-layout/react-draggable/issues/363#issuecomment-631750224. Simulates a mouse down event to trigger the internal calculations related to bounds.