Cognition

Components

Scroll Area

A bounded container that replaces native browser scrollbars with custom Cognition-styled ones. Use it when content can exceed the space it has.

Preview

Tags

v1.2.0-beta.50
v1.2.0-beta.49
v1.2.0-beta.48
v1.2.0-beta.47
v1.2.0-beta.46
v1.2.0-beta.45
v1.2.0-beta.44
v1.2.0-beta.43
v1.2.0-beta.42
v1.2.0-beta.41
v1.2.0-beta.40
v1.2.0-beta.39
v1.2.0-beta.38
v1.2.0-beta.37
v1.2.0-beta.36
v1.2.0-beta.35
v1.2.0-beta.34
v1.2.0-beta.33
v1.2.0-beta.32
v1.2.0-beta.31
v1.2.0-beta.30
v1.2.0-beta.29
v1.2.0-beta.28
v1.2.0-beta.27

Rendered with live Cognition tokens. Toggle the theme and it remaps, no dark: classes.

Variants

v1.2.0-beta.50
v1.2.0-beta.49
v1.2.0-beta.48
v1.2.0-beta.47
v1.2.0-beta.46
v1.2.0-beta.45
v1.2.0-beta.44
v1.2.0-beta.43
v1.2.0-beta.42
v1.2.0-beta.41
v1.2.0-beta.40
v1.2.0-beta.39
v1.2.0-beta.38
v1.2.0-beta.37
v1.2.0-beta.36
v1.2.0-beta.35
v1.2.0-beta.34
v1.2.0-beta.33
v1.2.0-beta.32
v1.2.0-beta.31
v1.2.0-beta.30
v1.2.0-beta.29
v1.2.0-beta.28
v1.2.0-beta.27
<ScrollArea className="h-44 w-40" />
All issues
Assigned to me
Recently updated
Closed this week
High priority
Awaiting review
<ScrollArea>
  <ScrollBar orientation="horizontal" />
</ScrollArea>
v1.2.0-beta.50released to staging on June 6, 2026
v1.2.0-beta.49released to staging on June 6, 2026
v1.2.0-beta.48released to staging on June 6, 2026
v1.2.0-beta.47released to staging on June 6, 2026
v1.2.0-beta.46released to staging on June 6, 2026
v1.2.0-beta.45released to staging on June 6, 2026
v1.2.0-beta.44released to staging on June 6, 2026
v1.2.0-beta.43released to staging on June 6, 2026
v1.2.0-beta.42released to staging on June 6, 2026
v1.2.0-beta.41released to staging on June 6, 2026
v1.2.0-beta.40released to staging on June 6, 2026
v1.2.0-beta.39released to staging on June 6, 2026
v1.2.0-beta.38released to staging on June 6, 2026
v1.2.0-beta.37released to staging on June 6, 2026
<ScrollArea className="h-44 w-44" />

Add a horizontal ScrollBar for the horizontal and both-axes layouts. The vertical bar is built in.

States

v1.2.0-beta.50
v1.2.0-beta.49
v1.2.0-beta.48
v1.2.0-beta.47

Default. Content fits, so no scrollbar appears.

v1.2.0-beta.50
v1.2.0-beta.49
v1.2.0-beta.48
v1.2.0-beta.47
v1.2.0-beta.46
v1.2.0-beta.45
v1.2.0-beta.44
v1.2.0-beta.43
v1.2.0-beta.42
v1.2.0-beta.41
v1.2.0-beta.40
v1.2.0-beta.39
v1.2.0-beta.38
v1.2.0-beta.37
v1.2.0-beta.36
v1.2.0-beta.35
v1.2.0-beta.34
v1.2.0-beta.33
v1.2.0-beta.32
v1.2.0-beta.31
v1.2.0-beta.30
v1.2.0-beta.29
v1.2.0-beta.28
v1.2.0-beta.27
<ScrollArea type="always" />
v1.2.0-beta.50
v1.2.0-beta.49
v1.2.0-beta.48
v1.2.0-beta.47
v1.2.0-beta.46
v1.2.0-beta.45
v1.2.0-beta.44
v1.2.0-beta.43
v1.2.0-beta.42
v1.2.0-beta.41
v1.2.0-beta.40
v1.2.0-beta.39
v1.2.0-beta.38
v1.2.0-beta.37
v1.2.0-beta.36
v1.2.0-beta.35
v1.2.0-beta.34
v1.2.0-beta.33
v1.2.0-beta.32
v1.2.0-beta.31
v1.2.0-beta.30
v1.2.0-beta.29
v1.2.0-beta.28
v1.2.0-beta.27

Overflow. Content exceeds the container; the bar shows on hover or scroll.

The thumb uses border-strong so it stays visible on both themes. Set type="always" to keep the bar shown.

API

Prop
Type
Default
Description
type
"auto" | "always" | "scroll" | "hover"
"hover"
When the scrollbar is shown. hover shows it on pointer over; always keeps it visible.
scrollHideDelay
number
600
Milliseconds before the scrollbar hides after scrolling stops (types other than always).
dir
"ltr" | "rtl"
"ltr"
Reading direction, which side the vertical scrollbar sits on.

Compose with ScrollBar (it takes an orientation) for horizontal or both-axes scrolling.

Don't and Do

Don't

Don't wrap content that already fits its container. A Scroll Area earns its place only when content can exceed the space it has. Around content that never overflows it adds a control the reader never needs.

Do
<ScrollArea className="h-72 w-48 rounded-md border">
  <div className="p-4">
    {tags.map((tag) => (
      <div key={tag} className="py-2 text-sm">
        {tag}
      </div>
    ))}
  </div>
</ScrollArea>

Reach for it on long lists, code blocks, and any bounded container with variable-length content.

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

export function TagList({ tags }: { tags: string[] }) {
  return (
    <ScrollArea className="h-72 w-48 rounded-md border border-border-default">
      <div className="divide-y divide-border-default p-4">
        {tags.map((tag) => (
          <div key={tag} className="py-2 text-sm text-text-default">
            {tag}
          </div>
        ))}
      </div>
    </ScrollArea>
  );
}