Code Monkey home page Code Monkey logo

react-resizable-panels's Issues

External persistence

Would it be possible to expose a way to provide custom persistence (for example, if you wanna persist the sizes/layouts to a database rather than local storage)?

Support (or recommended approach) for handling "position: absolute" panels

We have a sidebar navigation panel on the left, and main content on the right, and a resizer between them.

I'm sure this is a fairly niche requirement but the navigation panel can be "unpinned" meaning it's given position: absolute and is "disconnected" from the main content so that the main content expands/"falls behind" the sidebar, yet the sidebar can continue to be expanded and collapsed as if the main content was still there.

Because this is using flex, it's not automatically compatible with an absolute panel. I was wondering if you can recommend a solution?

My initial thoughts are to use onResize to set fixed dimensions if it's supposed to be unpinned.

P.S. Sorry for filing an issue, I didn't see a better place to ask

external-persistence URL hash hinders history

  1. External persistence
  2. resize a panel or 2
  3. try to go back in history
  4. feel like you're starting an idle game ;)

Seems a new URL hash is written on every mouse move, which makes for a long history history.

Suggested fixes:

  1. debounce would reduce the number of updates
  2. wait for a mouseup (or timer for keyboard control) to change the URL hash.

I guess you might have excessive localStorage writes also, but didn't test for it.


Thanks for this project; I bookmarked for usage later, & I'm sure many other folks will use in their projects!

Support toggling panel visibility

This is a use case that Replay needs to show/hide the video/canvas panel in the top right so that the secondary toolbox (console, network, etc) can be full height.

In this case the PanelGroup should re-calculate size with the subset of components. If the autoSaveId prop is provided, it should also save/restore sizes separately for each Panel combination.

Change cursor based on min/max state

External feature request:

Will there be a change to the mouse cursor changing its icon based on the given state? For example, if the mouse resizes to the min size and it can't keep resizing, the cursor will change to the icon that reflects the allowed directions.

This video is from the VS Code editor.

Compile Error with Create React App with React 17

Hello πŸ‘‹πŸ½,

I'm getting a compile error when I try to use the react-resizable-panels components in my project:

Screenshot 2023-01-05 at 5 26 57 PM

I have the following setup in my package.json:

"react": "17.0.0", "react-dom": "17.0.0", "react-scripts": "4.0.3",

I'll appreciate any pointers to resolve this, thank you!

Support pixel values for sizes

We need to set specific pixel size values for the default, min, and max sizes for a panel. Please add support for pixel values, like 200px

Add maxSize to Panel

Currently there is a property minSize that restricts flex-grow to become smaller than this value. Can you add a new property maxSize that restricts flex-grow to become larger than this value?

Active resize handle styling

If you use the website in Mobile and try resizing panels you will notice that the active styles are not triggered, on debugging I found that on the web it focuses on the handle but in Mobile, the focus is only added if we click the handle but if we start moving it doesn't focus on the handle.

Maybe we can add a data attribute called data-panel-active=true whenever the handle is active and is being dragged. As of now we need to add focus styles for the active handle.

I am open to helping on this issue :D

Reproducible steps:
https://user-images.githubusercontent.com/22376783/209684416-e780f949-4a5d-4008-8c66-09fd61a2c109.mov

How to use this in NextJS

Hi,
This looks mighty impressive. However, when I try to use in NextJs, I am seeing the error message "document is not defined".

When I try dynamic importing it, the linter throws me this error

image

Thanks

Add min/maxSize support for px values

If your UI is designed to be reasonably sized within specific dimensions, having access to limit size with pixel values is essential.

Currently implementing with CSS values only works in 2-column/2-row setup,

Thanks for working on this component for all of us! <3

Module parse error

I am trying to using the library in an existing project bootstrapped with craco and create-react-app. Following is the error I get at the compile time.

./node_modules/react-resizable-panels/dist/react-resizable-panels.module.js 141:23
Module parse failed: Unexpected token (141:23)
File was processed with these loaders:
 * ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
|   if (state) {
|     const key = $6ff1a22b27cc039d$var$getSerializationKey(panels);
>     return state[key] ?? null;
|   }
|

Package.json details:
"@craco/craco": "^6.0.0", "react": "^17.0.2", "react-dom": "^17.0.2",

Please let me know if you need more details.

Direct control of sizes

Are there any ways to directly set the sizes for panels? On init, it seems like the defaultSize attribute for a Panel can do that but then there aren't any ways to override that later.

Flickering slider saveId bug

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)

Add minSize/maxSize, but in pixels

Hi! Can you add min/max panel size restrictions, but in pixels? Sometimes, if the window size becomes too small, panel content may shrink too much, which causes UI issues (overflows, etc.).

Better DEV warnings for invalid props

Invalid default sizes

The following panel group has an invalid configuration, which will cause flickering during resize:

<PanelGroup direction="horizontal">
  <Panel defaultSize={20}>
    {/* ... */}
   </Panel>
  <ResizeHandle />
  <Panel defaultSize={20}>
    {/* ... */}
   </Panel>
</PanelGroup>

Panel with onResize prop and no order prop

The docs warn about this but we could also programmatically detect and warn as well since it is non-obvious.

Collapse/open via external component

A use-case I would have for this would be clicking on a list item to open up a detailed side panel view, it would great if the library could include the functionality of triggering the opening of the side panel on click of another element.

Warning during SSR due to useLayoutEffect

Hi @bvaughn, thanks for this amazing library!

I get a warning due to the use of useLayoutEffect in this library during SSR using Next.js:

Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://reactjs.org/link/uselayouteffect-ssr for common fixes.
    at $4b51bd7b90b9da8b$export$2e2bcd8739ae039 (/Users/erikmuller/cnapp/node_modules/react-resizable-panels/dist/react-resizable-panels.js:29:63)

Is it possible to use something like useIsomorphicLayoutEffect instead of useLayoutEffect?

Hope to support more property settings

This is a great job, but when setting defaultSize, maxSize, minSize and other attributes, only numbers are supported. In use, pixels need to be used to operate elements more precisely, and more setting methods are expected to be supported.

useId usage breaks persistence

useId ids are not deterministic, meaning that they break the current persistence mechanism. We should re-work that somehow so that it's not based on panel ids but more on the panel data's attributes (which are deterministic?)

Resizing panels should not require a full re-render

Resizing a panel should just be a matter of changing the style value, which could be done imperatively (without requiring a re-render). This has some consequences, since rendering that's conditional on size would not "work" with a partially imperative UI, but the way panel sizes are being managed (as CSSProperties objects) is somewhat opaque already so this change would probably be okay.

Related: #27

Panel collapse mode

Panels in VS Code can be fully collapsed when shrunk past a certain point.

Kapture.2022-12-23.at.07.24.54.mp4

This is an interesting UX that might be worth copying (if it can be done without adding a lot of complexity).

Iframe inside panels

I noted that the drag event doesn't work correctly when there's an iframe inside a Panel. It could be because the dragging listener is on the main window, and it doesn't consider the other window, which is the iframe.

Here's a screenrecording (sandbox):

Screen.Recording.2023-01-05.at.14.06.37.mov

Possible solution

It just works if you set point-events: none on the iframe.

Screen.Recording.2023-01-05.at.14.13.17.mov

Copy button for code snippits

Ideally, the code snippets should have copy buttons. You can copy the code now by hand, but you end up getting the line numbers as well, which is annoying to try to take out.

Proposed fix in PR #61

Conditional panel positions

PanelGroup infers panel positions based on the order panels are registered in. Conditional rendering can "break" this, as panels registered after mount will be added to the end of the container.

There needs to be a way for panels to specify their ordering via a prop. This prop could be optional for cases when there is no conditional rendering.

Render custom PanelResizeHandle based on whether it's resizing or not

What you did:

I'm using a styled resize handle, like the following:

<panels.PanelResizeHandle className="w-0.5 relative">
    <div className="absolute inset-y-0 -left-[0.1875rem] w-1.5 bg-blue-500 opacity-0 hover:opacity-100 transition-opacity"></div>
</panels.PanelResizeHandle>

It basically becomes blue on hover.

image

What happened:

The problem is that, while resizing, the handle will stop being highlighted in blue if the mouse moves too fast. It happens because the mouse won't be on top of the handle for a few milliseconds.

Suggested solution:

The PanelResizeHandle component could pass a isResizing boolean to its children so we can keep the highlighting in place. It'd look like this:

<panels.PanelResizeHandle className="w-0.5 relative">
    {({ isResizing }) => (
        <div className={classNames("absolute inset-y-0 -left-[0.1875rem] w-1.5 bg-blue-500 hover:opacity-100 transition-opacity", { "opacity-100": isResizing, "opacity-0": !isResizing })}></div>
    )}
</panels.PanelResizeHandle>

Server side rendering causes the layout to shift when loading

I am using NextJS and at the start (after a refresh), the panels start in their default configuration (so not whatever the user had before). Then it quickly shifts to the user's intended position (within a couple ms).

It looks like this:

2023-01-17 16 52 40

I feel like the panel should be client side rendered, but I do not want the content of the panels to be client side rendered. Is there anything that can be done against this? I do not have a lot of experience with NextJS, so there is probably an easy solution I am not seeing.

Ability to keep dragging with mouse outside the window

If you compare https://codesandbox.io/s/react-resizable-panels-zf7hwd and https://react-grid-layout.github.io/react-grid-layout/ you'll notice that react-grid-layout lets you keep dragging even if your mouse leaves the window, but with react-resizable-panels the drag event seems to stop as soon as the mouse leaves the window.

This is probably not a dealbreaker, but it would arguably be nicer UX if the drag event didn't just stop if you accidentally dragged too much.

Sorry, I'm currently on my phone so I can't record a video to make it crystal clear what I'm talking about but I hope the description suffices!

Nested PanelGroup flickering when resizing

I've noticed this border flickering issue when resizing the nested Panel as seen in the below video.
It may be more noticeable on slow machines

2022-12-27.01-12-11.mp4

Collapse on click

Thanks for the really nice package!

One feature I'd love to see is the ability to close and open (ie; collapse) a panel on click of the ResizeHandle.

Add isCollapsed boolean or size value to the Imperative API

It would be handy to include either a status boolean or the current size of a panel in the Imperative API to use alongside the methods it provides.

Scenario:
You have a panel you want to toggle open or closed via another button component:

 import {
   ImperativePanelHandle,
   Panel,
   PanelGroup,
   PanelResizeHandle,
 } from "react-resizable-panels";
 
 const ref = useRef<ImperativePanelHandle>(null);
 
 const collapsePanel = () => {
   const panel = ref.current;
   if (panel.isCollapased) {
     panel.expand();
   } else {
     panel.collapse();
   }
 };
 
 <PanelGroup direction="horizontal">
   <Panel collapsible ref={ref}>
     left
   </Panel>
   <PanelResizeHandle />
   <Panel>
     right
   </Panel>
 </PanelGroup>

Mobile (touch) support

If it's possible to do so without introducing too much complexity, it would be nice to support mobile/touch platforms.

The primary purpose for this component is Replay.io, which does not support touch devices, but it would still be nice to support this for other users.

export "useId" was not found in "react"

Please note: This is related to Webpack issue: webpack/webpack#14814

Some bundles (Webpack) may throw an error during compilation if code references a named import that a module does not export– even if the import is only used conditionally.

The error thrown by Webpack will look like:

export 'useId' (imported as '$fpI56$useId') was not found in 'react'

To work around this, the following change was made in 0.0.38:

- const useReactId = (React as any).useId as () => string;
+ // `toString()` prevents bundlers from trying to `import { useId } from 'react'`
+ const useReactId = (React as any)['useId'.toString()] as () => string;

Unfortunately it caused a regression and was reverted in 0.0.39. (Seemingly the new syntax confused Parcel.)


(Description modified by @bvaughn)

New size should only be committed after dragging ends

Currently, when dragging panel 'right' and causing another panel 'left' to resize, it immediately commits the new size of the panel 'left', even if I drag panel 'right' back to its original position. See:

Screen.Recording.2023-01-09.at.12.23.14.mov

It feels counterintuitive, since it's quite common that I'm not 100% precise on my drag and will overshoot. Ideally all new sizes are only committed after I release the mouse button and panels spring back to their original position. See e.g. in vscode:

Screen.Recording.2023-01-09.at.12.24.10.mov

Playwright e2e tests

Should test various mouse/keyboard interactions as well as layout persistence (including with conditional panels)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.