fix(ui): live sidebar inner width during resize

Inner sidebar content was pinned to a fixed openWidth (derived from store state) so it kept its full size during open/close animation. But store state only updates on pointer-release during a drag, which meant inner content didn't reflow while the user was actively dragging — only after they let go.

Keep openWidth as the inner width when the sidebar is idle (so slide-out animation still shows full-width content under the clipping aside), but during an active resize bind the inner content to a CSS variable that applyLiveWidth updates on every pointermove. The aside continues to use direct px width for transition reliability; the variable is just a side channel for the inner element.
This commit is contained in:
Bohdan Triapitsyn
2026-05-21 15:45:44 +03:00
parent e57f66ccd3
commit 4c2eeb4d78
2 changed files with 6 additions and 2 deletions
@@ -37,6 +37,7 @@ export const RightSidebar: React.FC<RightSidebarProps> = ({ isOpen, children, cl
sidebar.style.width = `${nextWidth}px`;
sidebar.style.minWidth = `${nextWidth}px`;
sidebar.style.maxWidth = `${nextWidth}px`;
sidebar.style.setProperty('--oc-right-sidebar-width', `${nextWidth}px`);
}, []);
const openWidth = Math.min(RIGHT_SIDEBAR_MAX_WIDTH, Math.max(RIGHT_SIDEBAR_MIN_WIDTH, rightSidebarWidth || RIGHT_SIDEBAR_CONTENT_WIDTH));
@@ -117,6 +118,7 @@ export const RightSidebar: React.FC<RightSidebarProps> = ({ isOpen, children, cl
width: `${currentWidth}px`,
minWidth: `${currentWidth}px`,
maxWidth: `${currentWidth}px`,
['--oc-right-sidebar-width' as string]: `${isResizing ? currentWidth : openWidth}px`,
overflowX: 'clip',
transitionProperty: isResizing ? 'none' : 'width, min-width, max-width',
transitionDuration: '200ms',
@@ -145,7 +147,7 @@ export const RightSidebar: React.FC<RightSidebarProps> = ({ isOpen, children, cl
isResizing && 'pointer-events-none',
!isOpen && 'pointer-events-none select-none opacity-0'
)}
style={{ width: `${openWidth}px` }}
style={{ width: 'var(--oc-right-sidebar-width)' }}
aria-hidden={!isOpen}
>
{isOpen ? children : null}
@@ -39,6 +39,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ isOpen, isMobile, children, cl
sidebar.style.width = `${nextWidth}px`;
sidebar.style.minWidth = `${nextWidth}px`;
sidebar.style.maxWidth = `${nextWidth}px`;
sidebar.style.setProperty('--oc-left-sidebar-width', `${nextWidth}px`);
}, []);
React.useEffect(() => {
@@ -132,6 +133,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ isOpen, isMobile, children, cl
width: `${currentWidth}px`,
minWidth: `${currentWidth}px`,
maxWidth: `${currentWidth}px`,
['--oc-left-sidebar-width' as string]: `${isResizing ? currentWidth : openWidth}px`,
overflowX: 'clip',
transitionProperty: isResizing ? 'none' : 'width, min-width, max-width',
transitionDuration: '200ms',
@@ -160,7 +162,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ isOpen, isMobile, children, cl
isResizing && 'pointer-events-none',
!isOpen && 'pointer-events-none select-none opacity-0'
)}
style={{ width: `${openWidth}px`, overflowX: 'hidden' }}
style={{ width: 'var(--oc-left-sidebar-width)', overflowX: 'hidden' }}
aria-hidden={!isOpen}
>
<div className="flex-1 overflow-y-auto">