Glin UI
Primitive / Moleculebeta

Scroll Area

Custom-styled scroll container with vertical and horizontal scrollbars that keeps native scrolling.

Edit on GitHub

Changelog

Recent releases

  1. v2.8.0Oct 6

    Scheduled exports and a new CSV mapper.

    Feature
  2. v2.7.3Sep 29

    Timezone drift in recurring reports.

    Fix
  3. v2.7.2Sep 22

    Dropdown menus now close on route change.

    Fix
  4. v2.7.0Sep 15

    Dark appearance for the billing portal.

    Feature
  5. v2.6.4Sep 8

    Dashboard loads 38 percent faster.

    Perf
  6. v2.6.0Aug 30

    Team roles with per-project access.

    Feature
  7. v2.5.2Aug 21

    Webhook retries respect the backoff header.

    Fix
  8. v2.5.0Aug 12

    Audit log with 90 day retention.

    Feature

Installation

Install from
pnpm dlx @glinui/cli@latest add scroll-area

Prefer the package?

Usage

Variants

Every vocabulary variant on the default tone. Omit variant to follow the ambient design style. Omitted variant renders a chromeless region like the shadcn primitive.

First row
Second row
Third row
Fourth row
First row
Second row
Third row
Fourth row
First row
Second row
Third row
Fourth row
First row
Second row
Third row
Fourth row
First row
Second row
Third row
Fourth row
First row
Second row
Third row
Fourth row
import { ScrollArea } from "@glinui/ui"
export function ScrollAreaVariantsDemo() {
return (
<div className="grid gap-4 md:grid-cols-2">
<ScrollArea variant="glinr" className="h-24 w-full"><div className="space-y-1 p-3 text-sm"><div>First row</div><div>Second row</div><div>Third row</div><div>Fourth row</div></div></ScrollArea>
<ScrollArea variant="solid" className="h-24 w-full"><div className="space-y-1 p-3 text-sm"><div>First row</div><div>Second row</div><div>Third row</div><div>Fourth row</div></div></ScrollArea>
<ScrollArea variant="soft" className="h-24 w-full"><div className="space-y-1 p-3 text-sm"><div>First row</div><div>Second row</div><div>Third row</div><div>Fourth row</div></div></ScrollArea>
<ScrollArea variant="outline" className="h-24 w-full"><div className="space-y-1 p-3 text-sm"><div>First row</div><div>Second row</div><div>Third row</div><div>Fourth row</div></div></ScrollArea>
<ScrollArea variant="ghost" className="h-24 w-full"><div className="space-y-1 p-3 text-sm"><div>First row</div><div>Second row</div><div>Third row</div><div>Fourth row</div></div></ScrollArea>
<ScrollArea variant="gradient" className="h-24 w-full"><div className="space-y-1 p-3 text-sm"><div>First row</div><div>Second row</div><div>Third row</div><div>Fourth row</div></div></ScrollArea>
</div>
)
}

Horizontal

A horizontal strip with its own scrollbar.

1 / 8
Overview
2 / 8
Reports
3 / 8
Billing
4 / 8
Members
5 / 8
Audit log
6 / 8
Webhooks
7 / 8
API keys
8 / 8
Settings
import { ScrollArea, ScrollBar } from "@glinui/ui"
export function Demo() {
const shots = ["Overview", "Reports", "Billing", "Members", "Audit log", "Webhooks", "API keys", "Settings"]
return (
<ScrollArea className="w-full max-w-lg whitespace-nowrap rounded-xl border border-[var(--line-soft)]" aria-label="Screens">
<div className="flex gap-3 p-4">
{shots.map((shot, index) => (
<figure key={shot} className="flex shrink-0 flex-col gap-2">
<div className="flex h-24 w-40 items-center justify-center rounded-lg bg-[var(--surface-3)] text-xs font-medium text-[var(--color-muted)]">
{index + 1} / {shots.length}
</div>
<figcaption className="text-sm font-medium">{shot}</figcaption>
</figure>
))}
</div>
<ScrollBar orientation="horizontal" />
</ScrollArea>
)
}

Accessibility

  • Native scrolling is preserved, so wheel, touch, and keyboard scroll work as usual.
  • The viewport is focusable with a visible violet focus ring so keyboard users can scroll it.

Keyboard Interactions

KeyAction
TabFocus the viewport.
Arrow keys / PageUp / PageDownScroll the focused viewport.

ARIA Attributes

  • Add `aria-label` or `aria-labelledby` on the viewport region when it is a landmark.

Reduced Motion

Scrollbar fade transitions are disabled with reduced motion.

Affected properties

opacitybackground-color

API Reference

ScrollArea

PropTypeRequiredDefaultDescription
variantSurfaceVariant | "default"Noplain (chromeless)Surface variant. Omit to follow the ambient design style (glinr by default, plain for minimal, glass for glass).
toneSurfaceToneNoneutralColour tone for the vocabulary variants.
viewportClassNamestringNo-Class names applied to the scrollable viewport.
type"auto" | "always" | "scroll" | "hover"-hoverWhen scrollbars are visible (Radix).
dir"ltr" | "rtl"--Reading direction for scrollbar placement.

ScrollBar

PropTypeRequiredDefaultDescription
orientation"vertical" | "horizontal"-verticalAdd a horizontal ScrollBar for wide content.
toneSurfaceToneNo-Auto-generated from TypeScript source.
variantSurfaceVariant | "default"No-Surface variant. Omit (or `plain`) for a chromeless scroll region like the shadcn primitive. Vocabulary: glinr, solid, soft, outline, ghost, gradient, glass. Legacy `default` maps to glinr.
viewportClassNamestringNo-Class names for the scrollable viewport.

Source

Import directly from the package or browse the source on GitHub. Click any file to view it.

Import

import { ScrollArea } from "@glinui/ui"

Source Files

Dependencies

@glinui/ui@radix-ui/react-scroll-areaclass-variance-authority

Generated API Snapshot

Beta

Auto-extracted from TypeScript source in packages/ui/src/components/scroll-area.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.

Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata

Primary Props Type

ScrollAreaProps

ScrollAreaProps

PropTypeRequiredDefaultDescription
toneSurfaceToneNo--
variantSurfaceVariant | "default"No-Surface variant. Omit (or `plain`) for a chromeless scroll region like the shadcn primitive. Vocabulary: glinr, solid, soft, outline, ghost, gradient, glass. Legacy `default` maps to glinr.
viewportClassNamestringNo-Class names for the scrollable viewport.

ScrollBarProps

No explicit fields extracted for this props type.