Skip to content

Commit afe5df9

Browse files
committed
fix(sidebar): shrink collapsed rail to 48px so chips center without shifting on toggle
1 parent 265d5eb commit afe5df9

4 files changed

Lines changed: 16 additions & 17 deletions

File tree

apps/sim/app/_styles/globals.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212
:root {
1313
--sidebar-width: 0px; /* 0 outside workspace; blocking script always sets actual value on workspace pages */
14-
--sidebar-collapsed-width: 51px; /* icon rail on web; desktop overrides to 0 before first paint */
14+
--sidebar-collapsed-width: 48px; /* icon rail on web; desktop overrides to 0 before first paint */
1515
--sidebar-expanded-width: 238px; /* SIDEBAR_WIDTH.DEFAULT; the width to restore to, held even while collapsed */
1616
--desktop-title-bar-height: 0px; /* macOS traffic-light lane; desktop overrides before first paint */
1717
--workspace-content-title-bar-inset: 0px; /* lane the content pane must leave clear; only non-zero when the pane, not the sidebar, sits under it */

apps/sim/app/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
7575
// The macOS desktop shell overlays native traffic lights on the
7676
// workspace. Mark it before first paint so the sidebar reserves
7777
// its inset title-bar lane without a post-hydration layout shift.
78-
var collapsedSidebarWidth = 51;
78+
var collapsedSidebarWidth = 48;
7979
try {
8080
if (window.simDesktop && /Mac/i.test(navigator.userAgent)) {
8181
document.documentElement.setAttribute('data-sim-desktop-title-bar', 'inset');

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/constants.ts

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,26 @@ export const SIDEBAR_DIVIDER_PAD_BELOW_CLASS = 'pt-2'
3535
* marker on the sidebar `aside` (the hover-peek card drops `data-collapsed`,
3636
* so peeked rows stay expanded). Collapses a full-width row to the natural
3737
* icon-only chip — 32px, the chip's own `px-2` + 16px glyph, matching the
38-
* header's Search/Collapse pills — and CENTERS it in the 51px rail:
39-
* (51 − 32) / 2 = 9.5px per side, the 8px gutter + this 1.5px margin, which
40-
* puts the glyph on the rail's midline. Padding stays untouched (the glyph is
41-
* already centered within the chip). Centering costs a 1.5px drift from the
42-
* expanded rows' glyph column (24px in); margin sits in the transition list
43-
* so that drift glides on the rail's own curve rather than snapping — the
44-
* glyph-stationary alternative left the rail visibly left-biased (8px vs
45-
* 11px insets). Collapsing, width and margin tween on the 175ms curve the
46-
* rail closes on; expanding targets `auto` width (not interpolable), so the
47-
* chip snaps to the still-narrow rail's width and stretch-tracks it open
48-
* while the margin tweens back. The duration is `!important` because the
49-
* aside zeroes chip transition durations
38+
* header's Search/Collapse pills. Only the WIDTH is overridden: the rail is
39+
* 48px precisely so that the plain 8px item gutter centers the chip
40+
* ((48 − 32) / 2 = 8) and puts the glyph (24px in) on the rail's midline
41+
* the same 24px column the expanded rows use, so NOTHING moves on toggle.
42+
* At the previous 51px rail those goals were mutually exclusive by 1.5px
43+
* (rail midline 25.5 vs glyph column 24), which produced either a
44+
* left-biased rail or a drift on toggle; keep the rail width and this chip
45+
* width commensurate (rail = chip + 2 × gutter) if either ever changes.
46+
* Collapsing, the width tweens down to 32px on the 175ms curve the rail
47+
* closes on; expanding targets `auto` (not interpolable), so the chip snaps
48+
* to the still-narrow rail's width and stretch-tracks it open. The duration
49+
* is `!important` because the aside zeroes chip transition durations
5050
* (`[&_.group.cursor-pointer]:duration-0`) for instant hover fills — colors
5151
* are excluded from the property list here, so hover fills keep snapping.
5252
*/
5353
export const SIDEBAR_RAIL_CHIP_CLASS = [
54-
'transition-[width,margin]',
54+
'transition-[width]',
5555
'![transition-duration:175ms]',
5656
'[transition-timing-function:cubic-bezier(0.25,0.1,0.25,1)]',
5757
'motion-reduce:!transition-none',
58-
'group-data-[collapsed]/rail:ml-[1.5px]',
5958
'group-data-[collapsed]/rail:w-[32px]',
6059
].join(' ')
6160

apps/sim/stores/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const SIDEBAR_WIDTH = {
2626
DEFAULT: 238,
2727
MIN: 238,
2828
/** Width when sidebar is collapsed to icon-only mode */
29-
COLLAPSED: 51,
29+
COLLAPSED: 48,
3030
/** Maximum is 30% of viewport, enforced dynamically */
3131
MAX_PERCENTAGE: 0.3,
3232
} as const

0 commit comments

Comments
 (0)