haixunMaster/haixun-backend/web/src/components/AppSidebar.tsx

80 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NavLink, useLocation } from 'react-router-dom'
import { navGroupsForOnboarding, onboardingGlowClass, shouldGlowNav } from '../lib/onboarding'
import type { AcAppKey } from '../lib/acAssets'
import { useOnboarding } from '../onboarding/OnboardingContext'
import { AcIcon } from './AcIcon'
function SidebarNavItem({
to,
label,
icon,
end,
matchPrefix,
guideGlow,
}: {
to: string
label: string
icon: AcAppKey
end?: boolean
matchPrefix?: string
guideGlow?: boolean
}) {
const { pathname } = useLocation()
return (
<NavLink
to={to}
end={end}
className={({ isActive }) => {
const prefixActive = matchPrefix ? pathname.startsWith(matchPrefix) : false
const active = isActive || prefixActive
return `ac-sidebar-nav-item relative ${active ? 'ac-sidebar-nav-item--active' : ''} ${onboardingGlowClass(!!guideGlow)}`
}}
>
{guideGlow ? (
<span className="hx-guide-badge" aria-hidden>
</span>
) : null}
<AcIcon app={icon} size="sm" className="ac-sidebar-nav-icon shrink-0" />
<span className="min-w-0 truncate">{label}</span>
</NavLink>
)
}
export function AppSidebar() {
const { pathname } = useLocation()
const { isComplete, nextStep } = useOnboarding()
const groups = navGroupsForOnboarding(isComplete)
return (
<aside className="ac-sidebar hidden lg:flex" aria-label="側欄導覽">
{!isComplete ? (
<p className="ac-sidebar-onboarding-hint px-4 pb-2 pt-3 text-xs leading-relaxed text-ink-secondary">
</p>
) : null}
<nav className="ac-sidebar-nav ac-sidebar-nav--top">
{groups.map((group, index) => (
<div key={group.label} className="ac-sidebar-nav-group">
{index > 0 ? <div className="ac-sidebar-nav-divider" aria-hidden /> : null}
<p className="ac-sidebar-nav-label">{group.label}</p>
<ul className="space-y-0.5">
{group.items.map((item) => (
<li key={item.to}>
<SidebarNavItem
to={item.to}
label={item.label}
icon={item.icon}
end={item.end}
matchPrefix={item.matchPrefix}
guideGlow={shouldGlowNav(nextStep, item.to, pathname)}
/>
</li>
))}
</ul>
</div>
))}
</nav>
</aside>
)
}