ScrollArea A custom scrollbar container for consistent cross-browser scroll appearance. Built on Radix UI ScrollArea.
The ScrollArea component replaces native browser scrollbars with styled, consistent scrollbar tracks and thumbs that match the design system's visual language. Built on Radix UI's ScrollArea primitive for cross-browser consistency.
Install the component via the CLI in one command.
npm pnpm yarn bun
npx @work-rjkashyap/unified-ui add scroll-area pnpm dlx @work-rjkashyap/unified-ui add scroll-area npx @work-rjkashyap/unified-ui add scroll-area bunx @work-rjkashyap/unified-ui add scroll-area
If you haven't initialized your project yet, run npx @work-rjkashyap/unified-ui init first. See the CLI docs for details.
Use this approach if you prefer to install the entire design system as a dependency instead of copying individual components.
npm pnpm yarn bun
npm install @work-rjkashyap/unified-ui pnpm add @work-rjkashyap/unified-ui yarn add @work-rjkashyap/unified-ui bun add @work-rjkashyap/unified-ui
import {
ScrollArea,
ScrollBar,
} from "@work-rjkashyap/unified-ui" ;
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos.
<ScrollArea className="h-48 w-full rounded-md border"> <div className="p-4 space-y-4"> <p>Lorem ipsum dolor sit amet...</p> <p>Ut enim ad minim veniam...</p> <p>Duis aute irure dolor...</p> <p>Excepteur sint occaecat...</p> <p>Sed ut perspiciatis...</p> <p>Nemo enim ipsam voluptatem...</p> </div> </ScrollArea>
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12
<ScrollArea className="w-full rounded-md border" showHorizontal showVertical={false}> <div className="flex gap-4 p-4 w-max"> {items.map((item, i) => ( <div key={i} className="flex h-20 w-28 shrink-0 items-center justify-center rounded-md border bg-muted"> Item {i + 1} </div> ))} </div> </ScrollArea>
Small (sm)
List item 1 — some content here
List item 2 — some content here
List item 3 — some content here
List item 4 — some content here
List item 5 — some content here
List item 6 — some content here
List item 7 — some content here
List item 8 — some content here
List item 9 — some content here
List item 10 — some content here
Medium (md)
List item 1 — some content here
List item 2 — some content here
List item 3 — some content here
List item 4 — some content here
List item 5 — some content here
List item 6 — some content here
List item 7 — some content here
List item 8 — some content here
List item 9 — some content here
List item 10 — some content here
{/* Small scrollbar */} <ScrollArea className="h-36 rounded-md border" scrollbarSize="sm" type="always"> <div className="p-3 space-y-3"> {items.map((_, i) => <p key={i}>List item {i + 1}</p>)} </div> </ScrollArea> {/* Medium scrollbar (default) */} <ScrollArea className="h-36 rounded-md border" scrollbarSize="md" type="always"> <div className="p-3 space-y-3"> {items.map((_, i) => <p key={i}>List item {i + 1}</p>)} </div> </ScrollArea>
Size Track Width Description sm6px Thin scrollbar for compact UIs md10px Default scrollbar width
type="always" — scrollbar always visible
Always visible scrollbar — item 1
Always visible scrollbar — item 2
Always visible scrollbar — item 3
Always visible scrollbar — item 4
Always visible scrollbar — item 5
Always visible scrollbar — item 6
Always visible scrollbar — item 7
Always visible scrollbar — item 8
type="hover" — scrollbar on hover (default)
Hover to see scrollbar — item 1
Hover to see scrollbar — item 2
Hover to see scrollbar — item 3
Hover to see scrollbar — item 4
Hover to see scrollbar — item 5
Hover to see scrollbar — item 6
Hover to see scrollbar — item 7
Hover to see scrollbar — item 8
{/* Always visible */} <ScrollArea className="h-28 rounded-md border" type="always"> {content} </ScrollArea> {/* Visible on hover (default) */} <ScrollArea className="h-28 rounded-md border" type="hover"> {content} </ScrollArea> {/* Visible during scroll only */} <ScrollArea className="h-28 rounded-md border" type="scroll"> {content} </ScrollArea> {/* Auto — visible when content overflows */} <ScrollArea className="h-28 rounded-md border" type="auto"> {content} </ScrollArea>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<ScrollArea className="h-48 w-full rounded-md border" showHorizontal type="always"> <div className="p-4 w-[600px]"> <div className="grid grid-cols-6 gap-3"> {Array.from({ length: 36 }).map((_, i) => ( <div key={i} className="flex h-14 w-20 items-center justify-center rounded-md border bg-muted"> {i + 1} </div> ))} </div> </div> </ScrollArea>
Prop Type Default Description type"auto" | "always" | "scroll" | "hover""hover"Scrollbar visibility behavior. scrollbarSize"sm" | "md""md"Size of the scrollbar track. showVerticalbooleantrueWhether to show the vertical scrollbar. showHorizontalbooleanfalseWhether to show the horizontal scrollbar. viewportClassNamestring— Additional CSS classes for the viewport element. classNamestring— Additional CSS classes for the root element.
Prop Type Default Description orientation"vertical" | "horizontal""vertical"Orientation of the scrollbar. size"sm" | "md""md"Size of the scrollbar. classNamestring— Additional CSS classes.
The custom scrollbars are purely decorative. Keyboard scrolling and assistive technology use the native scrollable region underneath.
Keyboard scrolling — Not intercepted; works natively via arrow keys, Page Up/Down, Home/End.
Screen readers — Announce the scrollable region naturally; custom scrollbar is invisible to assistive technology.
Focus management — Tab order and focus are preserved within the scrollable content.
Touch devices — Native touch scrolling is preserved; custom scrollbars are visual only.
Token Usage --borderScrollbar thumb color --muted-foregroundScrollbar thumb hover color --mutedScrollbar track hover tint --duration-fastTransition speed for hover --easing-standardEasing curve for transitions