ScrollArea (components/ui/scroll-area.tsx)¶
Overview¶
A customizable scroll area component built with Radix UI that provides cross-browser styled scrollbars with support for both vertical and horizontal scrolling.
Features¶
- Custom scrollbars
- Horizontal scrolling
- Vertical scrolling
- Thumb dragging
- Smooth scrolling
- Responsive design
- Accessibility support
- ARIA attributes
- Touch support
- Custom styling
Dependencies¶
import * as React from 'react'
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area'
import { cva, type VariantProps } from 'class-variance-authority'
import { cn } from '@/lib/utils'
Props¶
interface ScrollAreaProps extends React.HTMLAttributes<HTMLDivElement> {
orientation?: 'vertical' | 'horizontal' | 'both';
type?: 'auto' | 'always' | 'scroll' | 'hover';
scrollHideDelay?: number;
className?: string;
}
interface ScrollBarProps extends ScrollAreaPrimitive.ScrollAreaScrollbarProps {
orientation?: 'vertical' | 'horizontal';
className?: string;
}
Implementation¶
State Management¶
const [isScrolling, setIsScrolling] = useState(false);
const [scrollPos, setScrollPos] = useState({ x: 0, y: 0 });
useEffect(() => {
if (type === 'hover') {
const timer = setTimeout(() => {
setIsScrolling(false);
}, scrollHideDelay);
return () => clearTimeout(timer);
}
}, [isScrolling, type, scrollHideDelay]);
Methods¶
const handleScroll = (event: React.UIEvent<HTMLDivElement>) => {
const target = event.currentTarget;
setScrollPos({
x: target.scrollLeft,
y: target.scrollTop
});
setIsScrolling(true);
};
const handleScrollEnd = () => {
if (type === 'hover') {
setIsScrolling(false);
}
};
Unique Functionality¶
- Custom scrollbar rendering
- Scroll position tracking
- Visibility control
- Touch interaction
- Orientation handling
- ARIA attributes
HTML Structure¶
<ScrollAreaPrimitive.Root
type={type}
className={cn("relative overflow-hidden", className)}
{...props}
>
<ScrollAreaPrimitive.Viewport
className="h-full w-full rounded-[inherit]"
onScroll={handleScroll}
>
{children}
</ScrollAreaPrimitive.Viewport>
<ScrollBar
orientation="vertical"
className={cn(
"flex touch-none select-none transition-colors",
orientation !== 'horizontal' && "h-full w-2.5 border-l border-l-transparent p-[1px]",
type === 'hover' && !isScrolling && "opacity-0"
)}
/>
<ScrollBar
orientation="horizontal"
className={cn(
"flex touch-none select-none transition-colors",
orientation !== 'vertical' && "h-2.5 border-t border-t-transparent p-[1px]",
type === 'hover' && !isScrolling && "opacity-0"
)}
/>
<ScrollAreaPrimitive.Corner className="bg-border" />
</ScrollAreaPrimitive.Root>
<ScrollAreaPrimitive.ScrollAreaScrollbar
orientation={orientation}
className={cn(
"flex touch-none select-none transition-colors",
orientation === 'vertical' && "h-full w-2.5 border-l border-l-transparent p-[1px]",
orientation === 'horizontal' && "h-2.5 border-t border-t-transparent p-[1px]",
className
)}
{...props}
>
<ScrollAreaPrimitive.ScrollAreaThumb
className={cn(
"relative rounded-full bg-border",
orientation === 'vertical' && "flex-1",
orientation === 'horizontal' && "flex-1"
)}
/>
</ScrollAreaPrimitive.ScrollAreaScrollbar>
API Integration¶
No direct API integration.
Components Used¶
Exports the following components: - ScrollArea - ScrollBar - ScrollAreaViewport - ScrollAreaScrollbar - ScrollAreaThumb - ScrollAreaCorner
Notes¶
- Built on Radix UI primitives
- Handles both scroll directions
- Manages scrollbar visibility
- Provides smooth scrolling
- Maintains accessibility features
- Supports custom styling
- Uses semantic HTML elements