Repository navigation
fix(layout): pin shell side panels to px so a window resize can't wobble them / 侧栏与终端固定像素尺寸,消除缩放时分割线抖动 - #897
Merged
Conversation
…ble them react-resizable-panels writes each panel's size as `flex-grow` rounded to 3 significant digits (20.83% -> "20.8", ~0.5px at 1440px wide), by an error that changes with every window width. A sidebar sized through it wobbled sub-pixel on each resize step, however precisely the layout was fed in, so the divider jittered while the window was dragged. - Size the sidebar and aux panels (and the terminal, vertically) with a px `flex-basis` through the Panel `style` prop, which overrides the library's computed style, and let the center / workspace pane take the remainder. The library layout stays in step for handle drags and min/max clamping, and a drag reaches the px values through the existing onLayout -> setWidth / setHeight path. - Convert px <-> percent against the space left after the 1px dividers, not the container width, and compare re-applied layouts at sub-pixel precision (the old 0.25% tolerance skipped small steps until they added up, then snapped). - Apply the layout in layout effects, and ignore the onLayout calls a container resize itself causes, so they are not persisted as a user resize. - Keep the pane contents (sidebar, aux panel, terminal, workspace) as stable elements so the shell re-rendering on each resize step skips their subtrees. - The slide transition on the panels now covers `flex-basis` as well, since that is what changes when a side panel opens or closes. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…he resize guard - The side columns scaled down for a narrow window could drop below their minimum widths (and the terminal below its minimum height), where react-resizable-panels clamps its own layout. The drawn panels then disagreed with the layout a handle drag starts from by up to ~100px, and the aux panel could get narrower than the width that keeps the Windows/Linux title-bar overlay off the center column. Raise each open column back to its minimum and take the difference the way the library's clamp does: from the sidebar down to its own minimum, then from the center. - The container-resize guard was a flag raised in the ResizeObserver and lowered by the layout effect that applies the new layout. Two observations that cancel out before React renders make that render bail out with no layout effect, leaving the flag raised, so every later drag was dropped until the next window resize. Compare the last observed container size with the size the layout was last applied for instead. The first measurement now counts as a resize too, so applying it no longer persists scaled-down widths. - Update the comments that still described percent-sized panels and a flex-grow-only slide.
Collaborator
|
codeg work task |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What / 改动内容
The divider between the sidebar and the main area jittered left/right while the window was being resized. Cause:
react-resizable-panelswrites each panel's size asflex-growrounded to 3 significant digits (20.83%→"20.8", ~0.5px at 1440px wide), and that rounding error changes with every window width. A sidebar sized through it wobbled sub-pixel on each resize step, however precisely the layout was fed in.flex-basisthrough thePanelstyleprop, which overrides the library's computed style, and let the center / workspace pane take the remainder. The library's layout is still kept in step — it drives handle drags and min/max clamping, and a drag reaches the px values through the existingonLayout→setWidth/setHeightpath.onLayoutcalls a container resize itself causes so they are not persisted as a user resize.flex-basistoo, since that is what changes when a side panel opens or closes.Only
src/app/workspace/layout.tsxand one rule inglobals.csschange.Testing / 测试
pnpm lint .,pnpm test(560 files / 8390 tests) andpnpm buildpass.flex-basis) deserve a quick look from a reviewer.中文说明
调整窗口大小时,左侧栏与主框架之间的分割线会左右抖动。原因:
react-resizable-panels把每个面板的尺寸写成保留 3 位有效数字的flex-grow(20.83%变成"20.8",1440px 宽时约差 0.5px),而这个舍入误差会随窗口宽度不断变化,所以即使传入的布局再精确,侧栏也会在亚像素级别来回晃动。Panel的style用像素的flex-basis定宽(它会覆盖库计算出的样式),中间 / 工作区面板占满剩余空间。库的布局仍保持同步,用于拖动分割线和最小/最大宽度限制;拖动结果经由现有的onLayout→setWidth/setHeight写回像素值。onLayout,避免被当作用户拖动而持久化。flex-basis,因为打开/收起侧栏时变化的就是它。只改动
src/app/workspace/layout.tsx和globals.css中的一条规则。测试:
pnpm lint .、pnpm test(560 个文件 / 8390 个用例)、pnpm build均通过。在桌面端手动验证:拖动窗口边缘时侧栏分割线不再移动。布局部分没有被 jsdom 测试覆盖,拖动侧栏 / 右侧面板 / 终端分割线以及面板的滑动动画(现在过渡的是flex-basis)建议审查时再看一下。仅在 Linux(GNOME / Wayland、WebKitGTK 桌面版)测试,未在 macOS、Windows 上试过。🤖 Generated with Claude Code