diff --git a/src/components/PageBody/PageBody.tsx b/src/components/PageBody/PageBody.tsx index ae65a897f..18ac29982 100644 --- a/src/components/PageBody/PageBody.tsx +++ b/src/components/PageBody/PageBody.tsx @@ -1,6 +1,7 @@ import { Revision, RevisionPageDocument, Space } from '@gitbook/api'; import { PageHeader } from './PageHeader'; import { PageDocument } from './PageDocument'; +import { PageFooterNavigation } from './PageFooterNavigation'; export function PageBody(props: { space: Space; revision: Revision; page: RevisionPageDocument }) { const { space, revision, page } = props; @@ -9,6 +10,7 @@ export function PageBody(props: { space: Space; revision: Revision; page: Revisi
+
); } diff --git a/src/components/PageBody/PageFooterNavigation.tsx b/src/components/PageBody/PageFooterNavigation.tsx new file mode 100644 index 000000000..9b94d239f --- /dev/null +++ b/src/components/PageBody/PageFooterNavigation.tsx @@ -0,0 +1,60 @@ +import { pageHref } from "@/lib/links"; +import { resolvePrevNextPages } from "@/lib/pages"; +import { tcls } from "@/lib/tailwind"; +import { Revision, RevisionPageDocument } from "@gitbook/api"; +import Link from "next/link"; + +/** + * Show cards to go to previous/next pages at the bottom. + */ +export function PageFooterNavigation(props: { + revision: Revision; + page: RevisionPageDocument; +}) { + const { revision, page } = props; + const { previous, next } = resolvePrevNextPages(revision, page); + + return ( +
+ {previous ? ( + + ) : null} + {next ? ( + + ) : null} +
+ ) +} + +function NavigationCard(props: { + icon: React.ReactNode; + label: string; + title: string; + href: string; + reversed?: boolean; +}) { + const { icon, label, title, href, reversed } = props; + + return ( + + + {label} + {title} + + + {icon} + + + ) +} diff --git a/src/lib/pages.ts b/src/lib/pages.ts index 2ec729ee3..5c8248d99 100644 --- a/src/lib/pages.ts +++ b/src/lib/pages.ts @@ -73,6 +73,29 @@ export function resolvePageId( return iteratePages(revision.pages, []); } +/** + * Resolve the next/previous page before another one. + */ +export function resolvePrevNextPages( + revision: Revision, + page: RevisionPageDocument +): { previous?: RevisionPageDocument; next?: RevisionPageDocument } { + const flat = flattenPages(revision.pages); + + const currentIndex = flat.findIndex((p) => p.id === page.id); + if (currentIndex === -1) { + return {}; + } + + const previous = flat[currentIndex - 1]; + const next = flat[currentIndex + 1]; + + return { + previous, next + }; +} + + function resolveFirstDocument( pages: RevisionPage[], ancestors: AncestorRevisionPage[], @@ -105,3 +128,19 @@ function resolvePageDocument( return { page, ancestors }; } + +function flattenPages(pages: RevisionPage[]): RevisionPageDocument[] { + const result: RevisionPageDocument[] = []; + for (const page of pages) { + if (page.type === 'link') { + continue; + } + + if (page.type === 'document') { + result.push(page); + } + result.push(...flattenPages(page.pages)); + } + + return result; +}