Scroll Area
Augments native scroll functionality for custom, cross-browser styling.
Installation
bash
npx shadcn@latest add @redpanda/scroll-areabash
pnpm dlx shadcn@latest add @redpanda/scroll-areabash
yarn dlx shadcn@latest add @redpanda/scroll-areabash
bunx shadcn@latest add @redpanda/scroll-areabash
nubx shadcn@latest add @redpanda/scroll-areabash
aube dlx shadcn@latest add @redpanda/scroll-areaWhen to use
Scroll Area provides custom, cross-browser scrolling with consistent styling. Use this decision tree to determine when it’s appropriate:
Usage
Basic Vertical Scrolling
tsx
import { ScrollArea } from '@/components/redpanda-ui/scroll-area';
<ScrollArea className="h-[200px] w-[350px] rounded-md border p-4"> <div className="space-y-4"> <p>Long content that will scroll...</p> <p> Jokester began sneaking into the castle in the middle of the night and leaving jokes all over the place: under the king's pillow, in his soup, even in the royal toilet. </p> <p> The king was furious, but he couldn't seem to stop Jokester. And then, one day, the people of the kingdom discovered that the jokes left by Jokester were so funny that they couldn't help but laugh. </p> <p>And once they started laughing, they couldn't stop.</p> </div></ScrollArea>;Horizontal Scrolling
tsx
<ScrollArea className="w-96 whitespace-nowrap rounded-md border"> <div className="flex w-max space-x-4 p-4"> <div className="shrink-0 w-[250px] h-[125px] rounded-md bg-surface-subtle" /> <div className="shrink-0 w-[250px] h-[125px] rounded-md bg-surface-subtle" /> <div className="shrink-0 w-[250px] h-[125px] rounded-md bg-surface-subtle" /> <div className="shrink-0 w-[250px] h-[125px] rounded-md bg-surface-subtle" /> </div></ScrollArea>List with Scrollable Content
tsx
<ScrollArea className="h-72 w-48 rounded-md border"> <div className="p-4"> <h4 className="mb-4 text-sm font-medium leading-none">Tags</h4> {Array.from({ length: 50 }).map((_, i) => ( <div key={i} className="text-sm mb-2"> v1.2.0-beta.{i} </div> ))} </div></ScrollArea>With Custom Scrollbar
tsx
import { ScrollArea, ScrollBar } from '@/components/redpanda-ui/scroll-area';
<ScrollArea className="h-[300px] w-[400px] rounded-md border"> <div className="p-4"> {/* Your scrollable content */} <div className="space-y-4"> {Array.from({ length: 20 }).map((_, i) => ( <div key={i} className="p-4 border rounded"> Item {i + 1}: This is some content that demonstrates scrolling behavior. </div> ))} </div> </div> <ScrollBar orientation="vertical" /> <ScrollBar orientation="horizontal" /></ScrollArea>;Nested Scroll Areas
tsx
<ScrollArea className="h-[400px] w-[600px] rounded-md border p-4"> <div className="space-y-4"> <h3 className="text-lg font-semibold">Main Content Area</h3> <p>This outer area scrolls vertically...</p>
<ScrollArea className="h-[150px] w-full rounded-md border p-2"> <div className="space-y-2"> <h4 className="font-medium">Nested Scrollable Section</h4> {Array.from({ length: 15 }).map((_, i) => ( <p key={i} className="text-sm"> Nested content item {i + 1} </p> ))} </div> </ScrollArea>
<p>More content continues here...</p> </div></ScrollArea>Anatomy
The Scroll Area component is built with Base UI primitives and provides custom scrollbar styling:
plaintext
<ScrollArea> (Root Container)├── <ScrollAreaPrimitive.Root>│ ├── className: "relative"│ └── Custom positioning context├── <ScrollAreaPrimitive.Viewport> (Content Container)│ ├── className: "size-full rounded-[inherit]"│ ├── Focus management with ring styling│ ├── Content rendering area│ └── Scroll behavior container├── <ScrollBar> (Custom Scrollbar)│ ├── <ScrollAreaPrimitive.Scrollbar>│ │ ├── orientation: "vertical" | "horizontal"│ │ ├── Touch-friendly interaction (touch-none)│ │ └── Transition animations│ └── <ScrollAreaPrimitive.Thumb>│ ├── Visual scroll indicator│ ├── Rounded styling (rounded-full)│ └── Dynamic sizing based on content└── <ScrollAreaPrimitive.Corner> └── Corner element for dual-axis scrolling
Styling System:├── Scrollbar Track - border styling for visual separation├── Scrollbar Thumb - bg-border with flex-1 sizing├── Focus Indicators - ring styling for accessibility└── Responsive Sizing - adapts to container dimensionsKey Features:
- Cross-browser Consistency: Same scrollbar appearance across all browsers
- Keyboard Navigation: Full keyboard accessibility support
- Touch Support: Optimized for touch devices with proper touch handling
- Customizable Styling: Easy to theme and customize appearance
- Dual-axis Scrolling: Supports both horizontal and vertical scrolling
- Focus Management: Proper focus indicators for accessibility