Skip to content

ScrollFadeContainer API

All-in-one wrapper component that combines scroll detection with fade overlays. Simply wrap your scrollable content and it handles the rest.

Import

tsx
import { ScrollFadeContainer, type ScrollFadeContainerProps } from '@/shared/ui/components/scroll/ScrollFadeContainer'

Props

ScrollFadeContainerProps

PropTypeDefaultDescription
childrenReactNodeRequiredChild content (should include scrollable element)
fades'top' | 'bottom' | 'both''both'Which fades to show
fadeSize'sm' | 'md' | 'lg''md'Size of fade gradients
classNamestring-Additional CSS classes for container
scrollOptionsUseScrollFadeOptions-Options for scroll detection hook
fadeZIndexnumber10Z-index for fade overlays
fadeGradientGradientConfig-Custom gradient configuration
fadeClassNamestring-Additional CSS classes for fade elements

UseScrollFadeOptions

ts
interface UseScrollFadeOptions {
  /** Threshold in pixels before showing fade (default: 10) */
  threshold?: number
  /** Debounce delay in ms (default: 50) */
  debounce?: number
  /** Enable debug logging */
  debug?: boolean
}

GradientConfig

ts
interface GradientConfig {
  /** Starting color (e.g., 'rgb(255 255 255)', 'hsl(var(--card))') */
  from: string
  /** Middle color (optional, defaults to from with 80% opacity) */
  via?: string
}

Features

  • Automatic detection: Uses useScrollFade hook internally
  • Ref management: Handles container ref automatically
  • Flexible fades: Show top, bottom, or both
  • Pass-through props: All fade customization options available
  • Works with: SimpleBar, ScrollArea, native overflow

Examples

Basic Usage

tsx
import { ScrollFadeContainer } from '@/shared/ui/components/scroll/ScrollFadeContainer'
import SimpleBar from 'simplebar-react'

<ScrollFadeContainer>
  <SimpleBar className="h-[400px]">
    <div className="space-y-2 p-4">
      {items.map((item) => (
        <div key={item.id}>{item.name}</div>
      ))}
    </div>
  </SimpleBar>
</ScrollFadeContainer>

Custom Fade Size

tsx
<ScrollFadeContainer fadeSize="sm">
  <div className="h-[300px] overflow-y-auto">
    {content}
  </div>
</ScrollFadeContainer>

Top or Bottom Only

tsx
// Only show top fade
<ScrollFadeContainer fades="top">
  {content}
</ScrollFadeContainer>

// Only show bottom fade
<ScrollFadeContainer fades="bottom">
  {content}
</ScrollFadeContainer>

Custom Gradient

Match the fade to your background color:

tsx
<ScrollFadeContainer
  fadeGradient={{
    from: 'hsl(var(--card))',
    via: 'hsl(var(--card) / 0.8)',
  }}
>
  <div className="bg-card rounded-lg">
    {content}
  </div>
</ScrollFadeContainer>

Custom Scroll Options

tsx
<ScrollFadeContainer
  scrollOptions={{
    threshold: 20,  // Show fade when 20px from edge
    debounce: 150,  // Debounce scroll events by 150ms
    debug: true,    // Enable console logging
  }}
>
  {content}
</ScrollFadeContainer>

Complete Example

tsx
import { ScrollFadeContainer } from '@/shared/ui/components/scroll/ScrollFadeContainer'
import { Card, CardHeader, CardTitle, CardContent } from '@/shadcn/components/ui/card'
import SimpleBar from 'simplebar-react'

function ActivityFeed({ activities }) {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Recent Activity</CardTitle>
      </CardHeader>
      <CardContent>
        <ScrollFadeContainer
          fadeSize="md"
          fadeGradient={{
            from: 'hsl(var(--card))',
            via: 'hsl(var(--card) / 0.8)',
          }}
          scrollOptions={{
            threshold: 15,
            debounce: 100,
          }}
        >
          <SimpleBar className="h-[400px]">
            <div className="space-y-3 pr-4">
              {activities.map((activity) => (
                <div
                  key={activity.id}
                  className="p-3 bg-muted rounded-md"
                >
                  <p className="text-sm font-medium">
                    {activity.user}
                  </p>
                  <p className="text-sm text-muted-foreground">
                    {activity.message}
                  </p>
                  <p className="text-xs text-muted-foreground mt-1">
                    {activity.timestamp}
                  </p>
                </div>
              ))}
            </div>
          </SimpleBar>
        </ScrollFadeContainer>
      </CardContent>
    </Card>
  )
}

How It Works

  1. Creates a container with position: relative
  2. Attaches a ref to detect scroll events
  3. Uses useScrollFade hook to monitor scroll position
  4. Renders two ScrollFade components (top and bottom)
  5. Automatically shows/hides fades based on scroll position

Type Definition

ts
interface ScrollFadeContainerProps {
  children: ReactNode
  fades?: 'top' | 'bottom' | 'both'
  fadeSize?: 'sm' | 'md' | 'lg'
  className?: string
  scrollOptions?: UseScrollFadeOptions
  fadeZIndex?: number
  fadeGradient?: {
    from: string
    via?: string
  }
  fadeClassName?: string
}