|
1 | | -import { useEffect, useState } from "react"; |
| 1 | +import { useEffect, useRef, useState } from "react"; |
2 | 2 |
|
3 | 3 | const DEFAULT_SIDEBAR_WIDTH = 300; |
4 | 4 | const DEFAULT_SIDEBAR_SPLIT = 50; |
@@ -28,6 +28,10 @@ export function useResize({ |
28 | 28 | const [leftSplit, setLeftSplit] = useState(DEFAULT_SIDEBAR_SPLIT); |
29 | 29 | const [rightSplit, setRightSplit] = useState(DEFAULT_SIDEBAR_SPLIT); |
30 | 30 | const [storageLoaded, setStorageLoaded] = useState(false); |
| 31 | + const leftWidthAtDragStart = useRef(leftWidth); |
| 32 | + const rightWidthAtDragStart = useRef(rightWidth); |
| 33 | + const leftSplitAtDragStart = useRef(leftSplit); |
| 34 | + const rightSplitAtDragStart = useRef(rightSplit); |
31 | 35 |
|
32 | 36 | useEffect(() => { |
33 | 37 | // eslint-disable-next-line react-hooks/set-state-in-effect |
@@ -83,50 +87,64 @@ export function useResize({ |
83 | 87 | }; |
84 | 88 |
|
85 | 89 | const resizeLeftSidebar = (delta: number) => { |
86 | | - setLeftWidth((currentWidth) => { |
87 | | - const maximumWidth = getMaximumSidebarWidth(rightWidth, hasRightSidebar); |
| 90 | + const maximumWidth = getMaximumSidebarWidth(rightWidth, hasRightSidebar); |
88 | 91 |
|
89 | | - return Math.min( |
| 92 | + setLeftWidth( |
| 93 | + clamp( |
| 94 | + leftWidthAtDragStart.current + delta, |
| 95 | + MIN_SIDEBAR_WIDTH, |
90 | 96 | maximumWidth, |
91 | | - Math.max(MIN_SIDEBAR_WIDTH, currentWidth + delta), |
92 | | - ); |
93 | | - }); |
| 97 | + ), |
| 98 | + ); |
94 | 99 | }; |
95 | 100 |
|
96 | 101 | const resizeRightSidebar = (delta: number) => { |
97 | | - setRightWidth((currentWidth) => { |
98 | | - const maximumWidth = getMaximumSidebarWidth(leftWidth, hasLeftSidebar); |
| 102 | + const maximumWidth = getMaximumSidebarWidth(leftWidth, hasLeftSidebar); |
99 | 103 |
|
100 | | - return Math.min( |
| 104 | + setRightWidth( |
| 105 | + clamp( |
| 106 | + rightWidthAtDragStart.current + delta, |
| 107 | + MIN_SIDEBAR_WIDTH, |
101 | 108 | maximumWidth, |
102 | | - Math.max(MIN_SIDEBAR_WIDTH, currentWidth + delta), |
103 | | - ); |
104 | | - }); |
| 109 | + ), |
| 110 | + ); |
105 | 111 | }; |
106 | 112 |
|
107 | | - const getResizedSplit = (currentSplit: number, delta: number) => { |
| 113 | + const getResizedSplit = (splitAtDragStart: number, delta: number) => { |
108 | 114 | const availableHeight = window.innerHeight - islandGap * 3; |
109 | 115 |
|
110 | 116 | if (availableHeight <= 0) { |
111 | | - return currentSplit; |
| 117 | + return splitAtDragStart; |
112 | 118 | } |
113 | 119 |
|
114 | | - return clamp(currentSplit + (delta / availableHeight) * 100, 0, 100); |
| 120 | + return clamp(splitAtDragStart + (delta / availableHeight) * 100, 0, 100); |
115 | 121 | }; |
116 | 122 |
|
117 | 123 | const resizeLeftSidebarSplit = (delta: number) => { |
118 | | - setLeftSplit((currentSplit) => getResizedSplit(currentSplit, delta)); |
| 124 | + setLeftSplit(getResizedSplit(leftSplitAtDragStart.current, delta)); |
119 | 125 | }; |
120 | 126 |
|
121 | 127 | const resizeRightSidebarSplit = (delta: number) => { |
122 | | - setRightSplit((currentSplit) => getResizedSplit(currentSplit, delta)); |
| 128 | + setRightSplit(getResizedSplit(rightSplitAtDragStart.current, delta)); |
123 | 129 | }; |
124 | 130 |
|
125 | 131 | return { |
126 | 132 | leftWidth, |
127 | 133 | rightWidth, |
128 | 134 | leftSplit, |
129 | 135 | rightSplit, |
| 136 | + startResizeLeftSidebar: () => { |
| 137 | + leftWidthAtDragStart.current = leftWidth; |
| 138 | + }, |
| 139 | + startResizeRightSidebar: () => { |
| 140 | + rightWidthAtDragStart.current = rightWidth; |
| 141 | + }, |
| 142 | + startResizeLeftSidebarSplit: () => { |
| 143 | + leftSplitAtDragStart.current = leftSplit; |
| 144 | + }, |
| 145 | + startResizeRightSidebarSplit: () => { |
| 146 | + rightSplitAtDragStart.current = rightSplit; |
| 147 | + }, |
130 | 148 | resizeLeftSidebar, |
131 | 149 | resizeRightSidebar, |
132 | 150 | resizeLeftSidebarSplit, |
|
0 commit comments