import * as React from 'react'; import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area'; import { cn } from '../../lib/utils'; import { Icons } from '../Icons'; /** * Props interface for the ScrollArea component. * Extends Radix UI ScrollArea root props. */ interface ScrollAreaProps extends React.ComponentPropsWithoutRef { /** Flag to show/hide scroll indicator arrows at top and bottom */ showArrows?: boolean; type?: 'auto' | 'always' | 'scroll'; } /** * A custom scroll area component built on top of Radix UI's ScrollArea. * Provides a scrollable container with custom styling and optional scroll indicators. * * @param props - The component props * @param props.className - Additional CSS classes to apply * @param props.children - The content to be scrolled * @param props.showArrows - Whether to show scroll indicator arrows * @param ref - Forward ref for the root element * * @example * ```tsx * *
Scrollable content
*
* ``` */ const ScrollArea = React.forwardRef< React.ElementRef, ScrollAreaProps >(({ className, children, showArrows = false, ...props }, ref) => { const [showBottomArrow, setShowBottomArrow] = React.useState(false); const [showTopArrow, setShowTopArrow] = React.useState(false); const viewportRef = React.useRef(null); const checkScroll = React.useCallback(() => { if (viewportRef.current) { const { scrollHeight, clientHeight, scrollTop } = viewportRef.current; setShowBottomArrow(scrollHeight > clientHeight && scrollTop < scrollHeight - clientHeight); setShowTopArrow(scrollTop > 0); } }, []); React.useEffect(() => { checkScroll(); window.addEventListener('resize', checkScroll); return () => window.removeEventListener('resize', checkScroll); }, [checkScroll]); return ( {children} {showArrows && showTopArrow && (
)} {showArrows && showBottomArrow && (
)}
); }); ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName; /** * Custom scrollbar component for the ScrollArea. * Provides styled scrollbars that can be either vertical or horizontal. * * @param props - The component props * @param props.className - Additional CSS classes to apply * @param props.orientation - The scrollbar orientation ('vertical' | 'horizontal') * @param ref - Forward ref for the scrollbar element * * @example * ```tsx * * ``` */ const ScrollBar = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, orientation = 'vertical', ...props }, ref) => ( )); ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName; export { ScrollArea, ScrollBar };