Splitter
Create resizable split panes with draggable dividers.
Import
Section titled “Import”import { Splitter } from 'asterui'Examples
Section titled “Examples”Basic Horizontal Splitter
Drag the divider to resize the panels.
Left Panel
Drag the divider to resize.
Right Panel
Content on the right side.
import { Splitter } from 'asterui'
function App() {
return (
<div className="h-64 border border-base-300 rounded-lg overflow-hidden">
<Splitter>
<Splitter.Panel>
<div className="p-4 bg-base-200 h-full">
<h3 className="font-semibold">Left Panel</h3>
<p className="text-sm text-base-content/70 mt-2">Drag the divider to resize.</p>
</div>
</Splitter.Panel>
<Splitter.Panel>
<div className="p-4 h-full">
<h3 className="font-semibold">Right Panel</h3>
<p className="text-sm text-base-content/70 mt-2">Content on the right side.</p>
</div>
</Splitter.Panel>
</Splitter>
</div>
)
}
export default App Vertical Splitter
Split panels vertically.
Top Panel
Bottom Panel
import { Splitter } from 'asterui'
function App() {
return (
<div className="h-64 border border-base-300 rounded-lg overflow-hidden">
<Splitter direction="vertical">
<Splitter.Panel>
<div className="p-4 bg-base-200 h-full">
<h3 className="font-semibold">Top Panel</h3>
</div>
</Splitter.Panel>
<Splitter.Panel>
<div className="p-4 h-full">
<h3 className="font-semibold">Bottom Panel</h3>
</div>
</Splitter.Panel>
</Splitter>
</div>
)
}
export default App Controlled Sizes
Control panel sizes programmatically.
30%
70%
import { Splitter, Button, Space } from 'asterui'
import { useState } from 'react'
function App() {
const [sizes, setSizes] = useState([30, 70]);
return (
<div>
<Space className="mb-4">
<Button size="sm" onClick={() => setSizes([20, 80])}>
20/80
</Button>
<Button size="sm" onClick={() => setSizes([50, 50])}>
50/50
</Button>
<Button size="sm" onClick={() => setSizes([80, 20])}>
80/20
</Button>
</Space>
<div className="h-48 border border-base-300 rounded-lg overflow-hidden">
<Splitter sizes={sizes} onSizesChange={setSizes}>
<Splitter.Panel>
<div className="p-4 bg-primary/10 h-full">{sizes[0].toFixed(0)}%</div>
</Splitter.Panel>
<Splitter.Panel>
<div className="p-4 bg-secondary/10 h-full">{sizes[1].toFixed(0)}%</div>
</Splitter.Panel>
</Splitter>
</div>
</div>
)
}
export default App Multiple Panels
Split into more than two panels.
Panel 1
Panel 2
Panel 3
import { Splitter } from 'asterui'
function App() {
return (
<div className="h-48 border border-base-300 rounded-lg overflow-hidden">
<Splitter defaultSizes={[25, 50, 25]}>
<Splitter.Panel>
<div className="p-4 bg-primary/10 h-full">Panel 1</div>
</Splitter.Panel>
<Splitter.Panel>
<div className="p-4 bg-secondary/10 h-full">Panel 2</div>
</Splitter.Panel>
<Splitter.Panel>
<div className="p-4 bg-accent/10 h-full">Panel 3</div>
</Splitter.Panel>
</Splitter>
</div>
)
}
export default App With Min/Max Sizes
Constrain panel sizes with min and max values.
Min: 100px, Max: 300px
Min: 150px
import { Splitter } from 'asterui'
function App() {
return (
<div className="h-48 border border-base-300 rounded-lg overflow-hidden">
<Splitter>
<Splitter.Panel minSize={100} maxSize={300}>
<div className="p-4 bg-warning/10 h-full">
<p className="text-sm">Min: 100px, Max: 300px</p>
</div>
</Splitter.Panel>
<Splitter.Panel minSize={150}>
<div className="p-4 bg-info/10 h-full">
<p className="text-sm">Min: 150px</p>
</div>
</Splitter.Panel>
</Splitter>
</div>
)
}
export default App Nested Splitters
Combine horizontal and vertical splitters.
Sidebar
Main Content
Terminal
import { Splitter } from 'asterui'
function App() {
return (
<div className="h-72 border border-base-300 rounded-lg overflow-hidden">
<Splitter defaultSizes={[30, 70]}>
<Splitter.Panel>
<div className="p-4 bg-base-200 h-full">
<h3 className="font-semibold">Sidebar</h3>
</div>
</Splitter.Panel>
<Splitter.Panel>
<Splitter direction="vertical" defaultSizes={[60, 40]}>
<Splitter.Panel>
<div className="p-4 h-full">
<h3 className="font-semibold">Main Content</h3>
</div>
</Splitter.Panel>
<Splitter.Panel>
<div className="p-4 bg-base-200 h-full">
<h3 className="font-semibold">Terminal</h3>
</div>
</Splitter.Panel>
</Splitter>
</Splitter.Panel>
</Splitter>
</div>
)
}
export default App Custom Gutter Size
Adjust the gutter (divider) size.
Wide gutter (12px)
Easier to grab
import { Splitter } from 'asterui'
function App() {
return (
<div className="h-48 border border-base-300 rounded-lg overflow-hidden">
<Splitter gutterSize={12}>
<Splitter.Panel>
<div className="p-4 bg-success/10 h-full">Wide gutter (12px)</div>
</Splitter.Panel>
<Splitter.Panel>
<div className="p-4 bg-error/10 h-full">Easier to grab</div>
</Splitter.Panel>
</Splitter>
</div>
)
}
export default App IDE-Style Layout
Complex layout similar to an IDE.
Explorer
import React from 'react'
$ npm run build
import { Splitter, Menu } from 'asterui'
function App() {
return (
<div className="h-80 border border-base-300 rounded-lg overflow-hidden">
<Splitter defaultSizes={[20, 80]}>
<Splitter.Panel minSize={150}>
<div className="h-full bg-base-200">
<div className="p-2 border-b border-base-300 font-semibold text-sm">Explorer</div>
<Menu>
<Menu.Item>src/</Menu.Item>
<Menu.Item>components/</Menu.Item>
<Menu.Item>App.tsx</Menu.Item>
<Menu.Item>index.ts</Menu.Item>
</Menu>
</div>
</Splitter.Panel>
<Splitter.Panel>
<Splitter direction="vertical" defaultSizes={[70, 30]}>
<Splitter.Panel>
<div className="h-full p-4">
<div className="font-mono text-sm">
<span className="text-purple-500">import</span> React{' '}
<span className="text-purple-500">from</span>{' '}
<span className="text-green-500">'react'</span>
</div>
</div>
</Splitter.Panel>
<Splitter.Panel>
<div className="h-full bg-base-300 p-2">
<div className="text-xs font-mono text-base-content/70">$ npm run build</div>
</div>
</Splitter.Panel>
</Splitter>
</Splitter.Panel>
</Splitter>
</div>
)
}
export default App Collapsible Panels
Panels can be collapsed using arrow buttons on the gutter.
Sidebar
Click the arrow to collapse.
Main Content
This panel expands when the sidebar collapses.
import { Splitter } from 'asterui'
function App() {
return (
<div className="h-64 border border-base-300 rounded-lg overflow-hidden">
<Splitter defaultSizes={[25, 75]}>
<Splitter.Panel collapsible minSize={100}>
<div className="p-4 bg-base-200 h-full">
<h3 className="font-semibold">Sidebar</h3>
<p className="text-sm text-base-content/70 mt-2">
Click the arrow to collapse.
</p>
</div>
</Splitter.Panel>
<Splitter.Panel>
<div className="p-4 h-full">
<h3 className="font-semibold">Main Content</h3>
<p className="text-sm text-base-content/70 mt-2">
This panel expands when the sidebar collapses.
</p>
</div>
</Splitter.Panel>
</Splitter>
</div>
)
}
export default App Non-Resizable Panel
Disable resizing for specific panels.
Fixed width (30%)
Cannot resize - divider is disabled.
import { Splitter } from 'asterui'
function App() {
return (
<div className="h-48 border border-base-300 rounded-lg overflow-hidden">
<Splitter>
<Splitter.Panel resizable={false} defaultSize={30}>
<div className="p-4 bg-base-200 h-full">
<p className="text-sm">Fixed width (30%)</p>
</div>
</Splitter.Panel>
<Splitter.Panel>
<div className="p-4 h-full">
<p className="text-sm">Cannot resize - divider is disabled.</p>
</div>
</Splitter.Panel>
</Splitter>
</div>
)
}
export default App Splitter
Section titled “Splitter”| Property | Description | Type | Default |
|---|---|---|---|
direction | Direction of the splitter | 'horizontal' | 'vertical' | 'horizontal' |
sizes | Controlled panel sizes as percentages | number[] | - |
defaultSizes | Default panel sizes as percentages (uncontrolled) | number[] | - |
onSizesChange | Callback when sizes change | (sizes: number[]) => void | - |
gutterSize | Size of the draggable gutter in pixels | number | 8 |
minSize | Default minimum panel size in pixels | number | 50 |
className | Additional CSS classes | string | - |
data-testid | Test ID for testing | string | - |
Splitter.Panel
Section titled “Splitter.Panel”| Property | Description | Type | Default |
|---|---|---|---|
children | Panel content | React.ReactNode | - |
defaultSize | Default size percentage | number | - |
size | Controlled size percentage | number | - |
minSize | Minimum size in pixels | number | - |
maxSize | Maximum size in pixels | number | - |
collapsible | Allow panel to be collapsed | boolean | false |
collapsed | Controlled collapsed state | boolean | - |
defaultCollapsed | Default collapsed state | boolean | false |
onCollapse | Callback when collapse state changes | (collapsed: boolean) => void | - |
resizable | Allow panel to be resized | boolean | true |
className | Additional CSS classes | string | - |
data-testid | Test ID for testing | string | - |
Accessibility
Section titled “Accessibility”- Gutter is keyboard accessible with arrow keys
- ARIA attributes announce current panel sizes
- Focus indicators visible on gutter
- Increase gutterSize for easier touch interaction