"use client"; import { ScrollArea as ScrollAreaPrimitive } from "radix-ui"; import * as React from "react"; import { useRef, useState, useEffect } from "react"; import { cn } from "@turbostarter/ui"; function ScrollArea({ className, children, ...props }: React.ComponentProps) { return ( {children} ); } interface ScrollAreaWithShadowsProps { children: React.ReactNode; className?: string; maxHeight?: string; } /** * Scroll container with fade indicators. * Uses CSS mask-image to fade content at edges when scrollable. * No overlay elements = no overflow issues with rounded corners. */ function ScrollAreaWithShadows({ children, className, maxHeight = "60vh", }: ScrollAreaWithShadowsProps) { const scrollRef = useRef(null); const [scrollState, setScrollState] = useState({ top: false, bottom: false }); useEffect(() => { const el = scrollRef.current; if (!el) return; const updateScrollState = () => { const { scrollTop, scrollHeight, clientHeight } = el; setScrollState({ top: scrollTop > 10, bottom: scrollTop + clientHeight < scrollHeight - 10, }); }; updateScrollState(); el.addEventListener("scroll", updateScrollState); const resizeObserver = new ResizeObserver(updateScrollState); resizeObserver.observe(el); return () => { el.removeEventListener("scroll", updateScrollState); resizeObserver.disconnect(); }; }, []); // Build mask based on scroll state const getMaskStyle = (): React.CSSProperties => { const fadeSize = "24px"; if (scrollState.top && scrollState.bottom) { // Fade both edges return { maskImage: `linear-gradient(to bottom, transparent, black ${fadeSize}, black calc(100% - ${fadeSize}), transparent)`, WebkitMaskImage: `linear-gradient(to bottom, transparent, black ${fadeSize}, black calc(100% - ${fadeSize}), transparent)`, }; } else if (scrollState.top) { // Fade top only return { maskImage: `linear-gradient(to bottom, transparent, black ${fadeSize})`, WebkitMaskImage: `linear-gradient(to bottom, transparent, black ${fadeSize})`, }; } else if (scrollState.bottom) { // Fade bottom only return { maskImage: `linear-gradient(to bottom, black calc(100% - ${fadeSize}), transparent)`, WebkitMaskImage: `linear-gradient(to bottom, black calc(100% - ${fadeSize}), transparent)`, }; } // No fade needed return {}; }; return (
{children}
); } function ScrollBar({ className, orientation = "vertical", ...props }: React.ComponentProps) { return ( ); } export { ScrollArea, ScrollAreaWithShadows, ScrollBar };