From b57e29db595e19b93cd06243a2dfc4ca82c0cc7b Mon Sep 17 00:00:00 2001 From: _Kerman Date: Tue, 4 Aug 2026 13:34:29 +0800 Subject: [PATCH] fix(web): tighten sidebar session spacing --- .../src/client/SidebarRoot.module.css | 5 ++ .../src/client/WorkspaceBrowser.module.css | 47 ++++++++++--------- .../ui-workspace/tests/browser-styles.spec.ts | 21 ++++++--- 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/packages/client/ui-sidebar/src/client/SidebarRoot.module.css b/packages/client/ui-sidebar/src/client/SidebarRoot.module.css index ebb47467af..badab085de 100644 --- a/packages/client/ui-sidebar/src/client/SidebarRoot.module.css +++ b/packages/client/ui-sidebar/src/client/SidebarRoot.module.css @@ -196,9 +196,14 @@ min-height: 0; display: flex; flex-direction: column; + margin-right: -12px; overflow: hidden; } +.collapsed .regionArea { + margin-right: 0; +} + /* Foot seat: a pure layout socket pinned under the region; the ui-settings trigger row inside owns its own geometry (49px wide row / 36px rail circle) and hover chrome. */ diff --git a/packages/client/ui-workspace/src/client/WorkspaceBrowser.module.css b/packages/client/ui-workspace/src/client/WorkspaceBrowser.module.css index 970fc64e8b..dc5b489c3a 100644 --- a/packages/client/ui-workspace/src/client/WorkspaceBrowser.module.css +++ b/packages/client/ui-workspace/src/client/WorkspaceBrowser.module.css @@ -8,6 +8,12 @@ min-height: 0; display: flex; flex-direction: column; + box-sizing: border-box; + padding-right: 12px; +} + +.root.rail { + padding-right: 0; } .iconButton { @@ -167,9 +173,14 @@ min-height: 0; display: flex; flex-direction: column; + margin-right: -12px; overflow: hidden; } +.rail .listArea { + margin-right: 0; +} + /* Relative for the bottom fade overlay. */ .treeBody { flex: 1; @@ -202,27 +213,28 @@ /* List: the only scrolling region. Block, not a flex column: as flex items the 54/34 rows would shrink under content overflow; block children keep - their design heights and the 4px rhythm rides margins instead of gap. */ + their design heights do not shrink under content overflow. Its right + padding is the sole gap between row backgrounds and the sidebar edge; the + outer seats move their clip boundary out so they add no hidden inset. */ .list { + --dsh-session-list-edge-inset: 12px; + --dsh-session-list-scrollbar-width: 8px; flex: 1; min-height: 0; overflow-y: auto; + padding-right: var(--dsh-session-list-edge-inset); padding-bottom: 12px; - /* Row trailing content (the relative time, and the hover action buttons - that replace it) sits flush against the row's 8px right padding, so an - overlaid scrollbar covers it. Reserving the gutter keeps the bar beside - the rows instead of on top of them; `stable` holds the reservation when - the list is short enough not to scroll, so expanding a group does not - shift every row left. */ scrollbar-gutter: stable; } -.list > [role='treeitem'] + [role='treeitem'] { - margin-top: 4px; +.list::-webkit-scrollbar { + width: var(--dsh-session-list-scrollbar-width); } -.searchTree > [role='treeitem'] + [role='treeitem'] { - margin-top: 4px; +.list > [role='treeitem'] + [role='treeitem'], +.searchTree > [role='treeitem'] + [role='treeitem'], +.groupSection > * + * { + margin-top: 2px; } .searchStatus, @@ -237,22 +249,11 @@ color: var(--dsw-alias-label-secondary); } -/* One workspace section: header row + expanded session run. Rows inside - keep the former flat-list 4px gap as sibling margins; the inter-group - breathing room (figma 133:7661 batch separator, 20px after an expanded - run) rides the NEXT section's top margin so the last group adds none. */ -.groupSection > * + * { - margin-top: 4px; -} - +/* One workspace section: header row + a compact expanded session run. */ .groupSection + .groupSection { margin-top: 4px; } -.groupSection:has([aria-expanded='true']) + .groupSection { - margin-top: 20px; -} - .empty { padding: 16px 12px; color: var(--dsw-alias-label-tertiary); diff --git a/packages/client/ui-workspace/tests/browser-styles.spec.ts b/packages/client/ui-workspace/tests/browser-styles.spec.ts index d2ac07f0c2..55c0602090 100644 --- a/packages/client/ui-workspace/tests/browser-styles.spec.ts +++ b/packages/client/ui-workspace/tests/browser-styles.spec.ts @@ -1,8 +1,7 @@ /** * WorkspaceBrowser scroll-region style contract, asserted against the CSS text - * on disk: the session list reserves its scrollbar gutter so the scrollbar - * cannot overlay row trailing content, and reserves it whether or not the list - * currently overflows so expanding a group does not shift rows sideways. + * on disk: the session list keeps one stable right inset for row hover fills, + * with or without overflow, while outer clip seats add no hidden second inset. */ import { readFileSync } from 'node:fs' import { fileURLToPath } from 'node:url' @@ -32,17 +31,25 @@ function declarations(className: string): Map | undefined { } describe('WorkspaceBrowser.module.css list', () => { + const root = declarations('root') + const listArea = declarations('listArea') const list = declarations('list') + const treeBody = declarations('treeBody') it('is the scrolling region', () => { expect(list).toBeDefined() expect(list!.get('overflow-y')).toBe('auto') }) - it('reserves the scrollbar gutter unconditionally', () => { - // Row trailing content sits flush against the row's right padding, so an - // overlay scrollbar covers it. `stable` keeps the reservation when the list - // is short enough not to scroll, so expanding a group does not shift rows. + it('keeps row backgrounds edge-flush with the scrolling region', () => { + expect(root?.get('padding-right')).toBe('12px') + expect(listArea?.get('margin-right')).toBe('-12px') + expect(treeBody?.get('margin-right')).toBeUndefined() + expect(list?.get('margin-right')).toBeUndefined() + expect(list?.get('padding-right')).toBe('var(--dsh-session-list-edge-inset)') + }) + + it('reserves the scrollbar inside the stable visual inset', () => { expect(list!.get('scrollbar-gutter')).toBe('stable') }) })