npm / react-resizable-panels
react-resizable-panels
What changed in react-resizable-panels 4, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-17.
react-resizable-panels 4124 changes
Breaking changes 12
useDefaultGridLayoutnow persists the requested layout instead of the constrained layout.useDefaultLayoutnow persists the requested layout instead of the constrained layout.Separator no longer retains focus after a drag.
Panel replaces the aria-disabled attribute with data-disabled.
Adds a new Group callback for layout changes.
Pointer-event layout changes trigger the callback only after the pointer is released, reducing callback frequency for tasks like saving layouts.
Persistent layouts no longer use PanelGroup autoSaveId directly.
PanelGroup was renamed to Group to align with the version 4 API.
PanelGroup was replaced by Group in version 4.
PanelResizeHandle was replaced by Separator in version 4.
useGroupRef replaces the imperative group ref type and creates a group reference.
usePanelRef replaces the imperative panel ref type and creates a panel reference.
Deprecations 2
The previous callback remains supported but is marked deprecated.
The groupId parameter is deprecated in favor of id because the Group does not need a matching id.
New APIs and options 22
onLayoutChangedmetadata now includesrequestedLayout, exposing the layout requested before constraints were applied.Adds cells that can span multiple columns and rows in resizable two-dimensional layouts.
Adds Grid components for resizable two-dimensional layouts with row and column size constraints.
Adds optional gridlines that can span subsets of tracks to avoid spanning cells.
Adds a hook for default grid layout behavior.
Adds a callback ref hook for grids.
Adds a ref hook for grids.
Panels now support a configurable collapse threshold.
Resize preview mode is now customizable.
The callback now receives meta information indicating whether resizing was triggered by direct keyboard or mouse input.
The hook can now save layouts only when directly triggered by user interactions.
Adds a prop to turn off the double-click size reset behavior.
Automatically migrates legacy layouts to version 4 format, easing upgrades for existing persisted layouts.
Adds a Panel prop that lets panels retain their current pixel size when the parent Group is resized.
Panel and Separator components can now be disabled.
Group, Panel, and Separator components now expose displayName for a better debugging experience.
The onResize callback now receives prevPanelSize, simplifying collapse and expand detection.
The GroupImperativeHandle type is now exported for developers to use in application code.
The PanelImperativeHandle type is now exported for developers to use in application code.
Group accepts groupRef for imperative access.
Panel accepts panelRef for imperative access.
useDefaultLayout provides defaultLayout and onLayoutChange for persistent layouts.
Performance 4
Available group size is calculated once per hit-testing pass instead of once per hit region.
Panel avoids unnecessary re-renders in response to mouse-hover state.
Panel now applies flex-grow inline instead of using a CSS variable on the parent Group, reducing forced reflow and improving rendering performance.
Debounces calls to storage.setItem by 150ms, reducing the frequency of storage updates.
Behavior and default changes 16
The imperative Panel API now supports non-percentage sizes.
Default overflow styles changed to support shadows.
Imperative Panel and Group APIs now explicitly override disabled status when resizing, supporting conditionally disabled groups.
Pre-collapsed panels expand when dragged past the halfway point, making collapse and expansion behavior more consistent.
Separator and Panel edge hit target size decreases by default and becomes configurable through a new Group prop.
Double-clicking a Separator resets its associated Panel to its default size when one is configured.
The hook now uses the new layout-change callback while retaining support for the old callback.
Drag interactions call event.preventDefault only for the primary button.
Group now applies default width, height, and overflow styles, which can be overridden with style.
The storage parameter now defaults to localStorage when undefined.
The hook now supports saving and restoring multiple Panel layouts.
Resizable panels can render into a different Window, such as a popup or frame, by accessing globals through the element's owner document.
Expanded support for fixed-size elements, allowing developers to use more fixed-size elements with the library.
Layout-change events are deferred when a Group is within a hidden DOM subtree, improving developer experience.
Size constraints now support pixels, percentages, REMs/EMs, and more.
Support for server-rendering, including Server Components, has been expanded.
Fixes and other changes 68
Group, Panel, Separator, Grid, and Cell only render an explicit id or data-testid as data-testid.
An empty string id now behaves like an undefined id and falls back to useId.
Panel now correctly treats 0 as an explicit id value.
Errors from layout or resize callbacks no longer leave drags stuck or prevent other groups from updating; errors are re-thrown afterward.
Pointer events across documents no longer affect groups mounted in another document, and the resize cursor is limited to the active group's document.
Interrupted drags now end and commit the current layout instead of remaining active until the next pointer event.
Panels and separators are resorted before constraints are re-derived, fixing constraint calculations.
Constraint-induced layout changes no longer permanently alter the layout; the requested layout is restored when the constraint no longer applies.
Separator behind a modal dialog can no longer be dragged.
Panel ordering is fixed in environments with invalid offset values, such as JSDom.
The default layout is respected when an initially hidden group becomes visible.
Keyboard mappings are preserved for disabled separators, fixing the “Matching panels not found” error edge case.
Layout values now match panel IDs so reordered keys map to the correct constraints.
onLayoutChanged still fires when pressing elsewhere on the page or resizing another group.
Detached Separator components no longer capture the pointer.
Separator ARIA values now use proper panel indices.
Construction is guarded to avoid throwing in unsupported environments.
An edge case involving orphaned groups during pointerup was prevented.
The equality check for derived panel constraints was fixed.
Prevents context menu events from occurring while pointer-resize is active.
Improved server rendering support for the defaultSize prop.
Fixed an edge-case bug with pointer event capture.
Separators no longer scroll when receiving focus.
Checks for undefined adoptedStyleSheets to better support environments like jsdom.
Updates the in-memory layout cache when a group is resized by double-clicking on a separator.
Fixed resize actions sometimes jumping on touch devices.
Group now guards against layouts with mis-ordered Panel id keys.
Separator now sets a not-allowed cursor when its parent Group has cursors disabled.
Click events are no longer swallowed in certain cases.
A collapsible panel bugfix was re-enabled after another reported issue was fixed.
Imperative Group.setLayout now persists the layout to the in-memory cache.
The change to collapsible panel behavior from pull request 635 was disabled due to another reported regression.
Re-enables collapsible panels that were disabled in 4.5.6.
Resets separator hover state when the document receives a pointerout event.
Disabled the earlier change to collapsible panel behavior, restoring the previous behavior.
Removed the invalid aria-orientation role from the root Group element to comply with the ARIA specification.
Fixed a regression affecting collapsible Panel behavior that was introduced in 4.5.3.
Panels set max-width and max-height to 100% to fix a potential CSS overflow bug.
Safari now falls back to alternate CSS cursor styles for grab, col-resize, and row-resize cursors.
The library no longer overrides adoptedStyleSheets.
Panels within vertical groups are now sized correctly in Safari.
Fixes cursor style calculation when pointermove events provide low-precision or rounded clientX and clientY values.
Collapsible panels now treat defaultSize={0} as collapsed when mounted.
On pointerup, event.preventDefault() is no longer called unless a handle was actively dragged, fixing a Windows text selection bug.
Panel pixel size is read with offsetWidth/offsetHeight to avoid an edge-case ResizeObserver bug.
Pointerdown and pointerup handlers now use the capture phase for compatibility with UI libraries such as Blueprint JS.
Styles no longer use unset values, improving override safety for applications using the panels.
The useGroupRef type now includes | null for better compatibility with older React versions.
The usePanelRef type now includes | null for better compatibility with older React versions.
The ambiguous onResize prop type was fixed for compatibility with certain TypeScript versions.
Group handles newly registered Panels and Separators during mount, allowing user code to safely call imperative APIs earlier.
A race condition in the hook was fixed for more reliable group ref behavior.
A race condition in the hook was fixed for more reliable panel ref behavior.
Adds a guard for an unexpected defaultView value returned by some development environments.
Panel expand() now restores the size from before the panel was collapsed.
defaultLayout is ignored when its keys do not match Panel ids.
Fixes an edge case where panel constraints were not properly invalidated after resizing.
Group no longer remounts when defaultLayout or disableCursor props change.
Panel id changes are now handled gracefully.
Clicks on higher z-index elements such as modals no longer trigger separators behind them.
Invalid defaultLayout values are now handled gracefully.
Invalid layouts are no longer set when Group is hidden or has a width or height of 0.
Pointer-event styles are reset after the pointerup event, preventing stale interaction styles after pointer release.
Pointer-move delta percentages now account for Flex gap when calculating panel resizing.
Resize user experience is improved on iOS and Safari.
Separator receives focus on pointerdown, improving focus behavior during panel resizing.
Fixed the TypeScript type for the defaultLayout value returned from useDefaultLayout.
Accounts for pointer resize events near the edge of a window or iframe.