From 4c2eeb4d780b07d485ce63cccc31f1a923640a4a Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Thu, 21 May 2026 00:23:47 +0300 Subject: [PATCH] fix(ui): live sidebar inner width during resize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- packages/ui/src/components/layout/RightSidebar.tsx | 4 +++- packages/ui/src/components/layout/Sidebar.tsx | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/components/layout/RightSidebar.tsx b/packages/ui/src/components/layout/RightSidebar.tsx index d671c6ac..43b2c801 100644 --- a/packages/ui/src/components/layout/RightSidebar.tsx +++ b/packages/ui/src/components/layout/RightSidebar.tsx @@ -37,6 +37,7 @@ export const RightSidebar: React.FC = ({ 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 = ({ 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 = ({ 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} diff --git a/packages/ui/src/components/layout/Sidebar.tsx b/packages/ui/src/components/layout/Sidebar.tsx index 22665d6d..464be772 100644 --- a/packages/ui/src/components/layout/Sidebar.tsx +++ b/packages/ui/src/components/layout/Sidebar.tsx @@ -39,6 +39,7 @@ export const Sidebar: React.FC = ({ 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 = ({ 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 = ({ 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} >