From 47c293922c472c9bbfae7d6d3e12632f19e3ffd6 Mon Sep 17 00:00:00 2001 From: futurGH Date: Wed, 17 Sep 2025 20:20:38 -0400 Subject: [PATCH] use IntersectionObserver for sticky component --- src/components/sticky.tsx | 65 +++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/src/components/sticky.tsx b/src/components/sticky.tsx index 068d9db..b1731d4 100644 --- a/src/components/sticky.tsx +++ b/src/components/sticky.tsx @@ -4,41 +4,40 @@ export const StickyOverlay = (props: { children?: JSX.Element }) => { const [filterStuck, setFilterStuck] = createSignal(false); return ( -
{ - onMount(() => { - let ticking = false; - const tick = () => { - const topPx = parseFloat(getComputedStyle(node).top); - const { top } = node.getBoundingClientRect(); - setFilterStuck(top <= topPx + 0.5); - ticking = false; - }; + <> +
{ + onMount(() => { + const observer = new IntersectionObserver( + ([entry]) => setFilterStuck(!entry.isIntersecting), + { + rootMargin: "-8px 0px 0px 0px", + threshold: 0, + }, + ); - const onScroll = () => { - if (!ticking) { - ticking = true; - requestAnimationFrame(tick); - } - }; + observer.observe(trigger); - window.addEventListener("scroll", onScroll, { passive: true }); - - tick(); - - onCleanup(() => { - window.removeEventListener("scroll", onScroll); + onCleanup(() => { + observer.unobserve(trigger); + observer.disconnect(); + }); }); - }); - }} - class="sticky top-2 z-10 flex flex-col items-center justify-center gap-2 rounded-lg p-3 transition-colors" - classList={{ - "bg-neutral-50 dark:bg-dark-300 border-[0.5px] border-neutral-300 dark:border-neutral-700 shadow-md": - filterStuck(), - "bg-transparent border-transparent shadow-none": !filterStuck(), - }} - > - {props.children} -
+ }} + class="pointer-events-none h-0" + aria-hidden="true" + /> + +
+ {props.children} +
+ ); }; -- 2.43.0