mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-16 15:45:13 +00:00
Start prev/next navigation
This commit is contained in:
@@ -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
|
||||
<main>
|
||||
<PageHeader page={page} />
|
||||
<PageDocument space={space} revision={revision} page={page} />
|
||||
<PageFooterNavigation revision={revision} page={page} />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
<div className={tcls('flex', 'flex-row', 'mt-6', 'gap-2')}>
|
||||
{previous ? (
|
||||
<NavigationCard
|
||||
icon="P"
|
||||
label="Previous"
|
||||
title={previous.title}
|
||||
href={pageHref(previous.path)}
|
||||
reversed
|
||||
/>
|
||||
) : null}
|
||||
{next ? (
|
||||
<NavigationCard
|
||||
icon="N"
|
||||
label="Next"
|
||||
title={next.title}
|
||||
href={pageHref(next.path)}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function NavigationCard(props: {
|
||||
icon: React.ReactNode;
|
||||
label: string;
|
||||
title: string;
|
||||
href: string;
|
||||
reversed?: boolean;
|
||||
}) {
|
||||
const { icon, label, title, href, reversed } = props;
|
||||
|
||||
return (
|
||||
<Link href={href} className={tcls('group', 'flex', 'flex-1', reversed ? 'flex-row-reverse': 'flex-row', 'align-center', 'p-4', 'border', 'border-slate-200', 'rounded', 'hover:shadow', 'hover:border-primary-500')}>
|
||||
<span className={tcls('flex', 'flex-col', 'flex-1', reversed ? 'text-right' : null)}>
|
||||
<span className={tcls('text-xs', 'text-slate-400')}>{label}</span>
|
||||
<span className={tcls('text-base', 'text-slate-700', 'group-hover:text-primary-600')}>{title}</span>
|
||||
</span>
|
||||
<span className={tcls('group-hover:text-primary-600')}>
|
||||
{icon}
|
||||
</span>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user