Scroll Area
A scrolling region with a thin scrollbar that looks the same on every platform.
function ScrollAreaDemo() {
const domains = Array.from(
{ length: 30 },
(_, index) => `acme-${String(index + 1).padStart(2, "0")}.example.com`
)
return (
<ScrollArea className="h-72 w-64 rounded-md border border-border">
<div className="p-4">
<div className="mb-3 text-sm font-medium text-text-primary">
Monitored domains
</div>
{domains.map((domain) => (
<div key={domain}>
<div className="py-1.5 font-mono text-sm text-text-secondary">
{domain}
</div>
<Separator />
</div>
))}
</div>
</ScrollArea>
)
}Usage
import { ScrollArea } from "@zenoxai/ui/components/scroll-area"
<ScrollArea className="h-72 rounded-md border border-border">
{content}
</ScrollArea>
Use a scroll area for a region with a fixed size inside a page: a list in a card, a log panel, a popover with many options. Give it a height (or a width, for horizontal content); without one there is nothing to scroll. The page itself scrolls natively and needs no scroll area.
ScrollArea renders a vertical scrollbar. The scrollbar appears only when the content
overflows.
Examples
Horizontal
Add <ScrollBar orientation="horizontal" /> as the last child for content wider than the
area. Give the content a width it cannot shrink below, such as w-max.
function ScrollAreaHorizontal() {
const ports = [
{ port: 22, service: "SSH" },
{ port: 80, service: "HTTP" },
{ port: 443, service: "HTTPS" },
{ port: 3306, service: "MySQL" },
{ port: 3389, service: "RDP" },
{ port: 5432, service: "PostgreSQL" },
{ port: 6379, service: "Redis" },
{ port: 8080, service: "HTTP proxy" },
{ port: 9200, service: "Elasticsearch" },
]
return (
<ScrollArea className="w-full max-w-md rounded-md border border-border">
<div className="flex w-max gap-3 p-4">
{ports.map(({ port, service }) => (
<div
key={port}
className="flex w-28 shrink-0 flex-col gap-1 rounded-md bg-surface-muted p-3"
>
<span className="font-mono text-sm font-medium text-text-primary">
{port}/tcp
</span>
<span className="text-xs text-text-muted">{service}</span>
</div>
))}
</div>
<ScrollBar orientation="horizontal" />
</ScrollArea>
)
}Scrollbar on hover
While the content overflows, the scrollbar stays visible. On a panel that is always on
screen, fade it in on hover and while scrolling with scrollbarClassName and the
data-hovering and data-scrolling attributes.
function ScrollAreaFadingScrollbar() {
const events = Array.from(
{ length: 20 },
(_, index) =>
`10:${String(59 - index).padStart(2, "0")} Login from 203.0.113.${index + 10}`
)
return (
<ScrollArea
className="h-56 w-72 rounded-md border border-border"
scrollbarClassName="opacity-0 transition-opacity data-hovering:opacity-100 data-scrolling:opacity-100"
>
<ul className="flex flex-col gap-2 p-4 font-mono text-sm text-text-secondary">
{events.map((event) => (
<li key={event}>{event}</li>
))}
</ul>
</ScrollArea>
)
}Accessibility
- The scrolling element takes keyboard focus when its content overflows, so keyboard users can scroll it with the arrow keys, Page Up and Page Down. It shows a focus ring.
- Scrolling stays native: wheel, touch, find-in-page and screen readers work as in any overflowing element.
API reference
Generated from the TypeScript source. className, style and children are accepted everywhere and omitted below.
ScrollArea
ScrollArea is a scrolling region with a thin themed scrollbar in place of the browser's, for a panel of fixed size such as a sidebar list or a popover body. Let the page itself scroll natively.
| Prop | Type | Default |
|---|---|---|
overflowEdgeThreshold | number | Partial<{ xStart: number; xEnd: number; yStart: number; yEnd: number; }>The threshold in pixels that must be passed before the overflow edge attributes are applied. Accepts a single number for all edges or an object to configure them individually. | 0 |
render | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ScrollAreaRootState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. | - |
scrollbarClassName | stringClasses for the scrollbar track. Use it to size the bar or to fade it in on `data-hovering` / `data-scrolling` — the primitive keeps the track visible at all times, which reads as clutter on a permanently mounted surface. | - |
ScrollBar
ScrollBar is a scrollbar track and thumb. ScrollArea renders a vertical one; add a ScrollBar with `orientation="horizontal"` inside it for sideways scrolling.
| Prop | Type | Default |
|---|---|---|
keepMounted | booleanWhether to keep the HTML element in the DOM when the viewport isn't scrollable. | false |
orientation | "horizontal" | "vertical"Whether the scrollbar controls vertical or horizontal scroll. | vertical |
render | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ScrollAreaScrollbarState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. | - |