sozsoft-platform/ui/src/components/codeLayout/Splitter.tsx

135 lines
4.1 KiB
TypeScript
Raw Normal View History

2026-08-14 11:32:31 +00:00
import React, { useState, useRef, useCallback } from 'react'
2026-02-24 20:44:16 +00:00
interface SplitterProps {
2026-08-14 11:32:31 +00:00
direction: 'horizontal' | 'vertical'
initialSize: number
minSize?: number
maxSize?: number
children: [React.ReactNode, React.ReactNode]
className?: string
reverse?: boolean // İkinci panel için boyut kontrolü
2026-02-24 20:44:16 +00:00
}
export const Splitter: React.FC<SplitterProps> = ({
direction,
initialSize,
minSize = 200,
maxSize = 800,
children,
2026-08-14 11:32:31 +00:00
className = '',
2026-02-24 20:44:16 +00:00
reverse = false,
}) => {
2026-08-14 11:32:31 +00:00
const [size, setSize] = useState(initialSize)
const [isDragging, setIsDragging] = useState(false)
const splitterRef = useRef<HTMLDivElement>(null)
const containerRef = useRef<HTMLDivElement>(null)
2026-02-24 20:44:16 +00:00
const handleMouseDown = useCallback(
(e: React.MouseEvent) => {
2026-08-14 11:32:31 +00:00
e.preventDefault()
setIsDragging(true)
2026-02-24 20:44:16 +00:00
const handleMouseMove = (e: MouseEvent) => {
2026-08-14 11:32:31 +00:00
if (!splitterRef.current || !containerRef.current) return
2026-02-24 20:44:16 +00:00
2026-08-14 11:32:31 +00:00
const rect = containerRef.current.getBoundingClientRect()
let newSize: number
2026-02-24 20:44:16 +00:00
2026-08-14 11:32:31 +00:00
if (direction === 'horizontal') {
2026-02-24 20:44:16 +00:00
if (reverse) {
// İkinci panel için boyut kontrolü - sağdan ölçüm
2026-08-14 11:32:31 +00:00
newSize = rect.right - e.clientX
2026-02-24 20:44:16 +00:00
} else {
// İlk panel için boyut kontrolü - soldan ölçüm
2026-08-14 11:32:31 +00:00
newSize = e.clientX - rect.left
2026-02-24 20:44:16 +00:00
}
} else {
if (reverse) {
// İkinci panel için boyut kontrolü - alttan ölçüm
2026-08-14 11:32:31 +00:00
newSize = rect.bottom - e.clientY
2026-02-24 20:44:16 +00:00
} else {
// İlk panel için boyut kontrolü - üstten ölçüm
2026-08-14 11:32:31 +00:00
newSize = e.clientY - rect.top
2026-02-24 20:44:16 +00:00
}
}
2026-08-14 11:32:31 +00:00
newSize = Math.max(minSize, Math.min(maxSize, newSize))
setSize(newSize)
}
2026-02-24 20:44:16 +00:00
const handleMouseUp = () => {
2026-08-14 11:32:31 +00:00
setIsDragging(false)
document.removeEventListener('mousemove', handleMouseMove)
document.removeEventListener('mouseup', handleMouseUp)
}
2026-02-24 20:44:16 +00:00
2026-08-14 11:32:31 +00:00
document.addEventListener('mousemove', handleMouseMove)
document.addEventListener('mouseup', handleMouseUp)
2026-02-24 20:44:16 +00:00
},
2026-08-14 11:32:31 +00:00
[direction, minSize, maxSize, reverse],
)
2026-02-24 20:44:16 +00:00
2026-08-14 11:32:31 +00:00
const isHorizontal = direction === 'horizontal'
2026-02-24 20:44:16 +00:00
return (
<div
ref={containerRef}
className={`flex flex-1 min-h-0 ${
2026-08-14 11:32:31 +00:00
isHorizontal ? 'flex-row' : 'flex-col'
2026-02-24 20:44:16 +00:00
} h-full w-full ${className}`}
>
{reverse ? (
<>
<div className="flex-1 h-screen overflow-hidden min-w-0 min-h-0">{children[0]}</div>
<div
ref={splitterRef}
className={`
2026-08-14 11:32:31 +00:00
${isHorizontal ? 'w-1 cursor-col-resize' : 'h-1 cursor-row-resize'}
2026-05-19 20:22:25 +00:00
bg-gray-300 dark:bg-gray-700 hover:bg-blue-500 dark:hover:bg-blue-600 transition-colors duration-200 flex-shrink-0
2026-08-14 11:32:31 +00:00
${isDragging ? 'bg-blue-500 dark:bg-blue-600' : ''}
2026-02-24 20:44:16 +00:00
`}
onMouseDown={handleMouseDown}
/>
<div
style={{
2026-08-14 11:32:31 +00:00
[isHorizontal ? 'width' : 'height']: `${size}px`,
[isHorizontal ? 'minWidth' : 'minHeight']: `${size}px`,
[isHorizontal ? 'maxWidth' : 'maxHeight']: `${size}px`,
2026-02-24 20:44:16 +00:00
}}
className="overflow-hidden"
>
{children[1]}
</div>
</>
) : (
<>
<div
style={{
2026-08-14 11:32:31 +00:00
[isHorizontal ? 'width' : 'height']: `${size}px`,
[isHorizontal ? 'minWidth' : 'minHeight']: `${size}px`,
[isHorizontal ? 'maxWidth' : 'maxHeight']: `${size}px`,
2026-02-24 20:44:16 +00:00
}}
className="overflow-hidden"
>
{children[0]}
</div>
<div
ref={splitterRef}
className={`
2026-08-14 11:32:31 +00:00
${isHorizontal ? 'w-1 cursor-col-resize' : 'h-1 cursor-row-resize'}
2026-05-19 20:22:25 +00:00
bg-gray-300 dark:bg-gray-700 hover:bg-blue-500 dark:hover:bg-blue-600 transition-colors duration-200 flex-shrink-0
2026-08-14 11:32:31 +00:00
${isDragging ? 'bg-blue-500 dark:bg-blue-600' : ''}
2026-02-24 20:44:16 +00:00
`}
onMouseDown={handleMouseDown}
/>
<div className="flex-1 h-screen overflow-hidden min-w-0 min-h-0">{children[1]}</div>
</>
)}
</div>
2026-08-14 11:32:31 +00:00
)
}