Skip to main content

Overview

Scroll Area wraps a scrollable container with a styled, cross-browser-consistent scrollbar. Use it to replace native OS scrollbars in sidebars, lists, code blocks, and chat windows.

Installation

npm install @araf-ds/core

Usage

import { ScrollArea } from "@araf-ds/core"

export default function Example() {
  return (
    <ScrollArea className="h-64 w-56 rounded-md border">
      <div className="p-3">
        {components.map(name => (
          <div key={name} className="py-2 text-sm border-b last:border-0">
            {name}
          </div>
        ))}
      </div>
    </ScrollArea>
  )
}

Variants

Vertical Scroll

<ScrollArea className="h-40 w-56 rounded-md border">
  <div className="p-3 space-y-1">
    {users.map(user => (
      <div key={user.id} className="flex items-center gap-2 py-1.5">
        <Avatar size="sm" src={user.avatar} fallback={user.initials} />
        <span className="text-sm">{user.name}</span>
      </div>
    ))}
  </div>
</ScrollArea>

Horizontal Scroll

<ScrollArea className="w-72 whitespace-nowrap rounded-md border">
  <div className="flex gap-3 p-3">
    {artworks.map(art => (
      <figure key={art.id} className="shrink-0">
        <div className="overflow-hidden rounded-md">
          <img src={art.src} alt={art.title} className="h-32 w-32 object-cover" />
        </div>
        <figcaption className="pt-1 text-xs text-muted-foreground">
          {art.title}
        </figcaption>
      </figure>
    ))}
  </div>
  <ScrollBar orientation="horizontal" />
</ScrollArea>

With ScrollBar Visibility

// Always visible scrollbar
<ScrollArea type="always" className="h-48 rounded-md border">
  <div className="p-3">{content}</div>
</ScrollArea>

// Scrollbar only on hover
<ScrollArea type="hover" className="h-48 rounded-md border">
  <div className="p-3">{content}</div>
</ScrollArea>

// Scrollbar only while scrolling (default)
<ScrollArea type="scroll" className="h-48 rounded-md border">
  <div className="p-3">{content}</div>
</ScrollArea>

API Reference

ScrollArea

type
string
default:"hover"
When to show the scrollbar. Values: auto · always · scroll · hover
scrollHideDelay
number
default:"600"
Milliseconds before the scrollbar hides after scrolling stops (when type="scroll").
className
string
Additional class names for the outer container. Use this to set height and width.

ScrollBar

orientation
string
default:"vertical"
Scrollbar direction. Values: vertical · horizontal

Accessibility

  • ScrollArea uses overflow: scroll under the hood — the content remains keyboard scrollable
  • Keyboard users can scroll with Arrow keys, Page Up/Down, and Home/End when the scroll area is focused
  • Screen readers interact with the content inside ScrollArea directly — no special ARIA attributes are needed
  • Ensure the scroll container has a set height/width — without bounds it will expand to fit content and never scroll

Do’s & Don’ts

Do

  • Always set an explicit height (or max-height) on the ScrollArea
  • Add <ScrollBar orientation="horizontal" /> explicitly for horizontal scrolling
  • Use type="always" for sidebars so users always know the list is scrollable
  • Use inside bounded containers: sidebars, modals, cards

Don't

  • Don’t use ScrollArea for full-page scroll — use native page scroll instead
  • Don’t nest multiple ScrollAreas — outer and inner scroll compete on trackpad
  • Don’t forget to set height — without it, the area will never scroll
  • Don’t use for tables — use sticky headers with native table scroll instead