Live Docs

Effects & Media /

new

Reveal

Animate children into view as they scroll into the viewport, via IntersectionObserver (useInView).

import { Reveal } from "@naraya-ai/ui";

Examples

Staggered list

Scroll the preview — each card slides up + fades, staggered by delay. Scroll back up to replay (once={false}).

↓ scroll ↓

Item 1

Item 2

Item 3

Item 4

Item 5

{items.map((item, i) => (
  <Reveal key={i} animation="slide-up" delay={i * 80}>
    <Card>{item}</Card>
  </Reveal>
))}

Directions

Six entrance styles. Scroll within the box — they animate out and back in.

↓ scroll ↓

slide-up

slide-down

slide-left

slide-right

scale-in

blur-in

<Reveal animation="slide-left">…</Reveal>
<Reveal animation="scale-in">…</Reveal>
<Reveal animation="blur-in">…</Reveal>

Enter + exit combo

Enter from below, leave upward (pass-through). Set exit to compose any in/out pair.

↓ scroll ↓

In ↑ from below · out ↑ to top

In ↑ from below · out ↑ to top

In ↑ from below · out ↑ to top

In → from left · out ← to left

{/* enter from below, exit upward */}
<Reveal animation="slide-up" exit="slide-up" once={false}>…</Reveal>

{/* enter from left, exit back to the left */}
<Reveal animation="slide-right" exit="slide-left" once={false}>…</Reveal>

⚠️ Don't wrap glass

Reveal animates opacity + transform on its wrapper, which makes it a backdrop root and kills the frost of any .naraya-glass descendant. Reveal a glass-free element, or reveal the content inside the glass surface instead.

Props

PropTypeDefaultDescription
animation"fade-in" | "slide-up" | "slide-down" | "slide-left" | "slide-right" | "scale-in" | "blur-in""slide-up"Entrance style (motion into place).
exitRevealAnimation= animationExit style when scrolled away (needs once={false}).
delaynumber0Delay before the transition, in ms.
oncebooleantrueReveal once, or animate out + back in each pass.
thresholdnumber | number[]Forwarded to useInView.
rootMarginstring"0px 0px -10% 0px"Forwarded to useInView.
asElementType"div"Element to render.

useInView

The underlying hook is exported from @naraya-ai/hooks: const [ref, inView] = useInView(). SSR-safe; falls back to visible when IntersectionObserver is unavailable.

Accessibility

  • Content is rendered in the DOM regardless of visibility (good for SEO + screen readers).
  • Under prefers-reduced-motion the entrance is skipped and content shows immediately.