@@ -57,11 +57,17 @@ export const ResizableSidebar: React.FC<ResizableSidebarProps> = ({
5757 // SIDEBAR_MIN_WIDTH on the way to the edge, so if the drag ends closed we
5858 // put this back — the next open should restore the user's chosen width.
5959 const dragStartWidthRef = React . useRef ( width ) ;
60+ // Whether the drag has closed the sidebar. Tracked in a ref, synchronously
61+ // with the mousemove that closes it — mouseup can fire before React
62+ // re-registers the listeners with the post-close open/peek values, so the
63+ // closure state can't be trusted for the width restore.
64+ const dragEndedClosedRef = React . useRef ( false ) ;
6065
6166 const handleMouseDown = ( e : React . MouseEvent ) => {
6267 e . preventDefault ( ) ;
6368 dragOriginRef . current = open ? "docked" : "overlay" ;
6469 dragStartWidthRef . current = width ;
70+ dragEndedClosedRef . current = false ;
6571 setIsResizing ( true ) ;
6672 document . body . style . cursor = "col-resize" ;
6773 document . body . style . userSelect = "none" ;
@@ -99,6 +105,7 @@ export const ResizableSidebar: React.FC<ResizableSidebarProps> = ({
99105 if ( open ) {
100106 if ( pointer < DRAG_COLLAPSE_AT && setOpen ) {
101107 setOpen ( false ) ;
108+ dragEndedClosedRef . current = true ;
102109 return ;
103110 }
104111 setWidth ( clamped ) ;
@@ -108,6 +115,7 @@ export const ResizableSidebar: React.FC<ResizableSidebarProps> = ({
108115 if ( peek ) {
109116 if ( pointer < DRAG_COLLAPSE_AT ) {
110117 onPeekDismiss ?.( ) ;
118+ dragEndedClosedRef . current = true ;
111119 return ;
112120 }
113121 setWidth ( clamped ) ;
@@ -122,6 +130,7 @@ export const ResizableSidebar: React.FC<ResizableSidebarProps> = ({
122130 } else {
123131 onPeekEnter ?.( ) ;
124132 }
133+ dragEndedClosedRef . current = false ;
125134 setWidth ( clamped ) ;
126135 }
127136 } ;
@@ -134,7 +143,7 @@ export const ResizableSidebar: React.FC<ResizableSidebarProps> = ({
134143 // Drag ended closed (drag-to-close or peek dismiss): the collapse walk
135144 // clamped the store width to min on the way down — restore the pre-drag
136145 // width so the next open comes back at the user's chosen size.
137- if ( ! open && ! peek ) {
146+ if ( dragEndedClosedRef . current ) {
138147 setWidth ( dragStartWidthRef . current ) ;
139148 }
140149 // A floating-panel drag suppresses the panel's mouseleave (the pointer
@@ -176,22 +185,28 @@ export const ResizableSidebar: React.FC<ResizableSidebarProps> = ({
176185
177186 // While the panel slides, the resize handle sweeps under a stationary
178187 // pointer and picks up a stale :hover (browsers only recompute hover on
179- // pointer moves) — the primary line would stick on. Disarm the handle for
180- // the duration of any slide; a grab in progress keeps it live.
188+ // pointer moves) — the primary line would stick on. Any open/peek flip
189+ // starts a slide, so disarm the handle inline during that same render (a
190+ // grab in progress keeps it live), then re-arm once the slide is over.
181191 const [ handleArmed , setHandleArmed ] = React . useState ( true ) ;
182- const skipFirstArmCycle = React . useRef ( true ) ;
183- // biome-ignore lint/correctness/useExhaustiveDependencies: open/overlayVisible are pure triggers — any open/peek flip starts a slide and must disarm the handle
184- React . useEffect ( ( ) => {
185- if ( skipFirstArmCycle . current ) {
186- skipFirstArmCycle . current = false ;
187- return ;
188- }
192+ const [ prevSlideState , setPrevSlideState ] = React . useState ( {
193+ open,
194+ overlayVisible,
195+ } ) ;
196+ if (
197+ prevSlideState . open !== open ||
198+ prevSlideState . overlayVisible !== overlayVisible
199+ ) {
200+ setPrevSlideState ( { open, overlayVisible } ) ;
189201 setHandleArmed ( false ) ;
202+ }
203+ React . useEffect ( ( ) => {
204+ if ( handleArmed ) return ;
190205 // Slightly past the 200ms slide; timer-based so reduced-motion (no
191206 // transitionend) can't leave the handle disarmed.
192207 const timer = setTimeout ( ( ) => setHandleArmed ( true ) , 250 ) ;
193208 return ( ) => clearTimeout ( timer ) ;
194- } , [ open , overlayVisible ] ) ;
209+ } , [ handleArmed ] ) ;
195210
196211 return (
197212 < Box
0 commit comments