ScrollArea
Overlay scrollbars that flow with the UI. Built on Radix ScrollArea: a thin, token-colored thumb that reveals on hover/scroll and never reserves layout width the way a native scrollbar does. Use it for bounded scroll containers — lists, panels, tables. The global thin-scrollbar styling in @roger-emerson/ploxum-tokens covers everything that isn't explicitly wrapped.
Import
import { ScrollArea } from "@roger-emerson/ploxum-primitives";Usage
<ScrollArea className="h-64 w-56 rounded-sm border border-subtle">
<div className="p-3">
{rows.map((row) => (
<div key={row}>{row}</div>
))}
</div>
</ScrollArea>The ScrollArea is the bounded box — give it a height (and/or width). Its child is the content that overflows.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | The content that overflows the viewport. |
orientation | "vertical" | "horizontal" | "both" | "vertical" | Which scrollbars to render. |
type | "hover" | "scroll" | "auto" | "always" | "hover" | Radix visibility behavior. hover/scroll keep the scrollbar as an overlay; always reserves it. |
className | string | — | Merged onto the bounded root (set the height/width here). |
viewportClassName | string | — | Class for the scroll viewport (the element that actually overflows). |
Design rules
- The thumb is the
border-defaulttoken and brightens totext-tertiaryon hover — same language as the global scrollbar styling, so wrapped and unwrapped scroll areas match. - Prefer
type="hover"(the default) so the scrollbar overlays and never shifts layout. Reservetype="always"for cases where a persistent affordance matters. - For a quick app-wide fix you don't need this component — the tokens layer already restyles native scrollbars. Reach for
ScrollAreawhen you want overlay behavior or horizontal scrolling without a native bar.
