Build the RTL Next.js experience with live catalog, journal, customer interactions, and SEO-ready canonical routes. Co-authored-by: Cursor <cursoragent@cursor.com>
79 lines
1.9 KiB
TypeScript
79 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect } from "react";
|
|
import { usePathname } from "next/navigation";
|
|
|
|
const revealSelectors = [
|
|
".section-heading",
|
|
".product-carousel",
|
|
".resume-grid > *",
|
|
".features-intro-grid > *",
|
|
".feature-card",
|
|
".technology-grid > *",
|
|
".video-content > *",
|
|
".article-card",
|
|
".about-grid > *",
|
|
".about-stats-grid > *",
|
|
".why-grid > *",
|
|
".contact-cards article",
|
|
".contact-main > *",
|
|
".map-section",
|
|
".catalog-product-card",
|
|
".category-intro",
|
|
".blog-list-card",
|
|
".product-detail-grid > *",
|
|
".entity-tabs",
|
|
".blog-content-wrap",
|
|
".comments-list article",
|
|
".footer-grid > *",
|
|
];
|
|
|
|
export function MotionObserver() {
|
|
const pathname = usePathname();
|
|
|
|
useEffect(() => {
|
|
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
|
|
|
|
const root = document.documentElement;
|
|
const elements: HTMLElement[] = [];
|
|
|
|
revealSelectors.forEach((selector) => {
|
|
document.querySelectorAll<HTMLElement>(selector).forEach((element, index) => {
|
|
element.dataset.reveal = "";
|
|
element.style.setProperty("--reveal-delay", `${Math.min(index, 5) * 70}ms`);
|
|
elements.push(element);
|
|
});
|
|
});
|
|
|
|
root.classList.add("motion-ready");
|
|
|
|
const observer = new IntersectionObserver(
|
|
(entries) => {
|
|
entries.forEach((entry) => {
|
|
if (!entry.isIntersecting) return;
|
|
entry.target.classList.add("is-visible");
|
|
observer.unobserve(entry.target);
|
|
});
|
|
},
|
|
{
|
|
threshold: 0.12,
|
|
rootMargin: "0px 0px -55px",
|
|
},
|
|
);
|
|
|
|
elements.forEach((element) => observer.observe(element));
|
|
|
|
return () => {
|
|
observer.disconnect();
|
|
root.classList.remove("motion-ready");
|
|
elements.forEach((element) => {
|
|
delete element.dataset.reveal;
|
|
element.classList.remove("is-visible");
|
|
element.style.removeProperty("--reveal-delay");
|
|
});
|
|
};
|
|
}, [pathname]);
|
|
|
|
return null;
|
|
}
|