Provides a scroll-state tracking hook and edge-fade overlay component for adding "scroll shadow" indicators to scrollable containers. ## Key Components ### `useScrollFade()` Hook that observes a scrollable element and reports whether content overflows at the top or bottom edge. Uses `ResizeObserver` to detect container size changes and `MutationObserver` to detect content growth (e.g., appended list items that change `scrollHeight` without resizing the container). **Returns:** | Property | Type | Description | |---|---|---| | `scrollRef` | `RefObject` | Attach to the scrollable element | | `fadeTop` | `boolean` | `true` when scrolled away from the top | | `fadeBottom` | `boolean` | `true` when content continues below the visible area | | `update` | `() => void` | Manual re-measure; wire to `onScroll` | ### `ScrollFadeOverlay` Absolutely-positioned overlay that renders a gradient fade at a specified edge. Must be placed inside a `relative` wrapper alongside the scrollable element. **Props:** | Prop | Type | Default | Description | |---|---|---|---| | `edge` | `'top' \| 'bottom'` | — | Which edge to render the fade on | | `visible` | `boolean` | — | Controls opacity via CSS transition | | `color` | `string` | `var(--color-bg)` | Surface color the gradient fades into | | `className` | `string` | — | Additional Tailwind classes | ## Usage Example ```typescript import { useScrollFade, ScrollFadeOverlay } from './scroll-fade' function ChatList({ messages }: { messages: string[] }) { const { scrollRef, fadeTop, fadeBottom, update } = useScrollFade() return (
{messages.map((msg, i) => (
{msg}
))}
) } ``` > The `color` prop should match the background surface behind the list — override it when the list sits on a card or modal rather than the page background.