38 lines
962 B
JavaScript
38 lines
962 B
JavaScript
import { useEffect, useRef, useState } from 'react';
|
|||
|
|
|
||
|
|
// Fades children in when they scroll into view.
|
||
|
|
export default function Reveal({ as: Tag = 'div', delay = 0, className = '', children, ...rest }) {
|
||
|
|
const ref = useRef(null);
|
||
|
|
const [visible, setVisible] = useState(false);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
const node = ref.current;
|
||
|
|
if (!node || typeof IntersectionObserver === 'undefined') {
|
||
|
|
setVisible(true);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
const observer = new IntersectionObserver(
|
||
|
|
([entry]) => {
|
||
|
|
if (entry.isIntersecting) {
|
||
|
|
setVisible(true);
|
||
|
|
observer.disconnect();
|
||
|
|
}
|
||
|
|
},
|
||
|
|
{ rootMargin: '0px 0px -10% 0px' }
|
||
|
|
);
|
||
|
|
observer.observe(node);
|
||
|
|
return () => observer.disconnect();
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<Tag
|
||
|
|
ref={ref}
|
||
|
|
className={`reveal ${visible ? 'is-visible' : ''} ${className}`}
|
||
|
|
style={{ transitionDelay: `${delay}ms` }}
|
||
|
|
{...rest}
|
||
|
|
>
|
||
|
|
{children}
|
||
|
|
</Tag>
|
||
|
|
);
|
||
|
|
}
|