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' ;
2
8
9
+ import { pageHref } from '@/lib/links' ;
3
10
import { tcls } from '@/lib/tailwind' ;
4
11
5
12
import { PageIcon } from '../PageIcon' ;
13
+ import { StyledLink } from '../primitives' ;
6
14
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 ;
9
17
10
18
if ( ! page . layout . title && ! page . layout . description ) {
11
19
return null ;
12
20
}
13
21
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
+
14
30
return (
15
31
< header
16
32
className = { tcls ( 'max-w-3xl' , 'mx-auto' , 'mb-6' , 'space-y-3' , 'page-api-block:ml-0' ) }
17
33
>
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
+ ) }
18
76
{ page . layout . title ? (
19
77
< h1 className = { tcls ( 'text-4xl' , 'font-bold' , 'flex' , 'items-center' , 'gap-4' ) } >
20
78
< PageIcon page = { page } style = { [ 'text-dark/6' , 'dark:text-light/6' ] } />
@@ -29,3 +87,10 @@ export function PageHeader(props: { page: RevisionPageDocument }) {
29
87
</ header >
30
88
) ;
31
89
}
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