@@ -23,17 +23,47 @@ import {
2323} from './icons.tsx'
2424import { TeamCircle } from './team-circle.tsx'
2525
26- const LINKS = [
27- { id : 'blog' , name : 'Blog' , to : '/blog' } ,
28- { id : 'talks' , name : 'Talks' , to : '/talks' } ,
29- { id : 'courses' , name : 'Courses' , to : '/courses' } ,
30- { id : 'discord' , name : 'Discord' , to : '/discord' } ,
31- { id : 'chats' , name : 'Chats' , to : '/chats/05' } ,
32- { id : 'calls' , name : 'Calls' , to : '/calls/05' } ,
33- { id : 'about' , name : 'About' , to : '/about' } ,
34- ]
35-
36- const MOBILE_LINKS = [ { name : 'Home' , to : '/' } , ...LINKS ]
26+ type NavbarLinkItem = {
27+ id : string
28+ name : string
29+ to : string
30+ /**
31+ * Optional path prefix to determine active state. Useful when the `to` path
32+ * points at a specific season (e.g. `/chats/06`), but we want the nav item
33+ * active for all `/chats/*` routes.
34+ */
35+ activeTo ?: string
36+ }
37+
38+ function useNavbarLinks ( ) : {
39+ links : Array < NavbarLinkItem >
40+ mobileLinks : Array < { name : string ; to : string } >
41+ } {
42+ const { latestPodcastSeasonLinks } = useRootData ( )
43+
44+ const chatsTo = latestPodcastSeasonLinks ?. chats . latestSeasonPath ?? '/chats'
45+ const callsTo = latestPodcastSeasonLinks ?. calls . latestSeasonPath ?? '/calls'
46+
47+ const links = React . useMemo < Array < NavbarLinkItem > > (
48+ ( ) => [
49+ { id : 'blog' , name : 'Blog' , to : '/blog' } ,
50+ { id : 'talks' , name : 'Talks' , to : '/talks' } ,
51+ { id : 'courses' , name : 'Courses' , to : '/courses' } ,
52+ { id : 'discord' , name : 'Discord' , to : '/discord' } ,
53+ { id : 'chats' , name : 'Chats' , to : chatsTo , activeTo : '/chats' } ,
54+ { id : 'calls' , name : 'Calls' , to : callsTo , activeTo : '/calls' } ,
55+ { id : 'about' , name : 'About' , to : '/about' } ,
56+ ] ,
57+ [ chatsTo , callsTo ] ,
58+ )
59+
60+ const mobileLinks = React . useMemo (
61+ ( ) => [ { name : 'Home' , to : '/' } , ...links . map ( ( l ) => ( { name : l . name , to : l . to } ) ) ] ,
62+ [ links ] ,
63+ )
64+
65+ return { links, mobileLinks }
66+ }
3767const searchHotkeyOptions = {
3868 ignoreInputs : true ,
3969 preventDefault : true ,
@@ -48,15 +78,18 @@ const searchHotkeyModifierOptions = {
4878
4979function NavLink ( {
5080 to,
81+ activeTo,
5182 navItem,
5283 ...rest
5384} : Omit < Parameters < typeof Link > [ '0' ] , 'to' > & {
5485 to : string
86+ activeTo ?: string
5587 navItem ?: string
5688} ) {
5789 const location = useLocation ( )
90+ const matchTo = activeTo ?? to
5891 const isSelected =
59- to === location . pathname || location . pathname . startsWith ( `${ to } /` )
92+ matchTo === location . pathname || location . pathname . startsWith ( `${ matchTo } /` )
6093
6194 return (
6295 < li className = "px-5 py-2" data-nav-item = { navItem } >
@@ -610,7 +643,7 @@ function NavSearch({
610643 )
611644}
612645
613- function MobileMenu ( ) {
646+ function MobileMenu ( { links } : { links : Array < { name : string ; to : string } > } ) {
614647 const menuButtonRef = React . useRef < HTMLButtonElement > ( null )
615648 const popoverRef = React . useRef < HTMLDivElement > ( null )
616649 const location = useLocation ( )
@@ -720,7 +753,7 @@ function MobileMenu() {
720753 } }
721754 />
722755 </ div >
723- { MOBILE_LINKS . map ( ( link ) => (
756+ { links . map ( ( link ) => (
724757 < Link
725758 className = "hover:bg-secondary focus:bg-secondary text-primary px-5vw hover:text-team-current border-b border-gray-200 py-9 dark:border-gray-600"
726759 key = { link . to }
@@ -815,6 +848,7 @@ function Navbar() {
815848 const navigate = useNavigate ( )
816849 const [ team ] = useTeam ( )
817850 const { requestInfo, userInfo } = useRootData ( )
851+ const { links, mobileLinks } = useNavbarLinks ( )
818852 const avatar = userInfo ? userInfo . avatar : kodyProfiles [ team ]
819853 const navLinksRef = React . useRef < HTMLDivElement > ( null )
820854 const searchIconRef = React . useRef < HTMLAnchorElement > ( null )
@@ -886,8 +920,13 @@ function Navbar() {
886920 className = "navbar-links flex-none justify-center overflow-visible max-lg:hidden lg:flex"
887921 >
888922 < ul className = "flex" >
889- { LINKS . map ( ( link ) => (
890- < NavLink key = { link . to } to = { link . to } navItem = { link . id } >
923+ { links . map ( ( link ) => (
924+ < NavLink
925+ key = { link . id }
926+ to = { link . to }
927+ activeTo = { link . activeTo }
928+ navItem = { link . id }
929+ >
891930 { link . name }
892931 </ NavLink >
893932 ) ) }
@@ -898,7 +937,7 @@ function Navbar() {
898937 { /* Right: theme + profile */ }
899938 < div className = "flex min-w-0 shrink-0 items-center justify-end" >
900939 < div className = "block lg:hidden" >
901- < MobileMenu />
940+ < MobileMenu links = { mobileLinks } />
902941 </ div >
903942 < div className = "ml-4 flex items-center gap-4 lg:ml-0" >
904943 < div className = "noscript-hidden hidden lg:block" >
0 commit comments