fix(web): tighten sidebar session spacing

This commit is contained in:
_Kerman
2026-08-04 14:11:54 +08:00
parent 4b591c0abc
commit b57e29db59
3 changed files with 43 additions and 30 deletions
@@ -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. */
@@ -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);
@@ -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<string, string> | 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')
})
})