From 272c097c31436449c01cf5c081673aa4064d53a5 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Thu, 22 Feb 2024 09:12:39 -0600 Subject: [PATCH] Extract theme color logic to custom hook --- src/components/Modal.tsx | 17 +++-------------- src/site/useMetaThemeColor.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 src/site/useMetaThemeColor.ts diff --git a/src/components/Modal.tsx b/src/components/Modal.tsx index 6c35b83b..ac0f7526 100644 --- a/src/components/Modal.tsx +++ b/src/components/Modal.tsx @@ -1,6 +1,6 @@ 'use client'; -import { ReactNode, useEffect, useLayoutEffect, useRef, useState } from 'react'; +import { ReactNode, useEffect, useRef, useState } from 'react'; import { motion } from 'framer-motion'; import { clsx } from 'clsx/lite'; import useClickInsideOutside from '@/utility/useClickInsideOutside'; @@ -8,7 +8,7 @@ import { useRouter } from 'next/navigation'; import AnimateItems from './AnimateItems'; import { PATH_ROOT } from '@/site/paths'; import usePrefersReducedMotion from '@/utility/usePrefersReducedMotion'; -import { useTheme } from 'next-themes'; +import useMetaThemeColor from '@/site/useMetaThemeColor'; export default function Modal({ onClosePath, @@ -39,18 +39,7 @@ export default function Modal({ } }, []); - const { resolvedTheme } = useTheme(); - useLayoutEffect(() => { - if (resolvedTheme === 'light') { - // Temporarily create meta tag for overlays in light mode, - // which prevents stale headers on theme changes - const meta = document.createElement('meta'); - meta.name = 'theme-color'; - meta.content = '#333'; - document.getElementsByTagName('head')[0]?.appendChild(meta); - return () => meta.remove(); - } - }, [resolvedTheme]); + useMetaThemeColor({ colorLight: '#333' }); useClickInsideOutside({ htmlElements, diff --git a/src/site/useMetaThemeColor.ts b/src/site/useMetaThemeColor.ts new file mode 100644 index 00000000..c2e4b34a --- /dev/null +++ b/src/site/useMetaThemeColor.ts @@ -0,0 +1,28 @@ +import { useTheme } from 'next-themes'; +import { useEffect } from 'react'; + +export default function useMetaThemeColor({ + colorLight, + colorDark, +}: { + colorLight?: string + colorDark?: string +}) { + const { resolvedTheme } = useTheme(); + + const preferredThemeColor = resolvedTheme === 'light' + ? colorLight + : colorDark; + + useEffect(() => { + if (preferredThemeColor) { + // Temporarily create meta tag for overlays, + // which prevents stale headers on theme changes + const meta = document.createElement('meta'); + meta.name = 'theme-color'; + meta.content = preferredThemeColor; + document.getElementsByTagName('head')[0]?.appendChild(meta); + return () => meta.remove(); + } + }, [preferredThemeColor]); +}