UnflowUI
Components

Scrollable

A scroll container with a consistently styled custom scrollbar. Supports vertical, horizontal, or both-axis scrolling with optional smooth scroll and persistent scrollbar gutter.

Overview

Scrollable wraps any content in a <div> with controlled overflow and a custom scrollbar style. height and width are set as inline styles, so you can use any CSS value (px, %, vh, etc.).

Import

import { Scrollable } from '@unflow/ui/components/Scrollable';

Props

PropTypeDefaultDescription
direction'vertical' | 'horizontal' | 'both'Scroll axis. When omitted, both axes scroll.
heightstringContainer height (CSS value)
widthstringContainer width (CSS value)
smoothbooleanfalseEnables scroll-behavior: smooth
persistentbooleanfalseReserves gutter space for the scrollbar (scrollbar-gutter: stable)

All standard HTMLDivElement props are forwarded to the container.

Vertical scroll

List item 1
List item 2
List item 3
List item 4
List item 5
List item 6
List item 7
List item 8
List item 9
List item 10
List item 11
List item 12
<Scrollable direction="vertical" height="160px">
  {items.map((item) => <div key={item.id}>{item.label}</div>)}
</Scrollable>

Horizontal scroll

Card 1
Card 2
Card 3
Card 4
Card 5
Card 6
Card 7
Card 8
<Scrollable direction="horizontal" width="300px">
  <div style={{ width: 'max-content', display: 'flex', gap: '12px' }}>
    {cards.map((card) => <Card key={card.id} {...card} />)}
  </div>
</Scrollable>

For horizontal scroll, make the inner content wider than the container. Use width: max-content or a fixed width on the inner element.

Smooth scrolling

<Scrollable direction="vertical" height="300px" smooth>
  {longContent}
</Scrollable>

Smooth scroll is useful for programmatic scroll (e.g. .scrollTo()) — user drag-scroll always feels instant regardless.

Persistent gutter

<Scrollable direction="vertical" height="300px" persistent>
  {content}
</Scrollable>

persistent reserves gutter space even when the scrollbar isn't visible, preventing layout shifts as content grows in/out of overflow.

Accessibility

  • The container has no semantic role — it's a layout primitive.
  • Ensure scrollable regions are reachable via keyboard (Tab focus should enter the container, then arrow keys scroll).
  • If the scrollable region contains interactive elements, they will be naturally Tab-navigable.