Skip to content

ScrollArea

<ScrollArea> is a Radix-based scroll container with thin, themed scrollbars. Use when default browser scrollbars look out of place — typically inside cards / popovers / sheets.

import from "@na/ui/components/scroll-area" ▶ Open in Storybook packages/ui/src/components/scroll-area.tsx

When to use

  • Vertical scrollers inside Cards, Popovers, Sheets, or DropdownMenus.
  • Long-but-bounded lists where browser scrollbars would visually dominate.

Don’t use ScrollArea for: page-level scroll (let the browser do it), chat-window scroll (often needs sticky-bottom logic which is a separate primitive), or trivial overflow that fits in overflow-auto.

Basic

Tags
agent
campaign
lead
inbox
flag
priority
paused
archived
review
beta
enterprise
public
private
admin
finance
support
qa
staging
production
legacy
<ScrollArea className="h-48 w-72 rounded-md border">
<div className="p-3">
{items.map((it) => <div key={it.id}>{it.label}</div>)}
</div>
</ScrollArea>

API

Prop Type Default Description
className string Required to set the bounded height/width — without it, ScrollArea has no scroll.
children ReactNode Inner content. Wrap in your own padding container.

ScrollBar is exported separately and accepts an orientation prop (“vertical” | “horizontal”).

Design guidelines

✓ Do

  • Set explicit height (h-* or max-h-*) on ScrollArea. Without it, it doesn't scroll — it just expands.
  • Use ScrollArea inside Cards / Popovers — places where native scrollbars look heavy.

✗ Don't

  • Wrap the whole page in a ScrollArea. Browser scroll is faster and natively keyboard-accessible.
  • Style ScrollArea's scrollbar with arbitrary colors. Use the design tokens.

Accessibility

  • Composes Radix ScrollArea — pointer / wheel / touch all work.
  • Keyboard scroll requires the contained content to be focusable; Tab into a focusable child, then arrow keys scroll.
  • Resizable — When the user controls the bounded size.

▶ Open ScrollArea stories in Storybook