bigbullui logobigbullui
Componentmedia

Reveal

IntersectionObserver: children animate in when entering viewport with fade-up/scale variants, delay prop, once re-trigger option.

Preview

Live Preview
Content reveals when scrolling into view

Installation

Tokens guide →

Add to your project via CLI (zero dependencies, code you own):

npx bigbullui add reveal

Or install the full npm package:

npm install bigbullui

Usage

import { Reveal } from "@/components/ui/reveal"

<Reveal delay={0}>Content animates when scrolling into view</Reveal>

Source code

reveal.tsx

Zero dependencies (only React + utils). Copy and paste directly into your project:

"use client";

import * as React from "react";
import { cn } from "./lib/utils";

export type RevealProps = {
  children?: React.ReactNode;
  /** kademeli giriş gecikmesi çarpanı (ms cinsinden index*40) */
  delay?: number;
  /** yalnızca ilk görünümde tetiklensin */
  once?: boolean;
};

export function Reveal({ children, delay = 0, once = true }: RevealProps) {
  const containerRef = React.useRef<HTMLDivElement>(null);
  const [visible, setVisible] = React.useState(false);

  React.useEffect(() => {
    const node = containerRef.current;
    if (!node) return;

    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setVisible(true);
          if (once) observer.disconnect();
        } else if (!once) {
          setVisible(false);
        }
      },
      { rootMargin: "0px", threshold: 0.1 },
    );

    observer.observe(node);
    return () => observer.disconnect();
  }, [once]);

  return (
    <div ref={containerRef} className="relative">
      <div
        className={cn(
          "animate-[fade-in-up_0.4s_ease-out_both]",
          "motion-reduce:animate-none",
          !visible && "opacity-0",
        )}
        style={{ animationDelay: `${delay * 40}ms` }}
      >
        {children}
      </div>
    </div>
  );
}

Props

PropTypeDescription
delaynumberAnimation delay in hundreds of milliseconds (0, 1, 2...).
oncebooleanWhether animation re-triggers on re-entry.