1- import { RevisionPageDocument } from '@gitbook/api' ;
1+ import {
2+ RevisionPage ,
3+ RevisionPageDocument ,
4+ RevisionPageGroup ,
5+ RevisionPageType ,
6+ } from '@gitbook/api' ;
7+ import { Icon } from '@gitbook/icons' ;
28
9+ import { pageHref } from '@/lib/links' ;
310import { tcls } from '@/lib/tailwind' ;
411
512import { PageIcon } from '../PageIcon' ;
13+ import { StyledLink } from '../primitives' ;
614
7- export function PageHeader ( props : { page : RevisionPageDocument } ) {
8- const { page } = props ;
15+ export function PageHeader ( props : { page : RevisionPageDocument ; pages : RevisionPage [ ] } ) {
16+ const { page, pages } = props ;
917
1018 if ( ! page . layout . title && ! page . layout . description ) {
1119 return null ;
1220 }
1321
22+ const pathSegments = page . path . split ( '/' ) . slice ( 0 , - 1 ) ; // Exclude the current page from the breadcrumbs
23+ const flattenedPages = flattenPages ( pages ) ;
24+ const breadcrumbs = pathSegments
25+ . map ( ( pathSegment ) =>
26+ flattenedPages . find ( ( page ) => 'slug' in page && page . slug == pathSegment ) ,
27+ )
28+ . filter ( ( page ) : page is RevisionPageDocument | RevisionPageGroup => page !== undefined ) ;
29+
1430 return (
1531 < header
1632 className = { tcls ( 'max-w-3xl' , 'mx-auto' , 'mb-6' , 'space-y-3' , 'page-api-block:ml-0' ) }
1733 >
34+ { breadcrumbs ?. length > 0 && (
35+ < nav >
36+ < ol className = { tcls ( 'flex' , 'flex-wrap' , 'items-center' , 'gap-2' ) } >
37+ { breadcrumbs . map ( ( breadcrumb , index ) => (
38+ < >
39+ < li key = { breadcrumb . id } >
40+ < StyledLink
41+ href = { pageHref ( pages , breadcrumb ) }
42+ style = { tcls (
43+ 'no-underline' ,
44+ 'hover:underline' ,
45+ 'text-xs' ,
46+ 'tracking-wide' ,
47+ 'font-semibold' ,
48+ 'uppercase' ,
49+ 'flex' ,
50+ 'items-center' ,
51+ 'gap-1' ,
52+ ) }
53+ >
54+ < PageIcon
55+ page = { breadcrumb }
56+ style = { tcls ( 'size-4' , 'text-base' , 'leading-none' ) }
57+ />
58+ { breadcrumb . title }
59+ </ StyledLink >
60+ </ li >
61+ { index != breadcrumbs . length - 1 && (
62+ < Icon
63+ icon = "chevron-right"
64+ className = { tcls (
65+ 'size-3' ,
66+ 'text-light-4' ,
67+ 'dark:text-dark-4' ,
68+ ) }
69+ />
70+ ) }
71+ </ >
72+ ) ) }
73+ </ ol >
74+ </ nav >
75+ ) }
1876 { page . layout . title ? (
1977 < h1 className = { tcls ( 'text-4xl' , 'font-bold' , 'flex' , 'items-center' , 'gap-4' ) } >
2078 < PageIcon page = { page } style = { [ 'text-dark/6' , 'dark:text-light/6' ] } />
@@ -29,3 +87,10 @@ export function PageHeader(props: { page: RevisionPageDocument }) {
2987 </ header >
3088 ) ;
3189}
90+
91+ function flattenPages ( pages : RevisionPage [ ] ) : RevisionPage [ ] {
92+ return pages . reduce < RevisionPage [ ] > ( ( acc , page ) => {
93+ const nestedPages = 'pages' in page && page . pages ? flattenPages ( page . pages ) : [ ] ;
94+ return acc . concat ( page , ...nestedPages ) ;
95+ } , [ ] ) ;
96+ }
0 commit comments