SplitPane
splitpane-1779394345462.tsx
'use client'
import { useState, useRef, useCallback } from 'react'
export default function SplitPane({ direction = 'horizontal', minSize = 100 }) {
const [split, setSplit] = useState(50)
const container = useRef(null)
const dragging = useRef(false)
const onMouseDown = () => { dragging.current = true }
const onMouseMove = useCallback((e) => {
if (!dragging.current || !container.current) return
const rect = container.current.getBoundingClientRect()
const pos = direction === 'horizontal' ? e.clientX - rect.left : e.clientY - rect.top
const total = direction === 'horizontal' ? rect.width : rect.height
const pct = Math.min(Math.max((pos / total) * 100, (minSize/total)*100), 100-(minSize/total)*100)
setSplit(pct)
}, [direction, minSize])
const onMouseUp = () => { dragging.current = false }
return (
<div ref={container} onMouseMove={onMouseMove} onMouseUp={onMouseUp} onMouseLeave={onMouseUp}
style={{ display:'flex', flexDirection:direction==='horizontal'?'row':'column', height:'300px', border:'1px solid #e2e8f0', borderRadius:'12px', overflow:'hidden', userSelect:'none' }}>
<div style={{ [direction==='horizontal'?'width':'height']:split+'%', background:'#f8fafc', overflow:'auto', padding:'16px', transition:'none' }}>
<div style={{ fontWeight:600, color:'#374151', marginBottom:'8px', fontSize:'13px', textTransform:'uppercase', letterSpacing:'0.05em' }}>Panel A</div>
<div style={{ fontSize:'13px', color:'#64748b', lineHeight:1.6 }}>Drag the divider to resize panels. This panel contains your primary content area with scrollable content.</div>
</div>
<div onMouseDown={onMouseDown} style={{
[direction==='horizontal'?'width':'height']:'6px',
background:'#e2e8f0', cursor:direction==='horizontal'?'col-resize':'row-resize',
flexShrink:0, position:'relative', display:'flex', alignItems:'center', justifyContent:'center',
}}>
<div style={{ [direction==='horizontal'?'width':'height']:'2px', [direction==='horizontal'?'height':'width']:'24px', background:'#94a3b8', borderRadius:'1px' }} />
</div>
<div style={{ flex:1, background:'#fff', overflow:'auto', padding:'16px' }}>
<div style={{ fontWeight:600, color:'#374151', marginBottom:'8px', fontSize:'13px', textTransform:'uppercase', letterSpacing:'0.05em' }}>Panel B</div>
<div style={{ fontSize:'13px', color:'#64748b', lineHeight:1.6 }}>Secondary content area. The split ratio is {Math.round(split)}% / {Math.round(100-split)}%.</div>
</div>
</div>
)
}Component info
CategoryLayouts
Frameworkreact
TierFREE
Views0
Copies0
About
Resizable split pane with horizontal or vertical orientation
More from Layouts
'use client'
import { useState, useRef, useCallback, useEffect } from 'react'
export default function SplitPane() {
const [split, setSplit] = useState(50)
const [dragging, setDragging] = useState(false)
const [collapsed, setCollapsed] = useStaSplitPane
Layouts
'use client'
import { useState } from 'react'
interface Block {
id: number
label: string
color: string
colSpan: number
rowSpan: number
}
const INITIAL: Block[] = [
{ id: 1, label: 'Header', color: '#C9A84C', colSpan: 12, rowSpan: 1 },
GridLayout
Layouts
'use client'
import { useState } from 'react'
const ITEMS = [
{ id: 1, title: 'What is Empire UI?', content: 'Empire UI is a library of 17,500 AI-generated React components.' },
{ id: 2, title: 'How to install?', content: 'Install via npm or useAccordion
Layouts
'use client'
import { useState } from 'react'
const INIT = [
{ id:1, label:'Design System Audit', priority:'P1' },
{ id:2, label:'API Integration', priority:'P2' },
{ id:3, label:'Performance Review', priority:'P1' },
{ id:4, label:'Mobile RDragList
Layouts