The ScrollArea component provides a customizable scrollable area with smooth scrolling and custom scrollbars. It's designed for content that exceeds the available space and needs to be scrollable. Built on top of @dashflowx/core components.
npm install @dashflowx/core
import { ScrollArea } from '@/components/scrollarea'export default function MyComponent() {return (<ScrollAreaheight="h-80"width="w-64"type="basic"/>)}
import { ScrollArea } from '@/components/scrollarea'export default function CustomScrollArea() {return (<ScrollArea height="h-72" width="w-48"><div className="p-4 space-y-4"><h3 className="text-lg font-semibold">Custom Content</h3>{Array.from({ length: 20 }, (_, i) => (<div key={i} className="p-3 bg-gray-50 rounded">Item {i + 1}</div>))}</div></ScrollArea>)}
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
height | string | 'h-72' | Height of the scroll area |
width | string | 'w-48' | Width of the scroll area |
type | 'basic' | 'tags' | 'messages' | 'files' | 'table' | 'basic' | Type of content to display |
children | React.ReactNode | - | Custom content to display |
orientation | 'vertical' | 'horizontal' | 'both' | 'vertical' | Scroll orientation |
scrollbarSize | 'sm' | 'md' | 'lg' | 'md' | Size of the scrollbar |
showScrollbar | boolean | true | Whether to show scrollbar |
autoHide | boolean | true | Auto-hide scrollbar on hover |
scrollBehavior | 'smooth' | 'auto' | 'smooth' | Scroll behavior |
import { ScrollArea } from '@/components/scrollarea'export default function BasicScrollArea() {return (<ScrollArea type="basic" />)}
Preview:
import { ScrollArea } from '@/components/scrollarea'export default function TagsScrollArea() {return (<ScrollArea type="tags" />)}
Preview:
import { ScrollArea } from '@/components/scrollarea'export default function MessagesScrollArea() {return (<ScrollArea type="messages" />)}
Preview:
import { ScrollArea } from '@/components/scrollarea'export default function FilesScrollArea() {return (<ScrollArea type="files" />)}
Preview:
import { ScrollArea } from '@/components/scrollarea'export default function TableScrollArea() {return (<ScrollArea type="table" />)}
Preview:
import { ScrollArea } from '@/components/scrollarea'export default function SmallScrollArea() {return (<ScrollArea height="h-32" width="w-40" />)}
Preview:
import { ScrollArea } from '@/components/scrollarea'export default function LargeScrollArea() {return (<ScrollArea height="h-96" width="w-64" />)}
Preview:
import { ScrollArea } from '@/components/scrollarea'export default function CustomStyledScrollArea() {return (<ScrollAreaclassName="border border-blue-500 rounded-lg"height="h-80"width="w-56"/>)}
Preview:
import { ScrollArea } from '@/components/scrollarea'export default function CustomContentScrollArea() {return (<ScrollArea height="h-72" width="w-48"><div className="p-4"><h4 className="mb-4 text-sm font-medium">Custom Content</h4><div className="space-y-2"><div className="p-2 bg-blue-50 rounded">Custom item 1</div><div className="p-2 bg-green-50 rounded">Custom item 2</div><div className="p-2 bg-purple-50 rounded">Custom item 3</div>{/* More items... */}</div></div></ScrollArea>)}
Preview:
import { ScrollArea } from '@/components/scrollarea'export default function CustomScrollbarScrollArea() {return (<ScrollAreascrollbarSize="lg"autoHide={false}showScrollbar={true}/>)}
Preview:
import { ScrollArea } from '@/components/scrollarea'export default function HorizontalScrollArea() {return (<ScrollAreaorientation="horizontal"height="h-32"width="w-96"/>)}
Preview:
import { ScrollArea } from '@/components/scrollarea'export default function BothDirectionsScrollArea() {return (<ScrollAreaorientation="both"height="h-64"width="w-80"/>)}
Preview:
import { ScrollArea } from '@/components/scrollarea'export default function AutoHideScrollArea() {return (<ScrollAreaautoHide={true}scrollBehavior="smooth"/>)}
Preview:
import { ScrollArea } from '@/components/scrollarea'export default function ChatApp() {const messages = [{ id: 1, user: 'Alice', message: 'Hello everyone!' },{ id: 2, user: 'Bob', message: 'Hi Alice, how are you?' },{ id: 3, user: 'Charlie', message: 'Good morning!' },// ... more messages];return (<div className="flex flex-col h-96"><div className="p-4 border-b"><h2 className="text-lg font-semibold">Team Chat</h2></div><ScrollAreatype="messages"height="h-full"width="w-full"className="flex-1"/><div className="p-4 border-t"><inputtype="text"placeholder="Type a message..."className="w-full p-2 border rounded"/></div></div>)}
import { ScrollArea } from '@/components/scrollarea'export default function FileExplorer() {return (<div className="w-80 h-96 border rounded-lg"><div className="p-3 border-b bg-gray-50"><h3 className="font-medium">Files</h3></div><ScrollAreatype="files"height="h-full"width="w-full"scrollbarSize="sm"autoHide={true}/></div>)}
import { ScrollArea } from '@/components/scrollarea'export default function DataDashboard() {return (<div className="grid grid-cols-2 gap-4"><div className="border rounded-lg"><div className="p-4 border-b"><h3 className="font-semibold">Recent Activity</h3></div><ScrollAreatype="basic"height="h-64"width="w-full"/></div><div className="border rounded-lg"><div className="p-4 border-b"><h3 className="font-semibold">Data Table</h3></div><ScrollAreatype="table"height="h-64"width="w-full"orientation="both"/></div></div>)}
import { ScrollArea } from '@/components/scrollarea'export default function CodeEditorSidebar() {const files = ['src/components/Button.tsx','src/components/Input.tsx','src/components/Modal.tsx','src/utils/helpers.ts','src/types/index.ts',// ... more files];return (<div className="w-64 h-full bg-gray-900 text-white"><div className="p-3 border-b border-gray-700"><h3 className="text-sm font-medium">Explorer</h3></div><ScrollAreaheight="h-full"width="w-full"className="bg-gray-900"scrollbarSize="sm"><div className="p-2">{files.map((file, index) => (<divkey={index}className="px-2 py-1 text-sm hover:bg-gray-800 rounded cursor-pointer">📄 {file}</div>))}</div></ScrollArea></div>)}
import { ScrollArea } from '@/components/scrollarea'export default function MobileList() {return (<div className="max-w-sm mx-auto"><ScrollAreatype="basic"height="h-96"width="w-full"scrollBehavior="smooth"scrollbarSize="sm"className="border rounded-lg"/></div>)}
import { ScrollArea } from '@/components/scrollarea'const longContentList = (<ScrollArea type="basic" height="h-80" />);
import { ScrollArea } from '@/components/scrollarea'const chatMessages = (<ScrollArea type="messages" height="h-96" />);
import { ScrollArea } from '@/components/scrollarea'const fileList = (<ScrollArea type="files" height="h-72" />);
import { ScrollArea } from '@/components/scrollarea'const dataTable = (<ScrollArea type="table" height="h-80" />);
Set appropriate height for scroll areas.
// ✅ Good - Appropriate height<ScrollArea height="h-72" />// ❌ Avoid - Too tall or too short<ScrollArea height="h-screen" />
Maintain consistent styling across scroll areas.
// ✅ Good - Consistent styling<ScrollArea className="border border-gray-300 rounded-lg" />// ❌ Avoid - Inconsistent styling<ScrollArea className="random-styles" />
Use appropriate content types for different use cases.
// ✅ Good - Use specific types<ScrollArea type="messages" /><ScrollArea type="files" /><ScrollArea type="table" />// ❌ Avoid - Always using basic<ScrollArea type="basic" />
Provide custom content when needed.
// ✅ Good - Custom content<ScrollArea><div className="p-4"><h4>Custom Title</h4><div>Your custom content here</div></div></ScrollArea>// ❌ Avoid - Empty scroll areas<ScrollArea />
Make scroll areas responsive.
// ✅ Good - Responsive sizing<ScrollArea height="h-72 md:h-96" width="w-full md:w-64" />// ❌ Avoid - Fixed sizes only<ScrollArea height="h-72" width="w-48" />
You can customize the scroll area appearance using CSS classes:
<ScrollAreaclassName="border border-gray-300 rounded-lg shadow-lg"height="h-80"width="w-56"/>
Use different themes for different contexts:
// Light theme<ScrollAreaclassName="bg-white border-gray-200"height="h-72"width="w-48"/>// Dark theme<ScrollAreaclassName="bg-gray-900 border-gray-700 text-white"height="h-72"width="w-48"/>// Brand theme<ScrollAreaclassName="bg-blue-50 border-blue-200"height="h-72"width="w-48"/>
Use different sizes for different emphasis levels:
// Small scroll area<ScrollArea height="h-32" width="w-40" />// Standard scroll area<ScrollArea height="h-72" width="w-48" />// Large scroll area<ScrollArea height="h-96" width="w-64" />
Load content dynamically:
import { ScrollArea } from '@/components/scrollarea'import { useState, useEffect } from 'react'export default function DynamicScrollArea() {const [content, setContent] = useState([]);useEffect(() => {// Load content from APIloadContent().then(setContent);}, []);return (<ScrollArea height="h-80" width="w-64"><div className="p-4"><h4 className="mb-4 text-sm font-medium">Dynamic Content</h4>{content.map((item, index) => (<div key={index} className="text-sm py-2 border-b border-gray-200 last:border-b-0">{item}</div>))}</div></ScrollArea>);}
Customize scrollbar appearance:
import { ScrollArea, ScrollBar } from '@/components/scrollarea'export default function CustomScrollbarScrollArea() {return (<ScrollAreaheight="h-72"width="w-48"className="border border-gray-300 rounded-lg"><div className="p-4"><h4 className="mb-4 text-sm font-medium">Custom Scrollbar</h4>{/* Content */}</div><ScrollBar className="bg-gray-200" /></ScrollArea>);}
Handle scroll position:
import { ScrollArea } from '@/components/scrollarea'import { useRef } from 'react'export default function ScrollPositionScrollArea() {const scrollAreaRef = useRef(null);const [scrollPosition, setScrollPosition] = useState(0);const handleScroll = (position) => {setScrollPosition(position);// Save scroll position to localStoragelocalStorage.setItem('scrollPosition', position);};return (<ScrollArearef={scrollAreaRef}height="h-72"width="w-48"onScroll={handleScroll}><div className="p-4"><h4 className="mb-4 text-sm font-medium">Scroll Position: {scrollPosition}</h4>{/* Content */}</div></ScrollArea>);}
Problem: Content is not visible or scrollable.
Solutions:
// ✅ Ensure proper height is set<ScrollArea height="h-72" width="w-48"><div>Your content here</div></ScrollArea>// ❌ Avoid - No height specified<ScrollArea><div>Your content here</div></ScrollArea>
Problem: Scrollbar is not visible.
Solutions:
// ✅ Show scrollbar explicitly<ScrollArea showScrollbar={true} />// ✅ Disable auto-hide for debugging<ScrollArea autoHide={false} />// ✅ Use larger scrollbar<ScrollArea scrollbarSize="lg" />
Problem: Slow scrolling or rendering.
Solutions:
// ✅ Use appropriate content types<ScrollArea type="basic" /> // For simple lists<ScrollArea type="messages" /> // For chat messages<ScrollArea type="files" /> // For file lists// ✅ Limit content amount<ScrollArea>{items.slice(0, 100).map(item => <div key={item.id}>{item.name}</div>)}</ScrollArea>
Problem: Touch scrolling not working properly.
Solutions:
// ✅ Use smooth scroll behavior<ScrollArea scrollBehavior="smooth" />// ✅ Ensure proper sizing<ScrollArea height="h-96" width="w-full" />
- Check Console: Look for error messages in browser console
- Verify Props: Ensure all required props are provided
- Test Content: Try with simple content first
- Check CSS: Verify Tailwind classes are applied correctly
| Feature | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| Basic Scrolling | ✅ | ✅ | ✅ | ✅ |
| Custom Scrollbar | ✅ | ✅ | ✅ | ✅ |
| Smooth Scrolling | ✅ | ✅ | ✅ | ✅ |
| Touch Support | ✅ | ✅ | ✅ | ✅ |
A: Use responsive Tailwind classes for height and width:
<ScrollAreaheight="h-64 md:h-80 lg:h-96"width="w-full md:w-64 lg:w-80"/>
A: Yes, use the scrollbarSize prop and custom CSS:
<ScrollAreascrollbarSize="lg"className="[&::-webkit-scrollbar]:w-4 [&::-webkit-scrollbar-track]:bg-gray-100"/>
A: Use the children prop with state management:
const [items, setItems] = useState([]);<ScrollArea>{items.map(item => <div key={item.id}>{item.name}</div>)}</ScrollArea>
A: Yes, it includes proper ARIA attributes and keyboard navigation support.
A: Yes, it supports touch scrolling and is mobile-friendly.
A: Set autoHide={false}:
<ScrollArea autoHide={false} />
A: Yes, use orientation="both":
<ScrollArea orientation="both" />
- List: For list content
- Table: For tabular data
- Card: For content containers
- Panel: For panel content
- Container: For content containers
For the complete API reference and advanced usage patterns, see the ScrollArea API documentation.
