diff --git a/docs/src/components/SiteNav.tsx b/docs/src/components/SiteNav.tsx index 8959250e0b..3f8080a0f1 100644 --- a/docs/src/components/SiteNav.tsx +++ b/docs/src/components/SiteNav.tsx @@ -1,16 +1,14 @@ /** * SiteNav.tsx * - * Unified site navigation with parent/sub-menu state switching. + * Unified site navigation. Every top-level section links directly to its index + * page; which menu renders (parent vs. a submenu) is derived from the current + * URL, not from in-menu click state. * - * Navigation behavior: - * - Components, Get started, Foundations: has submenu (many pages) - * - Tokens: Direct link, stays on parent menu, highlights "Tokens" - * - Examples: Direct link, stays on parent menu, highlights "Examples" - * - * Menu level is managed via React state: - * - Parent view: Shows all sections - * - Sub-menu view: Shows section-specific navigation (components, get-started, foundations) + * - Components, Get started, Foundations: land on their index page, which shows + * the matching submenu. + * - Tokens, Examples: single pages, stay on the parent menu and highlight. + * - A submenu's "All" item navigates home and opens global search. */ import { useState, useEffect, useCallback } from "react"; @@ -176,25 +174,6 @@ export function SiteNav({ }); }, [menuLevel]); - const handleSelectSection = useCallback( - (section: MenuSection) => { - // Submenu sections switch the menu into their dedicated view. - if (SUBMENU_SECTIONS.includes(section)) { - setMenuLevel(section); - // Auto-expand when entering submenu while collapsed (icons aren't descriptive enough) - if (!isOpen) { - setIsOpen(true); - } - } - // Other sections navigate directly via url prop, no state change needed - }, - [isOpen], - ); - - const handleBack = useCallback(() => { - setMenuLevel("parent"); - }, []); - const handleExpandMenu = useCallback(() => { setIsOpen(true); }, []); @@ -209,7 +188,6 @@ export function SiteNav({ @@ -246,7 +222,6 @@ export function SiteNav({ ); diff --git a/docs/src/components/nav/AllHomeItem.tsx b/docs/src/components/nav/AllHomeItem.tsx new file mode 100644 index 0000000000..29e8ebb85d --- /dev/null +++ b/docs/src/components/nav/AllHomeItem.tsx @@ -0,0 +1,31 @@ +/** + * AllHomeItem.tsx + * + * The "All" item rendered at the top of every submenu (Components, Get started, + * Foundations). It navigates back to the home page, where the hero search field + * is front and center, rather than just collapsing the menu. + * + * Wrapped-onClick + sentinel `url` mirrors the existing pattern in the submenus + * (e.g. handleAllComponentsClick): the menu's onNavigate ignores `/__` paths, so + * the onClick owns navigation. + */ + +import { type MouseEvent } from "react"; +import { GoabWorkSideMenuItem } from "@abgov/react-components"; +import { withBase } from "@/lib/base-url"; + +export function AllHomeItem() { + const handleClick = (e: MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + window.location.href = withBase("/"); + }; + + return ( +
+ +
+ ); +} + +export default AllHomeItem; diff --git a/docs/src/components/nav/ComponentsSubMenu.tsx b/docs/src/components/nav/ComponentsSubMenu.tsx index ef9eb535e7..c37bd59e84 100644 --- a/docs/src/components/nav/ComponentsSubMenu.tsx +++ b/docs/src/components/nav/ComponentsSubMenu.tsx @@ -12,13 +12,13 @@ import { GoabWorkSideMenuGroup, } from "@abgov/react-components"; import { MenuSecondaryContent } from "./MenuSecondaryContent"; +import { AllHomeItem } from "./AllHomeItem"; import type { NavCategory } from "../../lib/nav-categories"; import { withBase } from "@/lib/base-url"; interface ComponentsSubMenuProps { isOpen: boolean; onToggle: () => void; - onBack: () => void; onExpandMenu?: () => void; currentSlug?: string; categories?: NavCategory[]; @@ -27,7 +27,6 @@ interface ComponentsSubMenuProps { export function ComponentsSubMenu({ isOpen, onToggle, - onBack, onExpandMenu, currentSlug, categories = [], @@ -35,13 +34,6 @@ export function ComponentsSubMenu({ // We're on the All Components page if there's no currentSlug const isAllComponentsPage = !currentSlug; - // Handle back button click - wrap prevents navigation, triggers state change - const handleBackClick = (e: MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - onBack(); - }; - // Handle All Components click on detail pages - navigate without URL auto-matching const handleAllComponentsClick = (e: MouseEvent) => { e.preventDefault(); @@ -49,13 +41,11 @@ export function ComponentsSubMenu({ window.location.href = withBase("/components"); }; - // Primary content: Back button + All Components link + component categories + // Primary content: All (home + global search) + All Components link + component categories const primaryContent = ( <> - {/* Back to parent menu - wrapped div captures click since component doesn't expose onClick */} -
- -
+ {/* "All" navigates home and opens global search */} + {/* All Components page link - On All Components page: use url so auto-matching highlights it diff --git a/docs/src/components/nav/FoundationsSubMenu.tsx b/docs/src/components/nav/FoundationsSubMenu.tsx index 3b881630ce..79b9ad3159 100644 --- a/docs/src/components/nav/FoundationsSubMenu.tsx +++ b/docs/src/components/nav/FoundationsSubMenu.tsx @@ -5,13 +5,13 @@ * Uses GoabWorkSideMenuGroup for expandable Style guide sections. */ -import { type MouseEvent } from "react"; import { GoabWorkSideMenu, GoabWorkSideMenuItem, GoabWorkSideMenuGroup, } from "@abgov/react-components"; import { MenuSecondaryContent } from "./MenuSecondaryContent"; +import { AllHomeItem } from "./AllHomeItem"; import { withBase } from "@/lib/base-url"; // Top-level pages (not in a group) @@ -77,7 +77,6 @@ const ALL_URLS = [ interface FoundationsSubMenuProps { isOpen: boolean; onToggle: () => void; - onBack: () => void; onExpandMenu?: () => void; currentUrl?: string; } @@ -85,22 +84,13 @@ interface FoundationsSubMenuProps { export function FoundationsSubMenu({ isOpen, onToggle, - onBack, onExpandMenu, currentUrl, }: FoundationsSubMenuProps) { - const handleBackClick = (e: MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - onBack(); - }; - const primaryContent = ( <> - {/* Back to parent menu */} -
- -
+ {/* "All" navigates home and opens global search */} + {/* Top-level pages */} {TOP_PAGES.map((page) => ( diff --git a/docs/src/components/nav/GetStartedSubMenu.tsx b/docs/src/components/nav/GetStartedSubMenu.tsx index 8faea4c8bb..9a3e6a1f8b 100644 --- a/docs/src/components/nav/GetStartedSubMenu.tsx +++ b/docs/src/components/nav/GetStartedSubMenu.tsx @@ -7,20 +7,20 @@ * `getGetStartedNav()` in lib/get-started-nav.ts. */ -import { Fragment, type MouseEvent } from "react"; +import { Fragment } from "react"; import { GoabWorkSideMenu, GoabWorkSideMenuItem, GoabWorkSideMenuGroup, } from "@abgov/react-components"; import { MenuSecondaryContent } from "./MenuSecondaryContent"; +import { AllHomeItem } from "./AllHomeItem"; import { withBase } from "@/lib/base-url"; import type { GetStartedNav, GetStartedNavSection } from "@/lib/get-started-nav"; interface GetStartedSubMenuProps { isOpen: boolean; onToggle: () => void; - onBack: () => void; onExpandMenu?: () => void; currentUrl?: string; items: GetStartedNav; @@ -29,17 +29,10 @@ interface GetStartedSubMenuProps { export function GetStartedSubMenu({ isOpen, onToggle, - onBack, onExpandMenu, currentUrl, items, }: GetStartedSubMenuProps) { - const handleBackClick = (e: MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - onBack(); - }; - const renderSection = (section: GetStartedNavSection) => { if (section.type === "flat") { return ( @@ -72,10 +65,8 @@ export function GetStartedSubMenu({ const primaryContent = ( <> - {/* Back to parent menu */} -
- -
+ {/* "All" navigates home and opens global search */} + {items.sections.map(renderSection)} diff --git a/docs/src/components/nav/ParentMenu.tsx b/docs/src/components/nav/ParentMenu.tsx index 2e61b09358..93aabe78cc 100644 --- a/docs/src/components/nav/ParentMenu.tsx +++ b/docs/src/components/nav/ParentMenu.tsx @@ -1,12 +1,12 @@ /** * ParentMenu.tsx * - * Parent-level navigation showing all main sections. - * - Components, Get started, Foundations: opens submenu (has many pages) - * - Tokens, Examples: direct navigation (single page each) + * Parent-level navigation showing all main sections. Every section links + * directly to its index page. The destination page's SiteNav then shows the + * relevant submenu (Components, Get started, Foundations) based on the URL; + * Tokens and Examples are single pages. */ -import React from "react"; import { GoabWorkSideMenu, GoabWorkSideMenuItem } from "@abgov/react-components"; import type { GoabIconType } from "@abgov/ui-components-common"; import { MenuSecondaryContent } from "./MenuSecondaryContent"; @@ -23,7 +23,6 @@ export type MenuSection = interface ParentMenuProps { isOpen: boolean; onToggle: () => void; - onSelectSection: (section: MenuSection) => void; /** Currently active section (for highlighting) */ currentSection?: MenuSection; } @@ -34,15 +33,6 @@ interface TopLevelSection { icon: GoabIconType; } -// Sections that navigate directly to a page (no submenu) -const DIRECT_NAV_SECTIONS: Partial> = { - tokens: withBase("/tokens"), - examples: withBase("/examples"), -}; - -// Sections that open a submenu -const SUBMENU_SECTIONS = ["components", "get-started", "foundations"] as const; - // Main navigation sections const SECTIONS: TopLevelSection[] = [ { id: "get-started", label: "Get started", icon: "document-text" }, @@ -55,69 +45,20 @@ const SECTIONS: TopLevelSection[] = [ export function ParentMenu({ isOpen, onToggle, - onSelectSection, currentSection, }: ParentMenuProps) { - // Handle click on submenu item - prevent navigation, open submenu instead - const handleSubmenuClick = (sectionId: MenuSection) => (e: React.MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - onSelectSection(sectionId); - }; - - // Primary content: Main navigation sections + // Every section links directly to its index page. const primaryContent = ( <> - {SECTIONS.map((section) => { - const directUrl = DIRECT_NAV_SECTIONS[section.id]; - const hasSubmenu = SUBMENU_SECTIONS.includes( - section.id as (typeof SUBMENU_SECTIONS)[number], - ); - const isActive = currentSection === section.id; - - if (directUrl) { - // Direct navigation - use url prop - return ( - - ); - } - - if (hasSubmenu) { - // Opens submenu - use section URL when active for matching, - // otherwise use non-matching URL to prevent false positives on homepage - const submenuUrl = isActive ? withBase(`/${section.id}`) : "/__never_match__"; - return ( -
- -
- ); - } else { - // Placeholder sections - disabled for now - return ( - onSelectSection(section.id)} - /> - ); - } - })} + {SECTIONS.map((section) => ( + + ))} );