Split Pane
A resizable panel that divides content into two adjustable sections.
1
2
3
4
This component is built on top of Allotment, a lightweight (250 KB unpacked size) and flexible solution for resizable panels. While shadcn/ui uses react-resizable-panel (1.01 MB unpacked size), we opted for Allotment which provides similar core functionality:
- Proportional layout support
- Snap-to-zero capability
- Panel visibility control
- Minimum and maximum size constraints
- Nested layout support
We chose Allotment after encountering the "Max Depth Exceeded" error with react-resizable-panels during drag operations in complex layouts (see issue #456).
Automatic Installation
This method is still working on progress, please use manual installation for now.
Manual Installation
Install dependencies
npm install radix-ui lucide-react allotmentCopy the code
import { Allotment, AllotmentHandle } from 'allotment'
import { Slot } from 'radix-ui'
import * as React from 'react'
import { type SplitPaneStyles, splitPaneStyles } from './split-pane.css'
import 'allotment/dist/style.css'
interface SplitProps
extends React.ComponentPropsWithoutRef<typeof Allotment>,
Omit<SplitPaneStyles, keyof React.ComponentPropsWithoutRef<typeof Allotment>> {}
const Split = React.forwardRef<React.ComponentRef<typeof Allotment>, SplitProps>(
({ className, ...props }, forwardedRef) => {
const styles = splitPaneStyles()
return <Allotment ref={forwardedRef} className={styles.base({ className })} {...props} />
}
)
interface SplitPaneProps
extends React.ComponentPropsWithoutRef<typeof Allotment.Pane>,
Omit<SplitPaneStyles, keyof React.ComponentPropsWithoutRef<typeof Allotment.Pane>> {}
const SplitPane = React.forwardRef<React.ComponentRef<typeof Allotment.Pane>, SplitPaneProps>(
({ className, children, ...props }, forwardedRef) => {
const styles = splitPaneStyles()
return (
<Allotment.Pane ref={forwardedRef} className={styles.pane({ className })} {...props}>
{children}
</Allotment.Pane>
)
}
)
interface SplitPanelProps extends React.ComponentPropsWithoutRef<'div'>, SplitPaneStyles {
asChild?: boolean
}
const SplitPanel = React.forwardRef<HTMLDivElement, SplitPanelProps>(
({ className, asChild = false, ...props }, forwardedRef) => {
const Comp = asChild ? Slot.Root : 'div'
const styles = splitPaneStyles()
return <Comp ref={forwardedRef} className={styles.pane({ className })} {...props} />
}
)
Split.displayName = 'Split'
SplitPane.displayName = 'SplitPane'
SplitPanel.displayName = 'SplitPanel'
export { Split, SplitPane, SplitPanel }
export type { AllotmentHandle as SplitHandle }Usage
Imports
import { Split, SplitPane, SplitPanel } from '#/components/split-pane'Example
Browse the Storybook for more examples.
Anatomy
<Split>
<SplitPane>
<SplitPanel />
</SplitPane>
</Split>Edit on GitHub
Last updated on 3/25/2025