import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"; import * as React from "react"; import { useMemo } from "react"; import { cn } from "@sparkle/lib/utils"; interface ScrollAreaProps extends React.ComponentPropsWithoutRef< typeof ScrollAreaPrimitive.Root > { hideScrollBar?: boolean; orientation?: "vertical" | "horizontal"; scrollBarClassName?: string; viewportClassName?: string; scrollStyles?: { active?: string; inactive?: string; }; viewportRef?: React.RefObject; } const ScrollArea = React.forwardRef< React.ElementRef, ScrollAreaProps >( ( { className, children, hideScrollBar = false, orientation = "vertical", scrollBarClassName, viewportClassName, scrollStyles, viewportRef, ...props }, ref ) => { const localViewportRef = React.useRef(null); const [isScrolled, setIsScrolled] = React.useState(false); const hasCustomScrollBar = useMemo( () => React.Children.toArray(children).some( (child) => React.isValidElement(child) && (child.type as typeof ScrollBar).displayName === ScrollBar.displayName ), [children] ); const shouldHideDefaultScrollBar = hideScrollBar || hasCustomScrollBar; const handleScroll = React.useCallback(() => { if (viewportRef && viewportRef.current) { setIsScrolled(viewportRef.current.scrollTop > 0); } if (localViewportRef.current) { setIsScrolled(localViewportRef.current.scrollTop > 0); } }, []); return ( {children} ); } ); ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName; const scrollBarSizes = { compact: { bar: { vertical: "s-w-5", horizontal: "s-h-5", }, padding: { vertical: "s-pr-1 s-pl-2.5 s-py-2 hover:s-pl-2", horizontal: "s-pb-1 s-pt-2.5 s-px-2", }, thumb: cn( "s-bg-muted-foreground/40 dark:s-bg-muted-foreground-night/40", "hover:s-bg-muted-foreground/70 dark:hover:s-bg-muted-foreground-night/70" ), }, classic: { bar: { vertical: "s-w-5", horizontal: "s-h-5", }, padding: { vertical: "s-pl-2 s-pr-1 s-py-1", horizontal: "s-py-0.5 s-px-1", }, thumb: cn( "s-bg-muted-foreground/70 dark:s-bg-muted-foreground-night/70", "hover:s-bg-muted-foreground/80 dark:hover:s-bg-muted-foreground-night/80" ), }, minimal: { bar: { vertical: "s-w-3", horizontal: "s-h-3", }, padding: { vertical: "s-pr-px s-pl-1.5 s-py-px", horizontal: "s-pb-px s-pt-1.5 s-px-px", }, thumb: cn( "s-bg-muted-foreground/20 dark:s-bg-muted-foreground-night/20", "hover:s-bg-muted-foreground/50 dark:hover:s-bg-muted-foreground-night/50" ), }, } as const; type ScrollBarSize = keyof typeof scrollBarSizes; interface ScrollBarProps extends React.ComponentPropsWithoutRef< typeof ScrollAreaPrimitive.ScrollAreaScrollbar > { size?: ScrollBarSize; } const ScrollBar = React.forwardRef< React.ElementRef, ScrollBarProps >( ( { className, orientation = "vertical", size = "compact", ...props }, ref ) => { const sizeConfig = scrollBarSizes[size]; return ( ); } ); ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName; export { ScrollArea, ScrollBar }; export type { ScrollAreaProps, ScrollBarSize };