NimUI
ComponentsLayout

ScrollArea

Scroll container with quiet themed scrollbars

The ScrollArea component wraps Radix ScrollArea with scrollbars that match the kit in both themes. Content stays natively scrollable and keyboard accessible — the custom bars are purely visual. Give the root a height (or width, for horizontal) via className.

Import

import { ScrollArea, ScrollBar } from '@nim-ui/components';

Vertical scrolling

Activity Feed
Payment settled — ord_9021Label printing — ord_9020Awaiting stock check — ord_9019Webhook retry exhausted — ord_9018Refund issued — ord_9017Order archived — ord_9016Payment settled — ord_9015Fraud hold — ord_9014Payment settled — ord_9013Awaiting stock check — ord_9012
Code
<ScrollArea type="always" className="h-56 rounded-md border border-neutral-200 dark:border-neutral-800">
  <div className="flex flex-col gap-3 p-4 text-sm">
    <Dot status="success">Payment settled — ord_9021</Dot>
    {/* …more rows… */}
  </div>
</ScrollArea>

Horizontal scrolling

Add a horizontal ScrollBar and let the content define its own width.

Wide Row
ord_9021ord_9020ord_9019ord_9018ord_9017ord_9016ord_9015ord_9014ord_9013ord_9012ord_9011ord_9010
Code
<ScrollArea className="w-96">
  <div className="flex w-max gap-2 p-3">{/* wide content */}</div>
  <ScrollBar orientation="horizontal" />
</ScrollArea>

Props

ScrollArea

NameTypeDefaultDescription
type'hover' | 'always' | 'scroll' | 'auto''hover'When scrollbars are shown (Radix behavior)
scrollHideDelaynumber600Hide delay in ms for hover/scroll types
classNamestring-Size the region here (h-*, max-h-*, w-*)
children*ReactNode-Scrollable content

ScrollBar

NameTypeDefaultDescription
orientation'vertical' | 'horizontal''vertical'Scrollbar axis — a vertical bar is included automatically
classNamestring-Additional CSS classes to apply

Accessibility

  • The viewport remains a native scroll container — arrow keys, Page Up/Down, and screen-reader scrolling all work untouched.
  • Scrollbars are decorative; they add no extra tab stops.
  • Prefer type="always" when discoverability of more content matters (e.g. long policy text an operator must read).

Best Practices

Do

  • Size the region on ScrollArea's className, not on inner content
  • Use inside RecordInspector panels, activity feeds, and long option lists
  • Pair horizontal scrolling with w-max content so width comes from content

Don't

  • Nest ScrollAreas — restructure the layout instead
  • Use for whole-page scrolling; it's for bounded panels
  • Hide critical actions below the fold of a small ScrollArea
  • RecordInspector - Side panel that often needs bounded scrolling
  • Drawer - Overlay panel with its own scroll
  • DataTable - Tabular data with its own overflow handling

On this page