forked from accordproject/template-playground
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResizableContainer.tsx
More file actions
119 lines (106 loc) · 3.43 KB
/
ResizableContainer.tsx
File metadata and controls
119 lines (106 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { useEffect, useRef, useState } from 'react';
import useAppStore from '../store/store';
interface ResizableContainerProps {
leftPane: React.ReactNode;
rightPane: React.ReactNode;
initialLeftWidth?: number;
minLeftWidth?: number;
minRightWidth?: number;
}
const ResizableContainer: React.FC<ResizableContainerProps> = ({
leftPane,
rightPane,
initialLeftWidth = 66,
minLeftWidth = 30,
minRightWidth = 30,
}) => {
const [leftWidth, setLeftWidth] = useState(
Number(localStorage.getItem('editorPaneWidth')) || initialLeftWidth
);
const containerRef = useRef<HTMLDivElement>(null);
const isDragging = useRef(false);
const backgroundColor = useAppStore((state) => state.backgroundColor);
const [isHovered, setIsHovered] = useState(false);
useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
if (!isDragging.current || !containerRef.current) return;
const container = containerRef.current;
const containerRect = container.getBoundingClientRect();
const containerWidth = containerRect.width;
const mouseX = e.clientX - containerRect.left;
const newLeftWidth = (mouseX / containerWidth) * 100;
if (newLeftWidth >= minLeftWidth && (100 - newLeftWidth) >= minRightWidth) {
setLeftWidth(newLeftWidth);
localStorage.setItem('editorPaneWidth', newLeftWidth.toString());
}
};
const handleMouseUp = () => {
isDragging.current = false;
document.body.style.cursor = 'default';
};
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp);
return () => {
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
};
}, [minLeftWidth, minRightWidth]);
const [isMobile, setIsMobile] = useState(window.innerWidth <= 575);
useEffect(() => {
const handleResize = () => {
setIsMobile(window.innerWidth <= 575);
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return (
<div
ref={containerRef}
style={{
display: 'flex',
width: '100%',
position: 'relative',
backgroundColor,
flexDirection: isMobile ? 'column' : 'row',
height: '100%',
overflow: isMobile ? 'auto' : 'hidden'
}}
>
<div style={{
width: isMobile ? '100%' : `${leftWidth}%`,
height: isMobile ? 'auto' : '100%',
overflow: 'hidden'
}}>
{leftPane}
</div>
{!isMobile && (
<div
style={{
width: '8px',
cursor: 'col-resize',
background: isHovered || isDragging.current ? '#999' : '#ccc',
position: 'relative',
zIndex: 10,
userSelect: 'none',
transition: 'background-color 0.2s'
}}
onMouseDown={() => {
isDragging.current = true;
document.body.style.cursor = 'col-resize';
}}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
/>
)}
<div style={{
width: isMobile ? '100%' : `${100 - leftWidth}%`,
height: isMobile ? 'auto' : '100%',
overflow: 'hidden',
marginTop: isMobile ? '4px' : '0'
}}>
{rightPane}
</div>
</div>
);
};
export default ResizableContainer;