bvaughn / react-resizable-panels Goto Github PK
View Code? Open in Web Editor NEWHome Page: https://react-resizable-panels.vercel.app/
License: MIT License
Home Page: https://react-resizable-panels.vercel.app/
License: MIT License
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)?
Hi. I forked your codesandbox repo and tried creating my panels using your documentation.
The issue is that when I tried resizing 1 and 2 block it flickers and adjusts automatically.
Codesandbox Link - https://codesandbox.io/s/react-resizable-panels-forked-7ch71r?file=/src/App.js
Can someone please help me out what I am doing wrong here or is it a bug?
Thank You.
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
Can the imperative API provide a function like getSize
to get the current size. this way we can have logic that can position and size stuff with absolute positioning but aware of the panel sizes.
Seems a new URL hash is written on every mouse move, which makes for a long history history.
Suggested fixes:
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!
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.
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.
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
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?
When using nested panels https://react-resizable-panels.vercel.app/examples/nested there appears to be some strange behaviour that lets certain panels escape their boundry
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
Currently these callbacks are only triggered after a user-initiated resize. Combining this with the auto-save behavior leads to an ambiguous mount scenario: is the panel collapsed or not? what's the initial size?
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
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.
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.
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)
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.).
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>
onResize
prop and no order
propThe docs warn about this but we could also programmatically detect and warn as well since it is non-obvious.
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.
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
?
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
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 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
The cursor does not change back to the default cursor after using the keyboard to reposition the resize handle. It only changes back after having used the cursor to reposition the resize handle. Until then, it stays on col-resize
and only changes back to default
after using the cursor.
Panels in VS Code can be fully collapsed when shrunk past a certain point.
This is an interesting UX that might be worth copying (if it can be done without adding a lot of complexity).
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):
Possible solution
It just works if you set point-events: none
on the iframe.
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
Pros:
Panel
Cons:
PanelGroup
would need to somehow account for resize handle size when assigning panel size
flex-grow
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.
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.
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.
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>
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:
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.
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!
The current website is, at best, a test harness.
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
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.
in firefox, text gets selected and deselected while resizing a panel:
in chrome, this seems to work fine.
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>
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.
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)
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:
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:
I think PanelGroup
should be able to infer this based on the order of registered panels/drag-handles.
Might this get tricky with the changes in #3? Not sure.
This probably regressed in the latest release due to 8aed257
Should test various mouse/keyboard interactions as well as layout persistence (including with conditional panels)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.