40 lines
1.0 KiB
TypeScript
40 lines
1.0 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
|
|
/**
|
|
* Observes all `.reveal-item` descendants of the returned ref and adds
|
|
* `.is-visible` when they enter the viewport, triggering the CSS transition
|
|
* defined in globals.scss.
|
|
*
|
|
* The observer starts immediately so that elements already in the viewport
|
|
* become visible right away — including after language-change remounts.
|
|
*/
|
|
export function useScrollReveal() {
|
|
const ref = useRef<HTMLElement>(null);
|
|
|
|
useEffect(() => {
|
|
const container = ref.current;
|
|
if (!container) return;
|
|
|
|
const observer = new IntersectionObserver(
|
|
(entries) => {
|
|
entries.forEach((entry) => {
|
|
if (entry.isIntersecting) {
|
|
entry.target.classList.add('is-visible');
|
|
observer.unobserve(entry.target);
|
|
}
|
|
});
|
|
},
|
|
{ threshold: 0.12 }
|
|
);
|
|
|
|
const items = container.querySelectorAll('.reveal-item');
|
|
items.forEach((el) => observer.observe(el));
|
|
|
|
return () => {
|
|
observer.disconnect();
|
|
};
|
|
}, []);
|
|
|
|
return ref;
|
|
}
|