"use client"; import { Dialog, DialogPanel, Transition, TransitionChild, } from "@headlessui/react"; import { motion } from "framer-motion"; import { usePathname, useSearchParams } from "next/navigation"; import { type ComponentPropsWithoutRef, type MouseEvent, Suspense, createContext, useContext, useEffect, useRef, } from "react"; import { create } from "zustand"; import { Header } from "./Header"; import { Navigation } from "./Navigation"; function MenuIcon(props: ComponentPropsWithoutRef<"svg">) { return ( ); } function XIcon(props: ComponentPropsWithoutRef<"svg">) { return ( ); } const IsInsideMobileNavigationContext = createContext(false); function MobileNavigationDialog({ isOpen, close, }: { isOpen: boolean; close: () => void; }) { const pathname = usePathname(); const searchParams = useSearchParams(); const initialPathname = useRef(pathname).current; const initialSearchParams = useRef(searchParams).current; useEffect(() => { if ( pathname !== initialPathname || searchParams !== initialSearchParams ) { close(); } }, [pathname, searchParams, close, initialPathname, initialSearchParams]); function onClickDialog(event: MouseEvent) { if (!(event.target instanceof HTMLElement)) { return; } const link = event.target.closest("a"); if ( link && link.pathname + link.search + link.hash === window.location.pathname + window.location.search + window.location.hash ) { close(); } } return (
); } export function useIsInsideMobileNavigation() { return useContext(IsInsideMobileNavigationContext); } export const useMobileNavigationStore = create<{ isOpen: boolean; open: () => void; close: () => void; toggle: () => void; }>()((set) => ({ isOpen: false, open: () => set({ isOpen: true }), close: () => set({ isOpen: false }), toggle: () => set((state) => ({ isOpen: !state.isOpen })), })); export function MobileNavigation() { const isInsideMobileNavigation = useIsInsideMobileNavigation(); const { isOpen, toggle, close } = useMobileNavigationStore(); const ToggleIcon = isOpen ? XIcon : MenuIcon; return ( {!isInsideMobileNavigation && ( )} ); }