Skip to the content
BooleanPress UI

Panel

Scroll area

Scrolls content inside a fixed box, with a scrollbar styled to the theme.

Import

import { ScrollArea, ScrollBar } from "@booleanpress/ui/scroll-area"

Usage

Give the scroll area a size. Content that is taller or wider than the box scrolls inside it.

import { ScrollArea } from "@booleanpress/ui/scroll-area"

export function Events({ events }: { events: string[] }) {
  return (
    <ScrollArea className="h-56 w-64 rounded-md border">
      <ul className="p-4">
        {events.map((event) => (
          <li key={event}>{event}</li>
        ))}
      </ul>
    </ScrollArea>
  )
}

It draws a vertical scrollbar. For sideways scrolling, add <ScrollBar orientation="horizontal" /> as a child, and make the content wider than the box (w-max). The scrollbar shows while the pointer is over the area or the content scrolls. The area has no padding and no border: give them with className (on the area) or on the content.

Examples

Vertical

A list of 20 events in a box 14 rem tall, scrolled with the wheel, touch or the scrollbar.

Horizontal

A row of mailers wider than the box; ScrollBar with orientation="horizontal" adds the bar.

Accessibility

Semantics
A div for the area and a div viewport that holds the content. The scrollbars carry no role or name. The content stays in reading order.
Labels
The area has no role or name. Add role="region" and aria-label to the area when the box is a distinct part of the page that people should be able to find.
Focus
The viewport is not focusable. A keyboard user can scroll it only when content inside it takes focus (a link, a button), because the browser scrolls a focused control into view.
Known limits
  • Content with no focusable control cannot be scrolled from the keyboard in every browser: WCAG 2.1.1 asks for it. ScrollArea does not pass props to its viewport, so it cannot take tabIndex={0}. Put a focusable element in the content, or make the first item focusable.
  • The 10 px scrollbar is a small target for a pointer; the wheel, touch and trackpad scroll without it.

Keyboard

Keyboard
KeyBehaviour

API

ScrollArea

Renders Radix ScrollArea.Root and passes it every other prop.

ScrollArea props
PropTypeDefaultDescription
asChildboolean
dir"ltr" | "rtl"The reading direction. It follows the provider's dir unless set here.
scrollHideDelaynumberMilliseconds before the scrollbar hides again (default 600).
type"auto" | "hover" | "always" | "scroll"When the scrollbar shows: hover (default), scroll, auto or always.

ScrollBar

Renders Radix ScrollArea.ScrollAreaScrollbar and passes it every other prop.

ScrollBar props
PropTypeDefaultDescription
asChildboolean
forceMounttrue
orientation"horizontal" | "vertical"verticalvertical (default) or horizontal.

Every part takes className, merged with its defaults by cn(), and ref, which reaches the element it renders.

Data attributes: data-slot="scroll-area" (ScrollArea), data-slot="scroll-area-scrollbar" (ScrollBar).

Theming

The tokens its classes read. Change their values in your theme, and it follows.

Theme tokens
TokenUsed for
--borderbackground
--ringfocus ring