Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flickering slider saveId bug #48

Closed
abrman opened this issue Dec 30, 2022 · 10 comments
Closed

Flickering slider saveId bug #48

abrman opened this issue Dec 30, 2022 · 10 comments
Labels
bug Something isn't working

Comments

@abrman
Copy link

abrman commented Dec 30, 2022

The flickering: https://codesandbox.io/s/react-resizable-panels-forked-r68rvr?file=/src/App.js

I've just spent over an hour trying to pinpoint why my sliders were flickering.
Long story short, I had the slider state saved in the local storage with the following content:

{"1:10":[20],"1:10,1:10":[10,30],"1:10,2:10":[16.461173681090695,23.538826318909305],"1:10,2:10,3:10":[18.993775933609953,31.006224066390047,10],"1:10,3:10":[10,30],"1:100,2:10,3:10":[10,40,10],"1:5,2:10,3:10":[10,40,10],"10,10":[16.611570247933884,23.388429752066116],"10,10,10":[0,66.66666666666667,33.333333333333336],"0,10,10":[0,61.74632352941176,38.25367647058824]}"

Deleting the local storage entry fixed my problem.

I don't know how it became broken - I worked off of the codesandbox example so occasionally I had three panels, maybe 4 at most. I'm not sure exactly what the JSON means, but I'm dropping the content of it in here hoping someone will understand what happened, and will help avoid the bug from occurring again. (Not sure whether it's exclusive to development or can also occur in production)

@bvaughn
Copy link
Owner

bvaughn commented Dec 30, 2022

If you figure out the cause, or a repro, let me know.

@bvaughn bvaughn added the bug Something isn't working label Dec 30, 2022
@abrman
Copy link
Author

abrman commented Dec 30, 2022

From: #47 (comment)

You should be able to accomplish this using minSize/maxSize and a min/max external height/width though!

I wasn't sure what you meant with min/max external height/width and ran into the bug gain.
I suppose this is how you reproduce it: https://codesandbox.io/s/react-resizable-panels-forked-d8eqci?file=/src/App.js

Would you be willing to explain more of how you'd go about achieving min/max limits?

@abrman
Copy link
Author

abrman commented Dec 30, 2022

I suppose I triggered the bug previously with setting max-width on one of the panels previously. It behaves similarly to the beforementioned sandbox link.

@bvaughn
Copy link
Owner

bvaughn commented Dec 30, 2022

Ah, right. I don't think I'd consider that a bug in this library (or something I'd try to fix). It's just kind of an invalid configuration.

@bvaughn
Copy link
Owner

bvaughn commented Dec 30, 2022

Would you be willing to explain more of how you'd go about achieving min/max limits?

If you want to set min/max sizes in pixels and you control the overall width and height of the panel group, then you can do the conversion to whatever the min/max percentage would be.

In other words, if you wanted to make sure a panel couldn't shrink below 100px wide, and you know the panel group was 1,000 pixels wide, then you'd need to set minSize={10}

@bvaughn
Copy link
Owner

bvaughn commented Dec 30, 2022

Here is an example of what I mean:
https://codesandbox.io/s/react-resizable-panels-forked-m5qf69?file=/src/App.js

  const MIN_SIZE_IN_PIXELS = 100;

  const [minSize, setMinSize] = useState(10);

  useLayoutEffect(() => {
    const panelGroup = document.querySelector('[data-panel-group-id="group"]');
    const resizeHandles = document.querySelectorAll(
      "[data-panel-resize-handle-id]"
    );
    const observer = new ResizeObserver(() => {
      let height = panelGroup.offsetHeight;

      resizeHandles.forEach((resizeHandle) => {
        height -= resizeHandle.offsetHeight;
      });

      // Minimum size in pixels is a percentage of the PanelGroup's height,
      // less the (fixed) height of the resize handles.
      setMinSize((MIN_SIZE_IN_PIXELS / height) * 100);
    });
    observer.observe(panelGroup);
    resizeHandles.forEach((resizeHandle) => {
      observer.observe(resizeHandle);
    });

    return () => {
      observer.disconnect();
    };
  }, []);

@bvaughn
Copy link
Owner

bvaughn commented Dec 30, 2022

If the available height is ever too small to actually allow that scenario to work– you can decide what to do, but I don't think there's anything PanelGroup could do, since its size is managed externally.

@bvaughn
Copy link
Owner

bvaughn commented Dec 30, 2022

I'm going to close this issue because I think it's probably caused by an invalid CSS properties situation but if you see it again let me know and we'll re-open!

@bvaughn bvaughn closed this as completed Dec 30, 2022
@abrman
Copy link
Author

abrman commented Dec 30, 2022

Yup - definitely seemed like a invalid configuration. I just tried <Panel style={{maxHeight: 100}}/> which I know I tried before to achieve desired behavior. It does produce similar behavior to the buggy one, but doesn't seem to break it. I don't know what I did to break it earlier.

You were quick with your solution - I was thinking something more along the lines of keeping the window innerWidth in a state (assuming horizontal layout). Update it whenever window size changes, and feed it to Panel props as follows: <Panel minSize={(MIN_SIZE_IN_PIXELS/width)*100} maxSize={(MAX_SIZE_IN_PIXELS/width)*100}/>

ResizeObserver is something new to me. I'm confident it would likely be more performant, however when user resizes the window, it allows the size to go outside of the constraints.

Thank you for your assistance. I'll give it a try and see what I come up with :)

@bvaughn
Copy link
Owner

bvaughn commented Dec 30, 2022

Yup! 🙇🏼 Good luck!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants