|
| 1 | +<!-- |
| 2 | + This component acts as a parent container for HeaderNav and MobileNav, |
| 3 | + managing the shared state and interactions for nested mobile navigation. |
| 4 | +--> |
| 5 | +<script lang="ts"> |
| 6 | + // Removed import for $effect and $state as they are globals in Svelte 5 |
| 7 | + import { page } from "$app/stores"; |
| 8 | + import { goto } from "$app/navigation"; |
| 9 | +
|
| 10 | + import HeaderNav from "./HeaderNav.svelte"; |
| 11 | + import MobileNav from "./MobileNav.svelte"; |
| 12 | + import type { NavigationItem } from "./HeaderNav.svelte"; |
| 13 | + import type { NavSection } from "./MobileNav.svelte"; |
| 14 | +
|
| 15 | + // --- Props --- |
| 16 | + let { |
| 17 | + serviceName = "Service Name", |
| 18 | + homeHref = "/", |
| 19 | + // Used for the top desktop navigation and determining the current section |
| 20 | + navigationItems = [], |
| 21 | + // Used for the detailed structure within the mobile flyout menu |
| 22 | + mobileNavSections = [], |
| 23 | + } = $props<{ |
| 24 | + serviceName?: string; |
| 25 | + homeHref?: string; |
| 26 | + navigationItems: NavigationItem[]; |
| 27 | + mobileNavSections: NavSection[]; |
| 28 | + }>(); |
| 29 | +
|
| 30 | + // --- State --- |
| 31 | + let isMobileNavOpen = $state(false); // State for mobile menu visibility - reinstated $state |
| 32 | + let currentSection = $state(""); // Tracks the active top-level section - reinstated $state |
| 33 | +
|
| 34 | + // --- Effects --- |
| 35 | + // Update current section based on route changes |
| 36 | + $effect(() => { |
| 37 | + const path = $page.url.pathname; |
| 38 | +
|
| 39 | + // Find the matching top-level navigation item based on the current path |
| 40 | + const activeItem = navigationItems.find((item) => |
| 41 | + path === "/" |
| 42 | + ? item.href === "/" |
| 43 | + : item.href !== "/" && path.startsWith(item.href), |
| 44 | + ); |
| 45 | +
|
| 46 | + currentSection = activeItem |
| 47 | + ? activeItem.text |
| 48 | + : path === "/" |
| 49 | + ? navigationItems[0]?.text || "" |
| 50 | + : ""; |
| 51 | + }); |
| 52 | +
|
| 53 | + // --- Handlers --- |
| 54 | + // Toggle the mobile nav open/closed state |
| 55 | + function handleToggleMobileNav() { |
| 56 | + isMobileNavOpen = !isMobileNavOpen; |
| 57 | + } |
| 58 | +
|
| 59 | + // Handle navigation request from mobile menu |
| 60 | + function handleMobileNavigation(href: string) { |
| 61 | + isMobileNavOpen = false; // Close the menu |
| 62 | + if (typeof window !== "undefined") { |
| 63 | + goto(href); // Navigate using SvelteKit's router |
| 64 | + } |
| 65 | + } |
| 66 | +</script> |
| 67 | + |
| 68 | +<!-- Render the HeaderNav --> |
| 69 | +<HeaderNav |
| 70 | + {serviceName} |
| 71 | + {homeHref} |
| 72 | + {navigationItems} |
| 73 | + {currentSection} |
| 74 | + mobileNavIsOpen={isMobileNavOpen} |
| 75 | + onToggle={handleToggleMobileNav} |
| 76 | +/> |
| 77 | + |
| 78 | +<!-- Render the MobileNav --> |
| 79 | +<MobileNav |
| 80 | + isOpen={isMobileNavOpen} |
| 81 | + sections={mobileNavSections} |
| 82 | + {currentSection} |
| 83 | + onNavigate={handleMobileNavigation} |
| 84 | +/> |
0 commit comments