### Install react-resizable-panels with npm
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/README.md
Install the library from NPM to begin using it in your React project.
```sh
npm install react-resizable-panels
```
--------------------------------
### Install dependencies
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/CONTRIBUTING.md
Installs project dependencies.
```shell
pnpm install
```
--------------------------------
### Panel with Resize Callback Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-panel.md
Shows how to use the 'onResize' callback to get real-time updates on a panel's size. The callback receives 'PanelSize' object with percentage and pixel values.
```typescript
export function PanelWithCallback() {
const [size, setSize] = useState('');
const handleResize = (panelSize: PanelSize) => {
setSize(`${panelSize.asPercentage.toFixed(1)}% (${panelSize.inPixels}px)`);
};
return (
<>
Current size: {size}
Resizable Panel
Other Panel
>
);
}
```
--------------------------------
### Run documentation site locally
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/CONTRIBUTING.md
Starts the documentation site on localhost port 3000.
```shell
pnpm dev
```
--------------------------------
### Get Panel Size Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-panel.md
Demonstrates how to retrieve the current size of a panel in both pixels and percentage using the `getSize()` method. The returned object contains `asPercentage` and `inPixels` properties.
```typescript
const panelRef = useRef(null);
function MyComponent() {
const handleGetSize = () => {
const size = panelRef.current?.getSize();
console.log(`Size: ${size?.asPercentage}% (${size?.inPixels}px)`);
};
return (
<>
Content
>
);
}
```
--------------------------------
### Get Panel Size Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/types.md
Demonstrates how to retrieve the current size of a panel using its imperative handle. Ensure the panelRef is correctly assigned.
```typescript
const panelRef = useRef(null);
const handleGetSize = () => {
const size = panelRef.current?.getSize();
console.log(`${size?.asPercentage}% (${size?.inPixels}px)`);
// Output: "33.3% (400px)"
};
```
--------------------------------
### Basic Two-Panel Layout Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/getting-started.md
A practical example of a responsive two-panel layout using Group, Panel, and Separator. This is suitable for common sidebar and main content arrangements.
```typescript
import { Group, Panel, Separator } from 'react-resizable-panels';
export function BasicLayout() {
return (
Sidebar
Main Content
);
}
```
--------------------------------
### OnPanelResize Callback Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/types.md
Example of implementing the onResize callback to log changes in panel size, including the panel's ID and its previous dimensions. The prevPanelSize will be undefined on initial mount.
```jsx
{
console.log(`Panel ${id} resized from ${prevSize?.inPixels}px to ${size.inPixels}px`);
}}
>
Content
```
--------------------------------
### Panel Size Format Options
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/configuration.md
Examples demonstrating various formats for Panel size properties like defaultSize, minSize, and maxSize.
```typescript
// Numeric: pixels
defaultSize={300}
// Percentage strings
defaultSize="50%"
defaultSize="33.33%"
// Percentage numbers (no units)
minSize={25} // 25%
// Pixel strings
minSize="100px"
// Relative units
minSize="1em"
minSize="2rem"
// Viewport units
minSize="10vh" // 10% of viewport height
minSize="5vw" // 5% of viewport width
```
--------------------------------
### useDefaultLayout with Custom Storage
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/configuration.md
Example of initializing useDefaultLayout with a custom storage implementation.
```typescript
// Custom storage implementation
const customStorage: LayoutStorage = {
getItem: (key) => { /* ... */ },
setItem: (key, value) => { /* ... */ }
};
useDefaultLayout({
id: 'my-layout',
storage: customStorage
})
```
--------------------------------
### useDefaultLayout with Default Storage
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/configuration.md
Example of initializing useDefaultLayout with the default localStorage storage.
```typescript
// Use localStorage (default)
useDefaultLayout({ id: 'my-layout' })
```
--------------------------------
### Expand Panel Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-panel.md
Shows how to expand a collapsed panel using the `expand()` method. This is useful for restoring a panel's previous size after it has been collapsed.
```typescript
const panelRef = useRef(null);
function MyComponent() {
const handleExpand = () => {
panelRef.current?.expand();
};
return (
<>
Content
>
);
}
```
--------------------------------
### Example: Larger Touch Targets for Resize
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/configuration.md
Demonstrates how to increase the minimum hit target size for touch devices to improve accessibility.
```typescript
{/* panels */}
```
--------------------------------
### Basic Horizontal Layout Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-group.md
Demonstrates a simple horizontal layout with two panels and a separator.
```typescript
import { Group, Panel, Separator } from 'react-resizable-panels';
export function BasicLayout() {
return (
Left Panel
Right Panel
);
}
```
--------------------------------
### Imperative Panel Control Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-group.md
Demonstrates how to control panel layouts imperatively using `useRef` and `GroupImperativeHandle`.
```typescript
import { Group, Panel, Separator } from 'react-resizable-panels';
import { useRef } from 'react';
import type { GroupImperativeHandle } from 'react-resizable-panels';
export function ImperativeControl() {
const groupRef = useRef(null);
const resetLayout = () => {
groupRef.current?.setLayout({ panel1: 50, panel2: 50 });
};
const logLayout = () => {
const layout = groupRef.current?.getLayout();
console.log('Layout:', layout);
};
return (
<>
Panel 1
Panel 2
>
);
}
```
--------------------------------
### Panel Size Properties Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/types.md
Illustrates how to use different SizeUnits for panel properties like defaultSize, minSize, and maxSize. Numeric values for defaultSize are interpreted as pixels.
```jsx
```
--------------------------------
### Run end-to-end tests locally
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/CONTRIBUTING.md
Installs end-to-end test dependencies and runs the tests.
```shell
pnpm prerelease
pnpm e2e:install
pnpm dev:integrations & pnpm e2e:test
```
--------------------------------
### Panel with Size Constraints Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-panel.md
Illustrates setting minimum and maximum size constraints for a panel using pixel or percentage values. 'minSize' and 'maxSize' props are used.
```typescript
export function ConstrainedPanel() {
return (
Constrained Panel
Other Panel
);
}
```
--------------------------------
### Collapse Panel Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-panel.md
Demonstrates how to collapse a panel programmatically using the `collapse()` method. Ensure the panel is marked as `collapsible` and has a `collapsedSize` defined.
```typescript
const panelRef = useRef(null);
function MyComponent() {
const handleCollapse = () => {
panelRef.current?.collapse();
};
return (
<>
Content
>
);
}
```
--------------------------------
### useDefaultLayout with Session Storage
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/configuration.md
Example of initializing useDefaultLayout to use sessionStorage for layout persistence.
```typescript
// Use sessionStorage
useDefaultLayout({
id: 'my-layout',
storage: sessionStorage
})
```
--------------------------------
### Resize Panel Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-panel.md
Shows various ways to resize a panel using the `resize()` method. It accepts numbers (pixels), pixel strings, percentage strings, relative units, and viewport units.
```typescript
const panelRef = useRef(null);
function MyComponent() {
const handleResize = () => {
// All of these are valid:
panelRef.current?.resize(200); // 200 pixels
panelRef.current?.resize("200px"); // 200 pixels
panelRef.current?.resize(50); // 50%
panelRef.current?.resize("50%"); // 50%
panelRef.current?.resize("1rem"); // 1rem relative to font size
panelRef.current?.resize("50vh"); // 50% of viewport height
};
return (
<>
Content
>
);
}
```
--------------------------------
### Vertical Layout with Callbacks Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-group.md
Illustrates a vertical layout with `onLayoutChange` and `onLayoutChanged` callbacks to monitor layout updates.
```typescript
export function VerticalWithCallbacks() {
const handleLayoutChange = (layout: Layout) => {
console.log('Layout changing:', layout);
};
const handleLayoutChanged = (layout: Layout, meta: LayoutChangedMeta) => {
console.log('Layout changed:', layout);
console.log('User interaction:', meta.isUserInteraction);
// Persist to storage here
};
return (
Top PanelBottom Panel
);
}
```
--------------------------------
### Update assets
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/CONTRIBUTING.md
Updates generated docs and examples, and runs code formatting and linting.
```shell
pnpm compile
pnpm prettier
pnpm lint
```
--------------------------------
### Example of Mixed Size Units in Panels
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/configuration.md
Demonstrates using mixed units for size constraints within a group of panels.
```typescript
Mixed size constraints
Also mixed
```
--------------------------------
### Collapsible Panel Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/README.md
Illustrates how to make a panel collapsible, allowing it to be collapsed to a specific size, such as zero. Useful for sidebars or elements that can be hidden.
```typescript
Sidebar
```
--------------------------------
### Importing Components, Hooks, and Types
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/README.md
Provides a comprehensive guide to importing all necessary components, hooks, and types from the 'react-resizable-panels' library. Ensure these imports are present in your project files.
```typescript
// Components
import { Group, Panel, Separator } from 'react-resizable-panels';
// Hooks
import {
useGroupRef,
useGroupCallbackRef,
usePanelRef,
usePanelCallbackRef,
useDefaultLayout,
isCoarsePointer
} from 'react-resizable-panels';
// Types
import type {
GroupImperativeHandle,
GroupProps,
PanelImperativeHandle,
PanelProps,
SeparatorProps,
Layout,
PanelSize,
Orientation,
LayoutStorage,
LayoutChangedMeta,
SizeUnit,
GroupResizeBehavior,
} from 'react-resizable-panels';
```
--------------------------------
### Integrating React-Specific ESLint Plugins
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/integrations/vite/README.md
Example of how to integrate eslint-plugin-react-x and eslint-plugin-react-dom into the ESLint configuration.
```javascript
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
export default tseslint.config({
plugins: {
// Add the react-x and react-dom plugins
'react-x': reactX,
'react-dom': reactDom,
},
rules: {
// other rules...
// Enable its recommended typescript rules
...reactX.configs['recommended-typescript'].rules,
...reactDom.configs.recommended.rules,
},
})
```
--------------------------------
### Panel with Imperative Control Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-panel.md
Demonstrates controlling a panel's size and state imperatively using a ref. The 'PanelImperativeHandle' provides methods like 'resize', 'collapse', and 'expand'.
```typescript
import type { PanelImperativeHandle } from 'react-resizable-panels';
export function ImperativePanel() {
const panelRef = useRef(null);
return (
<>
Controlled Panel
>
);
}
```
--------------------------------
### Nested Layout Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/README.md
Shows how to create complex layouts by nesting groups of panels within other panels. This allows for unlimited depth and intricate UI structures.
```typescript
LeftTop-rightBottom-right
```
--------------------------------
### Implement Animated Panel Transitions
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/advanced-guide.md
Create smooth animated transitions for panel resizing using `requestAnimationFrame` for custom animation loops. This example animates a panel to a target size over 300ms with an ease-in-out quadratic easing function.
```typescript
export function AnimatedPanels() {
const panelRef = usePanelRef();
const [animating, setAnimating] = useState(false);
const animateResize = async (targetSize: number) => {
setAnimating(true);
const startTime = Date.now();
const duration = 300; // 300ms animation
const startSize = panelRef.current?.getSize().asPercentage ?? 50;
const animate = () => {
const elapsed = Date.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
const easeInOutQuad = progress < 0.5
? 2 * progress * progress
: -1 + (4 - 2 * progress) * progress;
const currentSize = startSize + (targetSize - startSize) * easeInOutQuad;
panelRef.current?.resize(currentSize);
if (progress < 1) {
requestAnimationFrame(animate);
} else {
setAnimating(false);
}
};
requestAnimationFrame(animate);
};
return (
<>
Animated Panel
Other
>
);
}
```
--------------------------------
### Zustand Integration for Layout State
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/patterns-and-examples.md
Integrate layout state management with Zustand using its persistence middleware. This example shows how to define a store and update the layout.
```typescript
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
const useLayoutStore = create(
persist(
(set) => ({
layout: undefined,
setLayout: (layout) => set({ layout }),
}),
{ name: 'layout-storage' }
)
);
export function ZustandLayout() {
const { layout, setLayout } = useLayoutStore();
return (
{
if (meta.isUserInteraction) {
setLayout(newLayout);
}
}}
>
{/* panels */}
);
}
```
--------------------------------
### Panel Resize Behavior Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/types.md
Demonstrates using 'preserve-relative-size' for flexible panels and 'preserve-pixel-size' for fixed-size panels within a group. Note the constraint that at least one panel must use 'preserve-relative-size'.
```jsx
{/* This panel shrinks/grows with group */}
Flexible
{/* This panel stays same pixel size */}
Fixed
```
--------------------------------
### Expanding ESLint Configuration with Type-Aware Rules
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/integrations/vite/README.md
Example of how to extend the ESLint configuration to include type-aware lint rules for TypeScript projects.
```javascript
export default tseslint.config({
extends: [
// Remove ...tseslint.configs.recommended and replace with this
...tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
...tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
...tseslint.configs.stylisticTypeChecked,
],
languageOptions: {
// other options...
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
},
})
```
--------------------------------
### Handle Storage Quotas with `useDefaultLayout`
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/advanced-guide.md
If storage quotas are exceeded, consider using `sessionStorage` for temporary storage or implementing custom quota management. This example shows using `sessionStorage` to avoid quota issues.
```typescript
try {
localStorage.setItem('test', 'large-data');
} catch (e) {
console.error('Storage quota exceeded:', e);
}
// Solution: Use sessionStorage or implement quota management
const { defaultLayout, onLayoutChanged } = useDefaultLayout({
id: 'layout',
storage: sessionStorage, // Clears on page close
});
```
--------------------------------
### VS Code-Style Three-Panel Layout
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/patterns-and-examples.md
This example mimics the VS Code editor layout, featuring a sidebar, main editor area, and a bottom panel. It utilizes nested groups for horizontal and vertical resizing and includes collapsible panels.
```typescript
import { Group, Panel, Separator } from 'react-resizable-panels';
import { useDefaultLayout } from 'react-resizable-panels';
export function VSCodeLayout() {
const { defaultLayout, onLayoutChanged } = useDefaultLayout({
id: 'vscode-layout',
panelIds: ['sidebar', 'editor', 'panel'],
});
return (
{/* Top menu bar */}
VS Code Layout
{/* Main resizable area */}
{/* Sidebar */}
Explorer
📁 src/
📁 public/
📄 package.json
{/* Editor area with nested vertical split */}
src/App.tsx
{/* Editor content */}
Terminal
npm run dev
{/* Side panel */}
Problem
No problems found
);
}
```
--------------------------------
### Get and Set Group Layout with useGroupRef
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/hooks-reference.md
Use `useGroupRef` to get a ref for the Group component's imperative API. This allows you to programmatically get or set the layout of the panels.
```typescript
import { Group, Panel, Separator, useGroupRef } from 'react-resizable-panels';
export function MyComponent() {
const groupRef = useGroupRef();
const handleGetLayout = () => {
const layout = groupRef.current?.getLayout();
console.log('Current layout:', layout);
};
const handleResetLayout = () => {
groupRef.current?.setLayout({
panel1: 50,
panel2: 50
});
};
return (
<>
Panel 1Panel 2
>
);
}
```
--------------------------------
### Basic Panel Usage
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-panel.md
Demonstrates how to set up a basic resizable panel group with two panels and a separator. Ensure 'react-resizable-panels' is imported.
```typescript
import { Group, Panel, Separator } from 'react-resizable-panels';
export function BasicPanel() {
return (
Resizable Content
More Content
);
}
```
--------------------------------
### Development Server Commands
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/integrations/next/README.md
Commands to run the development server using different package managers.
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
--------------------------------
### Use usePanelCallbackRef in a Component
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/hooks-reference.md
Demonstrates how to use the usePanelCallbackRef hook to get a ref for a Panel component and pass it to child controls for interaction.
```typescript
import { Group, Panel, Separator, usePanelCallbackRef } from 'react-resizable-panels';
function PanelControls({ panelRef }) {
return (
);
}
export function MyComponent() {
const [panelRef, setPanelRef] = usePanelCallbackRef();
return (
<>
Controlled Panel
Other Panel
>
);
}
```
--------------------------------
### Get Group Layout
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-group.md
Retrieves the current layout of the panels within a group. Use this to inspect the current state of panel sizes.
```typescript
interface GroupImperativeHandle {
getLayout(): { [panelId: string]: number };
setLayout(layout: { [panelId: string]: number }): Layout;
}
```
```typescript
const groupRef = useRef(null);
function MyComponent() {
const handleGetLayout = () => {
const layout = groupRef.current?.getLayout();
console.log('Current layout:', layout);
// Output: { panel1: 33.33, panel2: 66.67 }
};
return (
<>
{/* panels */}
>
);
}
```
--------------------------------
### Check if Panel is Collapsed Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-panel.md
Illustrates how to check if a panel is currently collapsed using the `isCollapsed()` method. This returns a boolean value.
```typescript
const panelRef = useRef(null);
function MyComponent() {
const checkCollapsed = () => {
const collapsed = panelRef.current?.isCollapsed();
console.log('Is collapsed:', collapsed);
};
return (
<>
Content
>
);
}
```
--------------------------------
### Responsive Layout Based on Screen Size
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/README.md
Demonstrates how to create a responsive layout that adjusts its orientation based on screen size (e.g., mobile vs. desktop). Use this to adapt layouts for different devices.
```typescript
{/* panels */}
```
--------------------------------
### Basic Layout Persistence with localStorage
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/hooks-reference.md
Demonstrates how to use the useDefaultLayout hook to save and restore panel layouts using localStorage. This is useful for maintaining user-defined panel sizes across sessions.
```typescript
import { Group, Panel, Separator, useDefaultLayout } from 'react-resizable-panels';
export function PersistentLayout() {
const { defaultLayout, onLayoutChanged } = useDefaultLayout({
id: 'my-layout',
storage: localStorage,
});
return (
Left Panel
Right Panel
);
}
```
--------------------------------
### Disabled Separator Example
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-separator.md
Disables user interaction with the separator using the `disabled` prop. A checkbox controls the disabled state of the separator.
```typescript
import { useState } from 'react';
import { Group, Panel, Separator } from 'react-resizable-panels';
export function DisabledSeparator() {
const [separatorDisabled, setSeparatorDisabled] = useState(false);
return (
<>
LeftRight
>
);
}
```
--------------------------------
### PanelImperativeHandle
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/types.md
Provides an imperative API for controlling Panel components, including methods to collapse, expand, get size, check collapsed state, and resize.
```APIDOC
## PanelImperativeHandle
### Description
Imperative API for Panel component.
### Interface Definition
```typescript
interface PanelImperativeHandle {
collapse(): void;
expand(): void;
getSize(): { asPercentage: number; inPixels: number };
isCollapsed(): boolean;
resize(size: number | string): void;
}
```
### Methods
- `collapse()`: Collapse panel to `collapsedSize` (if collapsible).
- `expand()`: Expand collapsed panel to previous size.
- `getSize()`: Get current size in percentage and pixels.
- `isCollapsed()`: Check if panel is collapsed.
- `resize(size)`: Set panel size (supports all size formats).
```
--------------------------------
### Apply Dynamic Size Constraints
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/advanced-guide.md
Implement responsive panel sizing by dynamically adjusting `minSize` and `maxSize` props based on window dimensions. Requires a `useEffect` hook to track window resize events.
```typescript
export function ResponsiveConstraints() {
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWindowWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
const minSidebarSize = windowWidth < 768 ? '60px' : '150px';
const maxSidebarSize = windowWidth < 768 ? '120px' : '400px';
return (
Sidebar
Main
);
}
```
--------------------------------
### Desktop-Friendly Group Configuration
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/configuration.md
Configure a Group component for desktop usage with `resizeTargetMinimumSize` optimized for mouse and trackpad precision. Panels have specific default and minimum sizes.
```typescript
Sidebar
Content
```
--------------------------------
### Strict Size Constraints with Fixed and Flexible Panels
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/configuration.md
Configure panels with strict size constraints, including a fixed-size panel using `minSize` and `maxSize` set to the same value, and a flexible panel that can grow to fill available space.
```typescript
Fixed Width Sidebar
Flexible Content
```
--------------------------------
### Documentation File Structure
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/README.md
This snippet shows the directory structure of the project's documentation files. Each file corresponds to a specific aspect of the library.
```markdown
/output/
├── README.md (this file)
├── getting-started.md (introduction)
├── api-reference-group.md (Group component)
├── api-reference-panel.md (Panel component)
├── api-reference-separator.md (Separator component)
├── hooks-reference.md (all hooks)
├── types.md (type definitions)
├── configuration.md (options and config)
├── patterns-and-examples.md (real-world patterns)
└── advanced-guide.md (troubleshooting, advanced)
```
--------------------------------
### Next.js App Router Layout
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/configuration.md
Configure layout for Next.js App Router by marking the component as a Client Component and using `useDefaultLayout`. No special `panelIds` are required for basic setup.
```typescript
'use client'; // Mark as Client Component
import { Group, Panel, Separator, useDefaultLayout } from 'react-resizable-panels';
export function AppLayout() {
const { defaultLayout, onLayoutChanged } = useDefaultLayout({
id: 'nextjs-layout',
});
return (
{/* panels */}
);
}
```
--------------------------------
### Use usePanelRef for Imperative Panel Control
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/hooks-reference.md
Demonstrates how to use the usePanelRef hook to get a ref for a Panel component and call its imperative methods like resize, getSize, collapse, expand, and isCollapsed.
```typescript
import { Group, Panel, Separator, usePanelRef } from 'react-resizable-panels';
export function MyComponent() {
const panelRef = usePanelRef();
const handleResize = () => {
panelRef.current?.resize('300px');
};
const handleGetSize = () => {
const size = panelRef.current?.getSize();
console.log(`Size: ${size?.asPercentage}% (${size?.inPixels}px)`);
};
const handleCollapse = () => {
panelRef.current?.collapse();
};
const handleExpand = () => {
panelRef.current?.expand();
};
const checkCollapsed = () => {
const isCollapsed = panelRef.current?.isCollapsed();
console.log('Collapsed:', isCollapsed);
};
return (
<>
Controlled Panel
Other Panel
>
);
}
```
--------------------------------
### Basic Separator Usage
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-separator.md
Demonstrates the basic implementation of a horizontal separator between two panels. Ensure 'react-resizable-panels' is imported.
```typescript
import { Group, Panel, Separator } from 'react-resizable-panels';
export function BasicSeparator() {
return (
Left Panel
Right Panel
);
}
```
--------------------------------
### Panel Component Configuration
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/getting-started.md
Shows how to configure a single Panel with various props like size constraints, collapsible behavior, and an ID. Use this to define individual content areas within a group.
```typescript
Panel Content
```
--------------------------------
### Server-Rendering Safe Layout Persistence
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/hooks-reference.md
Demonstrates a server-rendering safe approach for layout persistence using useDefaultLayout. The hook's internal use of `useSyncExternalStore` handles client-only storage like localStorage without causing hydration mismatches.
```typescript
export function ServerSafeLayout() {
const { defaultLayout, onLayoutChanged } = useDefaultLayout({
id: 'ssr-layout',
// useSyncExternalStore prevents hydration mismatch when storage
// is client-only (e.g., localStorage)
});
return (
LeftRight
);
}
```
--------------------------------
### Persistent Layout with State Management
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/README.md
Shows how to implement a persistent layout that saves and restores its state. Use this when user layout preferences need to be maintained across sessions.
```typescript
const { defaultLayout, onLayoutChanged } = useDefaultLayout({ id: 'layout' });
{/* panels */}
```
--------------------------------
### Synchronize Layouts Between Panel Groups
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/patterns-and-examples.md
Enable two separate panel groups to share the same layout configuration. A button click triggers a sync, applying the layout from one group to another using `getLayout` and `setLayout`.
```typescript
export function SynchronizedLayouts() {
const layout1Ref = useGroupRef();
const layout2Ref = useGroupRef();
const syncLayout = () => {
const layout = layout1Ref.current?.getLayout();
if (layout) {
layout2Ref.current?.setLayout(layout);
}
};
return (
<>
Layout 1
Panel A1Panel B1
Layout 2
Panel A2Panel B2
>
);
}
```
--------------------------------
### Run unit tests locally
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/CONTRIBUTING.md
Executes unit tests for the project.
```shell
pnpm test
```
--------------------------------
### Mobile-Friendly Group Configuration
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/configuration.md
Configure a Group component for touch devices with larger `resizeTargetMinimumSize` values for 'coarse' (touch) input. Includes fallback for 'fine' (mouse) input.
```typescript
Panel 1
Panel 2
```
--------------------------------
### resize()
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/api-reference-panel.md
Updates the panel's size. Accepts various size formats including numeric pixels, percentage strings, pixel strings, relative units, and viewport units.
```APIDOC
## resize()
### Description
Updates the panel's size. Accepts multiple size formats.
### Signature
```typescript
resize(size: number | string): void
```
### Parameters
- `size`: New panel size in any supported format:
- Numeric values are assumed to be pixels
- Strings without units are assumed to be percentages (e.g., "33")
- Percentage strings: "50%"
- Pixel strings: "200px"
- Relative units: "1rem", "2em"
- Viewport units: "50vh", "25vw"
### Example
```typescript
const panelRef = useRef(null);
function MyComponent() {
const handleResize = () => {
// All of these are valid:
panelRef.current?.resize(200); // 200 pixels
panelRef.current?.resize("200px"); // 200 pixels
panelRef.current?.resize(50); // 50%
panelRef.current?.resize("50%"); // 50%
panelRef.current?.resize("1rem"); // 1rem relative to font size
panelRef.current?.resize("50vh"); // 50% of viewport height
};
return (
<>
Content
>
);
}
```
```
--------------------------------
### Handle Empty Layouts with Missing Panel IDs
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/advanced-guide.md
Demonstrates how the library handles `Layout` objects where panel IDs might be missing. The library automatically assigns sizes to the remaining panels.
```typescript
const layout: Layout = {
left: 50,
// right panel ID missing
};
LeftRight {/* Gets auto-assigned size */}
```
--------------------------------
### useDefaultLayout Options Reference
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/configuration.md
Configuration options for the useDefaultLayout hook. Specify layout ID, storage, panel IDs, and save behavior.
```typescript
useDefaultLayout({
// Required: one of id or groupId
id?: string; // Preferred: unique layout identifier
groupId?: string; // Deprecated: use 'id' instead
// Optional: persistence configuration
storage?: LayoutStorage; // Default: localStorage
// Optional: conditional panel support
panelIds?: string[]; // Panel IDs for conditional rendering
// Optional: save behavior
onlySaveAfterUserInteractions?: boolean; // Default: false
// Deprecated: debounce configuration
debounceSaveMs?: number; // Default: 100ms (deprecated)
})
```
--------------------------------
### Layout Persistence with Custom Storage Implementation
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/hooks-reference.md
Illustrates using a custom storage object with useDefaultLayout, such as cookie-based storage. The custom storage must implement getItem and setItem methods compatible with the hook's expectations.
```typescript
// Example: cookie-based storage
const cookieStorage = {
getItem: (key: string) => {
const cookies = document.cookie.split(';');
for (const cookie of cookies) {
const [name, value] = cookie.trim().split('=');
if (name === key) return decodeURIComponent(value);
}
return null;
},
setItem: (key: string, value: string) => {
document.cookie = `${key}=${encodeURIComponent(value)};path=/`;
}
};
export function CookieStorageLayout() {
const { defaultLayout, onLayoutChanged } = useDefaultLayout({
id: 'cookie-layout',
storage: cookieStorage,
});
return (
LeftRight
);
}
```
--------------------------------
### Test Panel Resizing with User Events
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/patterns-and-examples.md
Use `@testing-library/user-event` to simulate user interactions like dragging a separator to test panel resizing functionality. Ensure the layout changes as expected after the interaction.
```typescript
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
describe('ResizablePanel', () => {
it('resizes panels via separator', async () => {
const { getByTestId } = render(
Left
Right
);
const separator = getByTestId('sep');
// Simulate drag
await userEvent.pointer({
keys: '[MouseLeft>]',
target: separator,
coords: { x: 100, y: 0 },
});
// Verify layout changed
const layout = /* get from component */ {};
expect(layout.left).not.toBe(50);
});
});
```
--------------------------------
### useDefaultLayout with Conditional Panels
Source: https://github.com/bvaughn/react-resizable-panels/blob/main/_autodocs/configuration.md
Demonstrates configuring useDefaultLayout for conditionally rendered panels by specifying all possible panel IDs.
```typescript
const { defaultLayout, onLayoutChanged } = useDefaultLayout({
id: 'conditional-layout',
panelIds: ['sidebar', 'main', 'footer'], // All possible panels
});
// Can now conditionally render any combination
{showSidebar && (
<>
Sidebar
>
)}
MainFooter
```