mirror of
https://github.com/netbirdio/docs.git
synced 2026-09-01 20:51:28 +02:00
Make sidebar nav groups with landing pages collapsible and fix mobile drawer closing on expand (#786)
* Add collapsible nav groups and delete old /docs dir * coderabbit fixes: auto-open effect, stable key, push guard
This commit is contained in:
@@ -8,12 +8,13 @@ import {
|
||||
} from '@/components/NavigationAPI'
|
||||
import { AnimatePresence, motion } from 'framer-motion'
|
||||
import { Button } from '@/components/mdx'
|
||||
import { useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import {
|
||||
NavigationStateProvider,
|
||||
useNavigationState,
|
||||
} from '@/components/NavigationState'
|
||||
import ChevronDownIcon from '@/components/icons/ChevronDownIcon'
|
||||
import { useIsInsideMobileNavigation } from '@/components/MobileNavigation'
|
||||
|
||||
export const docsNavigation = [
|
||||
{
|
||||
@@ -51,7 +52,7 @@ export const docsNavigation = [
|
||||
{ title: 'Quickstart Guide', href: '/get-started' },
|
||||
{
|
||||
title: 'Install NetBird',
|
||||
isOpen: true,
|
||||
isOpen: false,
|
||||
href: '/get-started/install',
|
||||
links: [
|
||||
{ title: 'Linux', href: '/get-started/install/linux' },
|
||||
@@ -951,11 +952,17 @@ const findActiveGroupIndex = (group, pathname) => {
|
||||
|
||||
function NavigationGroup({ group, className, hasChildren }) {
|
||||
let router = useRouter()
|
||||
let isActiveGroup = findActiveGroupIndex(group, router.pathname) !== -1
|
||||
let isActiveGroup =
|
||||
group.href === router.pathname ||
|
||||
findActiveGroupIndex(group, router.pathname) !== -1
|
||||
const [isOpen, setIsOpen] = useState(
|
||||
group.isOpen ? group.isOpen : !hasChildren
|
||||
(group.isOpen ?? !hasChildren) || isActiveGroup
|
||||
)
|
||||
useEffect(() => {
|
||||
if (isActiveGroup) setIsOpen(true)
|
||||
}, [router.pathname, isActiveGroup])
|
||||
const [, setActiveHighlight] = useNavigationState()
|
||||
const isInsideMobileNavigation = useIsInsideMobileNavigation()
|
||||
|
||||
return (
|
||||
<li className={clsx('relative', className, hasChildren ? '' : 'mt-6')}>
|
||||
@@ -965,12 +972,19 @@ function NavigationGroup({ group, className, hasChildren }) {
|
||||
'group flex items-center justify-between gap-2',
|
||||
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'
|
||||
: 'text-xs font-semibold text-zinc-900 dark:text-white'
|
||||
: 'text-xs font-semibold text-zinc-900 dark:text-white',
|
||||
group.href === router.pathname && 'text-zinc-900 dark:text-white'
|
||||
)}
|
||||
onClick={() => {
|
||||
if (group.href) {
|
||||
if (!isOpen) setIsOpen(true)
|
||||
if (group.href !== router.pathname) router.push(group.href)
|
||||
setActiveHighlight()
|
||||
return
|
||||
}
|
||||
setIsOpen(!isOpen)
|
||||
if (!isOpen) {
|
||||
if (!isActiveGroup && group.links[0]?.href)
|
||||
if (!isActiveGroup && !isInsideMobileNavigation && group.links[0]?.href)
|
||||
router.push(group.links[0].href)
|
||||
setActiveHighlight()
|
||||
} else {
|
||||
@@ -982,14 +996,28 @@ function NavigationGroup({ group, className, hasChildren }) {
|
||||
>
|
||||
{group.title}
|
||||
{hasChildren && (
|
||||
<ChevronDownIcon
|
||||
className={clsx(
|
||||
'fill-zinc-700 group-hover:fill-zinc-900 dark:fill-zinc-300 dark:group-hover:fill-white',
|
||||
'transition',
|
||||
isOpen ? 'rotate-180 transform' : ''
|
||||
)}
|
||||
size={10}
|
||||
/>
|
||||
<span
|
||||
className="-m-1 flex items-center justify-center p-1"
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
setIsOpen(!isOpen)
|
||||
if (isOpen) {
|
||||
setActiveHighlight(group.title)
|
||||
} else {
|
||||
setActiveHighlight()
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ChevronDownIcon
|
||||
className={clsx(
|
||||
'fill-zinc-700 group-hover:fill-zinc-900 dark:fill-zinc-300 dark:group-hover:fill-white',
|
||||
'transition',
|
||||
isOpen ? 'rotate-180 transform' : ''
|
||||
)}
|
||||
size={10}
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</motion.h2>
|
||||
<div className={clsx('relative', hasChildren ? '' : 'mt-3 pl-2')}>
|
||||
@@ -1031,23 +1059,22 @@ function NavigationGroup({ group, className, hasChildren }) {
|
||||
className="border-l border-transparent"
|
||||
>
|
||||
{group.links.map((link) => {
|
||||
return link.href ? (
|
||||
return link.links ? (
|
||||
<NavigationGroup
|
||||
className={'ml-4'}
|
||||
key={link.title}
|
||||
group={link}
|
||||
hasChildren={true}
|
||||
/>
|
||||
) : (
|
||||
<motion.li key={link.href} className="relative">
|
||||
<NavLink
|
||||
href={link.href}
|
||||
active={link.href === router.pathname}
|
||||
links={link.links}
|
||||
>
|
||||
{link.title}
|
||||
</NavLink>
|
||||
</motion.li>
|
||||
) : (
|
||||
<NavigationGroup
|
||||
className={'ml-4'}
|
||||
key={link.title + isOpen}
|
||||
group={link}
|
||||
hasChildren={true}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</motion.ul>
|
||||
|
||||
Reference in New Issue
Block a user