From 88fe9e97c0ece2e340c2da94034ec37607499ecf Mon Sep 17 00:00:00 2001 From: Viktor Renkema Date: Mon, 13 Oct 2025 12:43:17 +0200 Subject: [PATCH] Enable cover heights in gbo --- .../src/components/PageBody/PageBody.tsx | 4 ++- .../src/components/PageBody/PageCover.tsx | 9 ++++++ .../components/PageBody/PageCoverImage.tsx | 6 ++-- .../src/components/PageBody/coverHeight.ts | 31 +++++++++++++++++++ .../src/components/SitePage/SitePage.tsx | 8 ++--- 5 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 packages/gitbook/src/components/PageBody/coverHeight.ts diff --git a/packages/gitbook/src/components/PageBody/PageBody.tsx b/packages/gitbook/src/components/PageBody/PageBody.tsx index 6f1e8bfca9..4072c7234e 100644 --- a/packages/gitbook/src/components/PageBody/PageBody.tsx +++ b/packages/gitbook/src/components/PageBody/PageBody.tsx @@ -17,6 +17,7 @@ import { PageCover } from './PageCover'; import { PageFooterNavigation } from './PageFooterNavigation'; import { PageHeader } from './PageHeader'; import { PreservePageLayout } from './PreservePageLayout'; +import { hasVisibleCover } from './coverHeight'; const LINK_PREVIEW_MAX_COUNT = 100; @@ -32,6 +33,7 @@ export function PageBody(props: { const { customization } = context; const contentFullWidth = document ? hasFullWidthBlock(document) : false; + const visibleCover = hasVisibleCover(page.cover); // Render link previews only if there are less than LINK_PREVIEW_MAX_COUNT links in the document. const withLinkPreviews = document @@ -60,7 +62,7 @@ export function PageBody(props: { )} > - {page.cover && page.layout.cover && page.layout.coverSize === 'hero' ? ( + {visibleCover && page.layout.cover && page.layout.coverSize === 'hero' ? ( ) : null} diff --git a/packages/gitbook/src/components/PageBody/PageCover.tsx b/packages/gitbook/src/components/PageBody/PageCover.tsx index 0623310519..8a547103c5 100644 --- a/packages/gitbook/src/components/PageBody/PageCover.tsx +++ b/packages/gitbook/src/components/PageBody/PageCover.tsx @@ -8,6 +8,7 @@ import { tcls } from '@/lib/tailwind'; import { assert } from 'ts-essentials'; import { PageCoverImage } from './PageCoverImage'; +import { getCoverHeight } from './coverHeight'; import defaultPageCoverSVG from './default-page-cover.svg'; const defaultPageCover = defaultPageCoverSVG as StaticImageData; @@ -22,6 +23,12 @@ export async function PageCover(props: { context: GitBookSiteContext; }) { const { as, page, cover, context } = props; + const height = getCoverHeight(cover); + + if (height <= 0) { + return null; + } + const [resolved, resolvedDark] = await Promise.all([ cover.ref ? resolveContentRef(cover.ref, context) : null, cover.refDark ? resolveContentRef(cover.refDark, context) : null, @@ -78,8 +85,10 @@ export async function PageCover(props: {
@@ -61,9 +60,8 @@ export function PageCoverImage({ imgs, y }: { imgs: Images; y: number }) { sizes={imgs.dark.sizes} fetchPriority="low" alt="Page cover" - className={tcls('w-full', 'object-cover', 'dark:inline', 'hidden')} + className={tcls('h-full', 'w-full', 'object-cover', 'dark:inline', 'hidden')} style={{ - aspectRatio: `${PAGE_COVER_SIZE.width}/${PAGE_COVER_SIZE.height}`, objectPosition: `50% ${getTop(container, y, imgs.dark)}`, }} /> diff --git a/packages/gitbook/src/components/PageBody/coverHeight.ts b/packages/gitbook/src/components/PageBody/coverHeight.ts new file mode 100644 index 0000000000..76ca3d7456 --- /dev/null +++ b/packages/gitbook/src/components/PageBody/coverHeight.ts @@ -0,0 +1,31 @@ +import type { RevisionPageDocumentCover } from '@gitbook/api'; + +export const DEFAULT_COVER_HEIGHT = 240; +export const MIN_COVER_HEIGHT = 10; +export const MAX_COVER_HEIGHT = 700; + +type CoverWithHeight = RevisionPageDocumentCover & { height?: number | null }; + +export function clampCoverHeight(value: number): number { + return Math.min(MAX_COVER_HEIGHT, Math.max(MIN_COVER_HEIGHT, value)); +} + +export function normalizeCoverHeight(height: number | null | undefined): number { + if (typeof height !== 'number' || Number.isNaN(height)) { + return DEFAULT_COVER_HEIGHT; + } + + return clampCoverHeight(height); +} + +export function getCoverHeight(cover: RevisionPageDocumentCover | null | undefined): number { + if (!cover) { + return 0; + } + + return normalizeCoverHeight((cover as CoverWithHeight).height); +} + +export function hasVisibleCover(cover: RevisionPageDocumentCover | null | undefined): boolean { + return getCoverHeight(cover) > 0; +} diff --git a/packages/gitbook/src/components/SitePage/SitePage.tsx b/packages/gitbook/src/components/SitePage/SitePage.tsx index 4f0643ceec..74c2cc3d64 100644 --- a/packages/gitbook/src/components/SitePage/SitePage.tsx +++ b/packages/gitbook/src/components/SitePage/SitePage.tsx @@ -11,6 +11,7 @@ import React from 'react'; import { PageAside } from '@/components/PageAside'; import { PageBody, PageCover } from '@/components/PageBody'; +import { hasVisibleCover } from '@/components/PageBody/coverHeight'; import { getPagePath } from '@/lib/pages'; import { isPageIndexable, isSiteIndexable } from '@/lib/seo'; @@ -169,10 +170,9 @@ export async function getSitePageData(props: SitePageProps) { const { page, ancestors } = pageTarget; const withTopHeader = customization.header.preset !== CustomizationHeaderPreset.None; - const withFullPageCover = !!( - page.cover && - page.layout.cover && - page.layout.coverSize === 'full' + const visibleCover = hasVisibleCover(page.cover); + const withFullPageCover = Boolean( + visibleCover && page.layout.cover && page.layout.coverSize === 'full' ); const withPageFeedback = customization.feedback.enabled;