Skip to content

Commit b71ed8a

Browse files
committed
🐛 fix(draggable): improve resizing behavior with stable layout support
Signed-off-by: Innei <tukon479@gmail.com>
1 parent d39c948 commit b71ed8a

1 file changed

Lines changed: 34 additions & 4 deletions

File tree

src/DraggablePanel/DraggablePanel.tsx

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ const DraggablePanel = memo<DraggablePanelProps>(
9999
const resetTransitionTimeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);
100100
const resizableRef = useRef<Resizable>(null);
101101
const initialExpandedSizeRef = useRef<Size | undefined>(undefined);
102+
const outerRef = useRef<HTMLDivElement>(null);
102103

103104
const { direction: antdDirection } = use(ConfigProvider.ConfigContext);
104105
const direction = dir ?? antdDirection;
@@ -306,10 +307,20 @@ const DraggablePanel = memo<DraggablePanelProps>(
306307
const handleResize = useCallback(
307308
(_event: unknown, _direction: unknown, el: HTMLElement, delta: NumberSize) => {
308309
const nextSize = clampResizeSize(el);
310+
if (stableLayout && outerRef.current) {
311+
// Sync outer DOM width immediately so it doesn't lag behind the
312+
// re-resizable inline style (which would otherwise trigger a 0.2s
313+
// width transition on the outer/aside each frame during drag).
314+
const dimension = isVertical ? nextSize.height : nextSize.width;
315+
if (dimension) {
316+
if (isVertical) outerRef.current.style.height = dimension;
317+
else outerRef.current.style.width = dimension;
318+
}
319+
}
309320
setExpandedMainSize(nextSize);
310321
onSizeDragging?.(delta, nextSize);
311322
},
312-
[clampResizeSize, onSizeDragging, setExpandedMainSize],
323+
[clampResizeSize, isVertical, onSizeDragging, setExpandedMainSize, stableLayout],
313324
);
314325

315326
const triggerResetWithoutTransition = useCallback(() => {
@@ -366,10 +377,16 @@ const DraggablePanel = memo<DraggablePanelProps>(
366377
resetTransitionTimeoutRef.current = undefined;
367378
}
368379

380+
// Synchronously disable the outer transition so the first drag frame
381+
// does not animate. `setShouldTransition(false)` below is asynchronous
382+
// and would only take effect after the next React commit.
383+
if (stableLayout && outerRef.current) {
384+
outerRef.current.style.transition = 'none';
385+
}
369386
setShouldTransition(false);
370387
setShowExpand(false);
371388
},
372-
[handleResetSize],
389+
[handleResetSize, stableLayout],
373390
);
374391

375392
const handleResizeStop = useCallback(
@@ -378,9 +395,16 @@ const DraggablePanel = memo<DraggablePanelProps>(
378395
setExpandedMainSize(nextSize);
379396
setShouldTransition(true);
380397
setShowExpand(true);
398+
// Clear imperative inline overrides so React resumes owning the outer
399+
// width/transition on the next render.
400+
if (stableLayout && outerRef.current) {
401+
outerRef.current.style.removeProperty('width');
402+
outerRef.current.style.removeProperty('height');
403+
outerRef.current.style.removeProperty('transition');
404+
}
381405
onSizeChange?.(delta, nextSize);
382406
},
383-
[clampResizeSize, onSizeChange, setExpandedMainSize],
407+
[clampResizeSize, onSizeChange, setExpandedMainSize, stableLayout],
384408
);
385409

386410
const resizeHandleClassName = useMemo(
@@ -524,7 +548,13 @@ const DraggablePanel = memo<DraggablePanelProps>(
524548
</Center>
525549
</Center>
526550
)}
527-
{stableLayout ? <div style={sidebarOuterStyle}>{panelNode}</div> : panelNode}
551+
{stableLayout ? (
552+
<div ref={outerRef} style={sidebarOuterStyle}>
553+
{panelNode}
554+
</div>
555+
) : (
556+
panelNode
557+
)}
528558
</aside>
529559
);
530560
},

0 commit comments

Comments
 (0)