docs: promote Agent Network in the sidebar and make sections collapsible (#920)

* docs: promote Agent Network in the sidebar and make sections collapsible

Rework the docs sidebar navigation:
- Render any nav group flagged `featured: true` as a highlighted card at the
  top of the sidebar, with an optional `badge` label (currently Agent Network,
  "New"). The flag is data-driven, so a future feature can take the spot by
  moving two lines.
- Add a dropdown chevron to every collapsible menu, including the top-level
  sections and the featured card, so it is obvious they expand.
- Collapse the top-level sections by default and expand the active one, so the
  sidebar reads as a clean menu.
- Only render the active-page marker while its section is open, fixing the
  orange highlight bar that lingered after collapsing an active section.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs: make sidebar section toggles keyboard-accessible

The collapse toggle was a click-only span, so after sections collapse by
default keyboard and screen-reader users could not expand a section or reach
its links. Make each toggle a semantic button with aria-expanded and an
aria-label, which restores keyboard operation and announces the open state.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs: keep sidebar sections expanded by default, collapse only Agent Network

Restore the original behavior where top-level sections start expanded and only
the nested sub-groups start collapsed, instead of collapsing everything. The
featured Agent Network card keeps its own isOpen: false so it starts collapsed.
The dropdown chevrons, featured card, and keyboard-accessible toggles are
unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Bruno Mercier Costa
2026-08-17 10:35:10 +02:00
committed by GitHub
co-authored by Claude Opus 4.8
parent 538854e840
commit cbdbe5b5f0
+77 -36
View File
@@ -453,6 +453,14 @@ export const docsNavigation = [
}, },
{ {
title: 'AGENT NETWORK', title: 'AGENT NETWORK',
// Featured highlight: any group with `featured: true` renders as the
// card at the top of the sidebar, with an optional `badge`. isOpen:false
// keeps this card collapsed by default, while the other top-level
// sections start expanded. To spotlight a different product later, move
// these lines to its group; remove them to drop the card entirely.
featured: true,
badge: 'New',
isOpen: false,
links: [ links: [
{ {
title: 'Getting Started', title: 'Getting Started',
@@ -1171,15 +1179,30 @@ export function NavigationDocs({ className }) {
Github Github
</TopLevelNavItem> </TopLevelNavItem>
<TopLevelNavItem href="/slack-url">Support</TopLevelNavItem> <TopLevelNavItem href="/slack-url">Support</TopLevelNavItem>
{docsNavigation.map((group, groupIndex) => ( {docsNavigation.map((group, groupIndex) =>
<NavigationStateProvider key={group.title} index={groupIndex}> group.featured ? (
<NavigationGroup <NavigationStateProvider key={group.title} index={groupIndex}>
group={group} <NavigationGroup group={group} index={groupIndex} className="md:mt-0" />
index={groupIndex} </NavigationStateProvider>
className={groupIndex === 0 && 'md:mt-0'} ) : null
/> )}
</NavigationStateProvider> {docsNavigation.some((group) => group.featured) && (
))} <li
aria-hidden="true"
className="my-4 border-t border-zinc-900/10 dark:border-white/10"
/>
)}
{docsNavigation.map((group, groupIndex) =>
group.featured ? null : (
<NavigationStateProvider key={group.title} index={groupIndex}>
<NavigationGroup
group={group}
index={groupIndex}
className={groupIndex === 0 && 'md:mt-0'}
/>
</NavigationStateProvider>
)
)}
<li className="sticky bottom-0 z-10 mt-6 min-[416px]:hidden"> <li className="sticky bottom-0 z-10 mt-6 min-[416px]:hidden">
<Button <Button
href="https://app.netbird.io/" href="https://app.netbird.io/"
@@ -1222,6 +1245,10 @@ function NavigationGroup({ group, className, hasChildren }) {
}, [router.pathname, isActiveGroup]) }, [router.pathname, isActiveGroup])
const [, setActiveHighlight] = useNavigationState() const [, setActiveHighlight] = useNavigationState()
const isInsideMobileNavigation = useIsInsideMobileNavigation() const isInsideMobileNavigation = useIsInsideMobileNavigation()
const isFeatured = !!group.featured
// Show a dropdown chevron on every collapsible menu (top-level sections,
// nested groups, and the featured card), so it is obvious they expand.
const showChevron = (group.links?.length ?? 0) > 0
return ( return (
<li className={clsx('relative', className, hasChildren ? '' : 'mt-6')}> <li className={clsx('relative', className, hasChildren ? '' : 'mt-6')}>
@@ -1229,9 +1256,11 @@ function NavigationGroup({ group, className, hasChildren }) {
// layout={"size"} // layout={"size"}
className={clsx( className={clsx(
'group flex items-center justify-between gap-2', 'group flex items-center justify-between gap-2',
hasChildren isFeatured
? 'cursor-pointer select-none rounded-lg border border-netbird/30 bg-netbird/5 px-3 py-2 text-xs font-bold uppercase tracking-wide text-netbird transition hover:bg-netbird/10'
: hasChildren
? 'cursor-pointer select-none py-1 pr-3 text-sm font-medium text-zinc-700 hover:text-zinc-900 dark:text-zinc-300 dark:hover:text-white' ? 'cursor-pointer select-none py-1 pr-3 text-sm font-medium text-zinc-700 hover:text-zinc-900 dark:text-zinc-300 dark:hover:text-white'
: 'text-xs font-semibold text-zinc-900 dark:text-white', : 'cursor-pointer select-none text-xs font-semibold text-zinc-900 dark:text-white',
group.href === router.pathname && 'text-zinc-900 dark:text-white' group.href === router.pathname && 'text-zinc-900 dark:text-white'
)} )}
onClick={() => { onClick={() => {
@@ -1258,33 +1287,45 @@ function NavigationGroup({ group, className, hasChildren }) {
data-nb-active={hasChildren && isActiveGroup ? '1' : '0'} data-nb-active={hasChildren && isActiveGroup ? '1' : '0'}
> >
{group.title} {group.title}
{hasChildren && ( <span className="flex items-center gap-2">
<span {isFeatured && group.badge && (
className="-m-1 flex items-center justify-center p-1" <span className="rounded-full bg-netbird px-2 py-0.5 text-[10px] font-bold uppercase leading-none text-white">
onClick={(e) => { {group.badge}
e.preventDefault() </span>
e.stopPropagation() )}
setIsOpen(!isOpen) {showChevron && (
if (isOpen) { <button
setActiveHighlight(group.title) type="button"
} else { aria-label={`${isOpen ? 'Collapse' : 'Expand'} ${group.title}`}
setActiveHighlight() aria-expanded={isOpen}
} className="-m-1 flex cursor-pointer items-center justify-center p-1"
}} onClick={(e) => {
> e.preventDefault()
<ChevronDownIcon e.stopPropagation()
className={clsx( setIsOpen(!isOpen)
'fill-zinc-700 group-hover:fill-zinc-900 dark:fill-zinc-300 dark:group-hover:fill-white', if (isOpen) {
'transition', setActiveHighlight(group.title)
isOpen ? 'rotate-180 transform' : '' } else {
)} setActiveHighlight()
size={10} }
/> }}
</span> >
)} <ChevronDownIcon
className={clsx(
isFeatured
? 'fill-netbird'
: 'fill-zinc-500 group-hover:fill-zinc-900 dark:fill-zinc-400 dark:group-hover:fill-white',
'transition-transform duration-200',
isOpen ? 'rotate-180 transform' : ''
)}
size={12}
/>
</button>
)}
</span>
</motion.h2> </motion.h2>
<div className={clsx('relative', hasChildren ? '' : 'mt-3 pl-2')}> <div className={clsx('relative', hasChildren ? '' : 'mt-3 pl-2')}>
{!hasChildren && ( {!hasChildren && isOpen && (
<> <>
<AnimatePresence> <AnimatePresence>
{isActiveGroup && ( {isActiveGroup && (