fix(desktop): minimal, consistent scrollbars across all platforms (sidebar, sessions board, markdown preview)#2997
fix(desktop): minimal, consistent scrollbars across all platforms (sidebar, sessions board, markdown preview)#2997JAYATIAHUJA wants to merge 2 commits into
Conversation
…markdown preview - Sidebar: keep the brand header and the Projects/new-project row static; only the projects/sessions list scrolls, with the scrollbar hidden (scrollbar-none). - Sessions board: shared .board-scrollbar utility (4px rounded thumb, transparent track, no buttons, hover highlight) applied to the zone columns, idle stack, and done/terminated grid. - Markdown preview served by the daemon: thin neutral-gray scrollbars (WebKit + Firefox) that work in both light and dark schemes. - Settings panel background uses --color-bg-primary for consistency.
There was a problem hiding this comment.
Pull request overview
This PR standardizes scrollbar styling across the desktop app’s sidebar and sessions board, and also updates the daemon-rendered Markdown preview so scrollbars are visually lighter and more consistent across platforms. It additionally adjusts the settings panel background to better match the shell’s primary background color.
Changes:
- Introduced a shared minimal scrollbar utility (
.board-scrollbar) and applied it to Sessions Board scroll regions. - Updated the Sidebar layout so header/chrome stays fixed while the list scrolls, with scrollbars hidden via
scrollbar-none. - Added minimal scrollbar styling to the daemon-rendered Markdown preview page and aligned the settings panel background with
--color-bg-primary.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/renderer/styles.css | Adds .board-scrollbar styling and updates settings panel background color. |
| frontend/src/renderer/components/Sidebar.tsx | Keeps the “Projects” chrome static while only the list scrolls; hides scrollbar visuals. |
| frontend/src/renderer/components/Sidebar.test.tsx | Adds a test asserting sidebar content remains scrollable while using scrollbar-none. |
| frontend/src/renderer/components/SessionsBoard.tsx | Applies .board-scrollbar to board scroll containers (columns/idle/done regions). |
| frontend/src/renderer/components/SessionsBoard.test.tsx | Adds a test asserting the board uses .board-scrollbar across expected scroll regions. |
| backend/internal/preview/markdown.go | Adds CSS for minimal scrollbars in the Markdown preview HTML output. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /* Minimal scrollbars: thin, neutral gray, no track or buttons, so the panel | ||
| chrome stays quiet in both light and dark schemes. */ | ||
| * { scrollbar-width: thin; scrollbar-color: rgba(128,128,128,0.45) transparent; } | ||
| ::-webkit-scrollbar { width: 8px; height: 8px; } | ||
| ::-webkit-scrollbar-track { background: transparent; } | ||
| ::-webkit-scrollbar-thumb { background: rgba(128,128,128,0.35); border-radius: 4px; } | ||
| ::-webkit-scrollbar-thumb:hover { background: rgba(128,128,128,0.55); } | ||
| ::-webkit-scrollbar-corner { background: transparent; } |
Pulkit7070
left a comment
There was a problem hiding this comment.
Reviewed and ran locally. Backend and frontend checks pass, and I exercised the sidebar and board changes in the Playwright renderer harness.
Verification:
- Backend:
go test ./internal/preview/...pass,go build ./...clean. - Frontend: Sidebar + SessionsBoard unit tests 52 passed, typecheck clean.
- Playwright (renderer):
[data-sidebar="content"]hasoverflow-y-autoandscrollbar-noneand is genuinely scrollable (computedoverflow-y: auto); the Projects label is no longer a descendant of the scroll container, which confirms the static-chrome fix; and the board scroll regions all carryboard-scrollbarwithoverflow-y-auto. The T0 smoke suite passed alongside as an environment sanity check.
Scope note: Playwright verifies the DOM structure and scroll wiring the CSS hangs off, but not the scrollbar's pixel appearance (a Chromium paint detail, and headless Chromium here uses overlay scrollbars with zero layout width). The markdown-preview scrollbar ships in daemon-rendered HTML, which the browser-only harness does not serve, so I covered it via the preview go test and by reading the CSS.
One specific item inline about consistency across surfaces. Two smaller notes:
- The
@supports (-moz-appearance: none)block targets Firefox, which the Electron app never runs. For.board-scrollbarit is still load-bearing (it keeps the standard properties from overriding the webkit rules in Chromium), so keep it. I mention it only because markdown.go does not do the same, which is the inline point. - The Sidebar Projects row moved from nested padding (
px-2insidepl-2.5) to explicitpl-4.5 pr-3.75. Worth an eyeball that it still lines up with the tree items below, since that alignment is a visual detail the tests do not catch.
| * { box-sizing: border-box; } | ||
| /* Minimal scrollbars: thin, neutral gray, no track or buttons, so the panel | ||
| chrome stays quiet in both light and dark schemes. */ | ||
| * { scrollbar-width: thin; scrollbar-color: rgba(128,128,128,0.45) transparent; } |
There was a problem hiding this comment.
This sets the standard scrollbar-width: thin and scrollbar-color on * unconditionally, whereas .board-scrollbar in styles.css deliberately gates the standard properties behind @supports (-moz-appearance: none) (Firefox only) so its ::-webkit-scrollbar 4px thumb controls the width in the app's Chromium. Per Chromium's documented behavior, once scrollbar-width/scrollbar-color are set, the ::-webkit-scrollbar rules are ignored. So the ::-webkit-scrollbar { width: 8px } and border-radius: 4px block just below (lines 52 to 56) is likely inert in the Electron/Chromium runtime, and this panel renders the browser's default thin width rather than the board's 4px. Both are thin and gray, so it is not a visible break, but the markdown preview and the board end up using different widths, which cuts against this PR's stated goal of one consistent scrollbar across all surfaces. Suggest picking one mechanism for both surfaces: either gate the standard props here the same way .board-scrollbar does so the webkit width/radius applies, or drop the webkit block and rely on the standard properties everywhere. I could not measure the exact widths in my run because headless Chromium uses overlay scrollbars (zero layout width).
Summary
The desktop app rendered default OS scrollbars in several panels, which look and behave differently per platform — heavy always-visible tracks on Windows, overlay scrollbars on macOS, theme-dependent ones on Linux. This PR replaces them with one minimal, consistent scrollbar style across all surfaces and all platforms (the app is Electron/Chromium, so the styling applies identically on Windows, macOS, and Linux; Firefox-standard
scrollbar-width/scrollbar-colorfallbacks are included where relevant). It also fixes the sidebar so its static chrome no longer scrolls with the content.Changes
frontend/src/renderer/components/Sidebar.tsx)scrollbar-none: it remains fully scrollable (content never gets clipped or unreachable) but no visible scrollbar is rendered — on every platform.SessionsBoard.tsx,styles.css).board-scrollbarutility: 4px rounded thumb, transparent track/corner, no arrow buttons, subtle hover highlight, with a standards-basedscrollbar-width: thinfallback.backend/internal/preview/markdown.go)prefers-color-scheme, regardless of OS.styles.css): background now uses--color-bg-primaryfor visual consistency with the rest of the shell.Tests
Sidebar.test.tsxcase: sidebar content keepsoverflow-y-autowhile hiding the scrollbar.SessionsBoard.test.tsxcase: all six board scroll regions useboard-scrollbarwithoverflow-y-auto.Verification
npx vitest run src/renderer/components/Sidebar.test.tsx src/renderer/components/SessionsBoard.test.tsx— 52 passedcd frontend && npm run typecheck— cleancd backend && go test ./internal/preview/... && go build ./...— pass