diff --git a/src/components/shared/Header.jsx b/src/components/shared/Header.jsx index b990437d..f48c5581 100644 --- a/src/components/shared/Header.jsx +++ b/src/components/shared/Header.jsx @@ -1,12 +1,12 @@ 'use client' -import { Fragment, useEffect, useRef } from 'react' +import { Fragment, useEffect, useRef, useState } from 'react' import Image from 'next/image' import Link from 'next/link' import { usePathname } from 'next/navigation' import { Popover, Transition } from '@headlessui/react' import clsx from 'clsx' -import { motion } from 'framer-motion' +import { AnimatePresence, motion, useReducedMotion } from 'framer-motion' import { Container } from '@/components/shared/Container' @@ -183,6 +183,29 @@ function DesktopNavigation(props) { } function ModeToggle() { + const [mounted, setMounted] = useState(false) + const [isDarkMode, setIsDarkMode] = useState(false) + const prefersReducedMotion = useReducedMotion() + const iconTransition = prefersReducedMotion + ? { duration: 0 } + : { duration: 0.5, ease: 'easeInOut' } + + useEffect(() => { + setMounted(true) + setIsDarkMode(document.documentElement.classList.contains('dark')) + + const observer = new MutationObserver(() => { + setIsDarkMode(document.documentElement.classList.contains('dark')) + }) + + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ['class'], + }) + + return () => observer.disconnect() + }, []) + function disableTransitionsTemporarily() { document.documentElement.classList.add('[&_*]:!transition-none') window.setTimeout(() => { @@ -204,15 +227,42 @@ function ModeToggle() { } } + if (!mounted) { + return ( +
+ ) + } + return ( ) } diff --git a/src/components/shared/Pattern.jsx b/src/components/shared/Pattern.jsx index 5be975d2..25c61246 100644 --- a/src/components/shared/Pattern.jsx +++ b/src/components/shared/Pattern.jsx @@ -17,12 +17,12 @@ export function Pattern({ let height = pattern.length * size + (pattern.length - 1) * gapY return ( -