Resizable split pane layouts for React applications
npm install react-resplitResizable split pane layouts for React applications 🖖
- Compound component API that works with any styling method
- Built with modern CSS, a grid-based layout and custom properties
- Works with any amount of panes in a vertical or horizontal layout
- Built following the Window Splitter pattern for accessibility and keyboard controls
https://github.com/KenanYusuf/react-resplit/assets/9557798/d47ef278-bcb1-4c2b-99e6-7a9f99943f96
_Example of a code editor built with react-resplit_
Run the development server:
```
yarn dev
The files for the development app can be found in src, and the library files in lib.
---
Install the package using your package manager of choice.
``
npm install react-resplit
Import Resplit from react-resplit and render the Root, Pane(s) and Splitter(s).
`tsx
import { Resplit } from 'react-resplit';
function App() {
return (
Pane 1
Pane 2
);
}
`
The Root, Splitter and Pane elements are all unstyled by default apart from a few styles that are necessary for the layout - this is intentional so that the library remains flexible.
Resplit will apply the correct cursor based on the direction provided to the hook.
As a basic example, you could provide a className prop to the Splitter elements and style them as a solid 10px divider.
`tsx`
`css`
.splitter {
width: 100%;
height: 100%;
background: #ccc;
}
Resplit has been implemented using guidence from the Window Splitter pattern.
In addition to built-in accessibility considerations, you should also ensure that splitters are correctly labelled.
If the primary pane has a visible label, the aria-labelledby attribute can be used.
`tsx`
Pane 1
Alternatively, if the pane does not have a visible label, the aria-label attribute can be used on the Splitter instead.
`tsx`
All of the resplit components extend the React.HTMLAttributes interface, so you can pass any valid HTML attribute to them.
The root component of a resplit layout. Provides context to all child components.
| Prop | Type | Default | Description |
| ----------- | ---------------------------- | -------------- | ------------------------------------- |
| direction | "horizontal" \| "vertical" | "horizontal" | Direction of the panes |asChild
| | boolean | false | Merges props onto the immediate child |children
| | ReactNode | | Child elements |className
| | string | | Class name |style
| | CSSProperties | | Style object |
A pane is a container that can be resized.
| Prop | Type | Default | Description |
| --------------- | ------------------------------ | ------------------------------------- | -------------------------------------------------------------------------- |
| order | number | | Specifies the order of the resplit child (pane or splitter) in the DOM |initialSize
| | ${number}fr | [available space]/[number of panes] | Set the initial size of the pane as a fractional unit (fr) |minSize
| | ${number}fr \| ${number}px | "0fr" | Set the minimum size of the pane as a fractional (fr) or pixel (px) unit |collapsible
| | boolean | false | Whether the pane can be collapsed below its minimum size |collapsedSize
| | ${number}fr \| ${number}px | "0fr" | Set the collapsed size of the pane as a fractional (fr) or pixel (px) unit |onResizeStart
| | () => void | | Callback function that is called when the pane starts being resized. |onResize
| | (size: FrValue) => void | | Callback function that is called when the pane is actively being resized. |onResizeEnd
| | (size: FrValue) => void | | Callback function that is called when the pane is actively being resized. |asChild
| | boolean | false | Merges props onto the immediate child |children
| | ReactNode | | Child elements |className
| | string | | Class name |style
| | CSSProperties | | Style object |
A splitter is a draggable element that can be used to resize panes.
| Name | Type | Default | Description |
| ----------- | --------------- | -------- | ---------------------------------------------------------------------- |
| order | number | | Specifies the order of the resplit child (pane or splitter) in the DOM |size
| | ${number}px | "10px" | Set the size of the splitter as a pixel unit |asChild
| | boolean | false | Merges props onto the immediate child |children
| | ReactNode | | Child elements |className
| | string | | Class name |style
| | CSSProperties | | Style object |
The useResplitContext hook provides access to the context of the nearest Resplit.Root component.
See the methods below for more information on what is available.
#### setPaneSizes (paneSizes: FrValue[]) => void
Get the collapsed state of a pane.
Specify the size of each pane as a fractional unit (fr). The number of values should match the number of panes.
`tsx`
setPaneSizes(['0.6fr', '0.4fr']);
If your pane has an onResize callback, it will be called with the new size.
#### isPaneCollapsed (order: number) => boolean
Get the collapsed state of a pane.
Note: The returned value will not update on every render and should be used in a callback e.g. used in combination with a pane's onResize callback.
`tsx
import { Resplit, useResplitContext, ResplitPaneProps, FrValue } from 'react-resplit';
function CustomPane(props: ResplitPaneProps) {
const { isPaneCollapsed } = useResplitContext();
const handleResize = (size: FrValue) => {
if (isPaneCollapsed(props.order)) {
// Do something
}
};
return (
initialSize="0.5fr"
collapsedSize="0.2fr"
collapsible
onResize={handleResize}
/>
);
}
function App() {
return (
);
}
`
#### isPaneMinSize (order: number) => boolean
Get the min size state of a pane.
Note: The returned value will not update on every render and should be used in a callback e.g. used in combination with a pane's onResize callback.
`tsx
import { Resplit, useResplitContext, ResplitPaneProps, FrValue } from 'react-resplit';
function CustomPane(props: ResplitPaneProps) {
const { isPaneMinSize } = useResplitContext();
const handleResize = (size: FrValue) => {
if (isPaneMinSize(props.order)) {
// Do something
}
};
return
}
function App() {
return (
);
}
``