import { useEffect, useRef, useState, type ReactNode } from 'react' import { cn } from '@/lib/utils' interface RevealProps { children: ReactNode className?: string /** 进场延迟(毫秒),用于同屏元素错峰 */ delay?: number } /** 滚动进场:进入视口后淡入上移一次;prefers-reduced-motion 时直接显示 */ export function Reveal({ children, className, delay = 0 }: RevealProps) { const ref = useRef(null) const [visible, setVisible] = useState(false) useEffect(() => { const el = ref.current if (!el) return if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { setVisible(true) return } const io = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { setVisible(true) io.disconnect() } }, { threshold: 0.15, rootMargin: '0px 0px -40px 0px' }, ) io.observe(el) return () => io.disconnect() }, []) return (
{children}
) }