feat(frontend): replace native scrollbar styling with OverlayScrollbars

Adopt OverlayScrollbars for cross-platform consistent overlay scrollbars
with auto-hide on pointer leave, hover grow effect, and click-to-scroll.

- Add overlayscrollbars + overlayscrollbars-react dependencies
- Rewrite ScrollArea component from Radix to OverlayScrollbars wrapper
- Define custom theme `os-theme-codeg` in globals.css (6px → 8px on hover)
- Initialize body-level overlay scrollbar via OverlayScrollbarsInit
- Migrate all scrollbar-thin / scrollbar-thin-edge usages to ScrollArea
- Keep native .scrollbar-thin fallback for virtua scroll containers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
xintaofei
2026-04-12 20:16:46 +08:00
parent ad50cc28fc
commit 0fafe782ee
13 changed files with 411 additions and 336 deletions

View File

@@ -2,7 +2,6 @@
@import "tw-animate-css";
@import "shadcn/tailwind.css";
@import "@xterm/xterm/css/xterm.css";
@custom-variant dark (&:is(.dark *));
:root {
@@ -1002,14 +1001,28 @@
}
}
/* Unified scrollbar style for scrollable containers.
Thin overlay scrollbar — no gutter reserved, no layout shift. */
.scrollbar-thin,
.scrollbar-thin-edge {
/* Native fallback for containers that cannot use OverlayScrollbars (e.g. virtua) */
.scrollbar-thin {
scrollbar-width: thin;
scrollbar-color: var(--border) transparent;
}
/* OverlayScrollbars custom theme */
.os-theme-codeg {
--os-size: 6px;
--os-handle-bg: var(--border);
--os-handle-bg-hover: var(--muted-foreground);
--os-handle-bg-active: var(--muted-foreground);
--os-handle-border-radius: 999px;
--os-handle-perpendicular-size: 100%;
--os-handle-perpendicular-size-hover: 100%;
--os-handle-perpendicular-size-active: 100%;
}
.os-theme-codeg:hover {
--os-size: 8px;
}
/* Streamdown code blocks: dark mode via shiki dual-theme CSS variables */
.dark [data-streamdown="code-block-body"] {
background-color: var(--shiki-dark-bg, var(--sdm-bg, transparent)) !important;