Skip to content

Commit

Permalink
Moved intersectionobserver to useeffect.
Browse files Browse the repository at this point in the history
  • Loading branch information
evankirkiles committed Jun 6, 2023
1 parent c8680c4 commit 0936cc2
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 48 deletions.
88 changes: 47 additions & 41 deletions src/MetaThemeContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
* created on Sun Jun 04 2023
* 2023 the nobot space
*/
import React from 'react';
import React, { useEffect, useState } from 'react';
import { PropsWithChildren, createContext, useRef } from 'react';

interface IMetaThemeContext {
observerTop: IntersectionObserver;
observerBottom: IntersectionObserver;
observerTop: IntersectionObserver | null;
observerBottom: IntersectionObserver | null;
}

export const MetaThemeContext = createContext<IMetaThemeContext>({
observerTop: new IntersectionObserver(() => void 0),
observerBottom: new IntersectionObserver(() => void 0),
observerTop: null,
observerBottom: null,
});

/**
Expand All @@ -30,45 +30,51 @@ export const MetaThemeContext = createContext<IMetaThemeContext>({
export default function MetaThemeProvider({ children }: PropsWithChildren) {
const metaTag = useRef<HTMLMetaElement>(document.querySelector('meta[name="theme-color"'));
const currThemeColor = useRef<string | null>(metaTag.current?.getAttribute('content') ?? null);
const [observerTop, setTop] = useState<IntersectionObserver | null>(null);
const [observerBottom, setBot] = useState<IntersectionObserver | null>(null);

useEffect(() => {
setTop(
new IntersectionObserver(
(es) => {
if (!metaTag.current) return;
const selectedEntry = es.filter((e) => e.isIntersecting);
const target = selectedEntry[0]?.target;
if (!target) return;
const color = target.getAttribute('data-metathemeswap-color');
if (!color) return;
currThemeColor.current = color;
metaTag.current.setAttribute('content', currThemeColor.current);
},
{
rootMargin: '-0.05% 0px -99.9% 0px',
},
),
);
setBot(
new IntersectionObserver(
(es) => {
if (!metaTag.current) return;
const selectedEntry = es.filter((e) => e.isIntersecting);
const target = selectedEntry[0]?.target;
if (!target) return;
const color = target.getAttribute('data-metathemeswap-color');
if (!color) return;
currThemeColor.current = color;
metaTag.current.setAttribute('content', currThemeColor.current);
},
{
rootMargin: '-0.05% 0px -99.9% 0px',
},
),
);
}, []);

return (
<MetaThemeContext.Provider
value={{
// Top of screen intersection observer (controls theme-color)
observerTop: new IntersectionObserver(
(es) => {
if (!metaTag.current) return;
const selectedEntry = es.filter((e) => e.isIntersecting);
const target = selectedEntry[0]?.target;
if (!target) return;
const color = target.getAttribute('data-metathemeswap-color');
if (!color) return;
currThemeColor.current = color;
metaTag.current.setAttribute('content', currThemeColor.current);
},
{
rootMargin: '-0.05% 0px -99.9% 0px',
},
),
// Bottom of screen intersection observer (controls background-color)
observerBottom: new IntersectionObserver(
(es) => {
if (!metaTag.current) return;
const selectedEntry = es.filter((e) => e.isIntersecting);
const target = selectedEntry[0]?.target;
if (!target) return;
const color = target.getAttribute('data-metathemeswap-color');
if (!color) return;
document.body.style.backgroundColor = color;
metaTag.current.setAttribute('content', currThemeColor.current + 'fe');
const meta = metaTag.current;
requestAnimationFrame(() => {
meta.setAttribute('content', currThemeColor.current || '');
});
},
{
rootMargin: '-99.9% 0px -0.05% 0px',
},
),
observerTop,
observerBottom,
}}
>
{children}
Expand Down
20 changes: 13 additions & 7 deletions src/useMetaTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@ export default function useMetaTheme(ref: RefObject<Element>, color: string) {
const node = ref.current;
if (!node) return;
node.setAttribute('data-metathemeswap-color', color);
observerTop.observe(node);
observerBottom.observe(node);
return () => {
observerTop.unobserve(node);
observerBottom.unobserve(node);
};
}, [observerTop, observerBottom, color, ref]);
}, [color, ref]);

useEffect(() => {
const node = ref.current;
if (!node || !observerTop) return;
observerTop?.observe(node);
}, [observerTop, ref]);

useEffect(() => {
const node = ref.current;
if (!node || !observerBottom) return;
observerBottom?.observe(node);
}, [observerBottom, ref]);
}

0 comments on commit 0936cc2

Please sign in to comment.