re-resizable icon indicating copy to clipboard operation
re-resizable copied to clipboard

Parent scroll resets to 0 when resizing

Open naveensenapathi opened this issue 4 years ago • 7 comments

Overview of the problem

I have a list of <Resizable> elements arranged horizontally with a scroll. When you try to resize any element, the parent scroll resets to 0, making it difficult to see what's happening.

I'm using re-resizable version [6.5.0]

Reproducible on the documentation codesandbox: https://codesandbox.io/s/elegant-banzai-nwliz?file=/src/index.js

My browser is: Google Chrome Version 88.0.4324.192 (Official Build) (x86_64) macOS 11.1

I am sure this issue is not a duplicate after searching the issues for "scroll" issues I found no mention of this behaviour in the documentation.

Description

When there are multiple <Resizable> elements with either a horizontal or a vertical scroll, resizing the element resets the parent scrollLeft and scrollTop values to 0, which makes it difficult to resize elements that go out of the viewport.

Try to resize the 5th or 6th element from the codesandbox example

chrome-capture

Steps to Reproduce

  1. Try to resize the 5th or 6th element from the list of resizable elements

https://codesandbox.io/s/elegant-banzai-nwliz?file=/src/index.js

Expected behavior

It should retain parent's scroll position while resizing

Actual behavior

Parent's scroll resets to 0 obscuring the view of the resizable element

naveensenapathi avatar Feb 26 '21 10:02 naveensenapathi

In case this helps anyone,

I ran into the same issue however I worked around this issue by utilizing onResizeStart and onResize callbacks

onResizeStart={(e) => {
  const element = e.currentTarget.getBoundingClientRect();
  var topPos = element.top + window.scrollY;
  var leftPos = element.left + window.scrollX;
  pointX.current = leftPos; //just used ref in my case
  pointY.current = topPos;
}}
onResize={(
    event,
    direction,
    refToElement,
    delta,
  ) => {
  window.scrollTo(pointX.current + delta.width, pointY.current + delta.height);
}}

So using onResizeStart to get the position relevant to the view and then during onResize, I utilized the delta to keep it in view as the user resizes.

Hope this helps.

chankim206 avatar Jun 03 '21 18:06 chankim206

@chankim206 thank you for the answer!

For the future issuer found easier solution

onResize={(_e, _direction, _ref, data) => {
  if (prevValue.current > data.width) {
    onChange(width + data.width - prevValue.current, height, 100);
  } else {
    onChange(width + Math.abs(data.width - prevValue.current), height, 100);
  }
  prevValue.current = data.width;
}}
onResizeStop={() => {
  prevValue.current = 0;
}} 

MaxArnaut avatar Feb 15 '22 07:02 MaxArnaut

Using the above examples as a guide, for my use case this was the simplified solution for the general case.

// Create refs
const parentScrollOffsetX = useRef(0)
const parentScrollOffsetY = useRef(0)
onResizeStart={(e,direction,ref) => {
    parentScrollOffsetX.current = ref.parentElement?.scrollLeft || 0
    parentScrollOffsetY.current = ref.parentElement?.scrollTop || 0
}}
onResize={(e, direction, ref, d) => {
    ref.parentElement.scrollTo(parentScrollOffsetX.current, parentScrollOffsetY.current)
}}

tylerkahn avatar Feb 14 '23 20:02 tylerkahn

Using the above examples as a guide, for my use case this was the simplified solution for the general case.

// Create refs
const parentScrollOffsetX = useRef(0)
const parentScrollOffsetY = useRef(0)
onResizeStart={(e,direction,ref) => {
    parentScrollOffsetX.current = ref.parentElement?.scrollLeft || 0
    parentScrollOffsetY.current = ref.parentElement?.scrollTop || 0
}}
onResize={(e, direction, ref, d) => {
    ref.parentElement.scrollTo(parentScrollOffsetX.current, parentScrollOffsetY.current)
}}

Same for me, but I use scroll inside resizable area, so I replaced ref.parentElement to myListRef?.current and it's work well too 🙌

saymon-develop avatar Aug 08 '23 10:08 saymon-develop