From ffb576fd587668a05940f09bbd447d2742feeb0d Mon Sep 17 00:00:00 2001 From: Viktor Renkema <49148610+viktorrenkema@users.noreply.github.com> Date: Wed, 29 Oct 2025 15:18:22 +0100 Subject: [PATCH 1/2] Revert "Support cover image heights and positioning changes (#3758)" This reverts commit f682df1e01c7022144ceb5da5635fd1694f29a96. --- packages/gitbook/e2e/internal.spec.ts | 16 +-- packages/gitbook/e2e/util.ts | 7 -- .../src/components/PageBody/PageCover.tsx | 8 -- .../components/PageBody/PageCoverImage.tsx | 41 ++++--- .../src/components/PageBody/coverHeight.ts | 25 ---- .../gitbook/src/components/PageBody/index.ts | 1 - .../components/PageBody/useCoverPosition.ts | 109 ------------------ 7 files changed, 31 insertions(+), 176 deletions(-) delete mode 100644 packages/gitbook/src/components/PageBody/coverHeight.ts delete mode 100644 packages/gitbook/src/components/PageBody/useCoverPosition.ts diff --git a/packages/gitbook/e2e/internal.spec.ts b/packages/gitbook/e2e/internal.spec.ts index 8ea1a361a1..34088e136b 100644 --- a/packages/gitbook/e2e/internal.spec.ts +++ b/packages/gitbook/e2e/internal.spec.ts @@ -33,7 +33,6 @@ import { headerLinks, runTestCases, waitForCookiesDialog, - waitForCoverImages, waitForNotFound, } from './util'; @@ -907,10 +906,7 @@ const testCases: TestsCase[] = [ { name: 'With cover', url: 'page-options/page-with-cover', - run: async (page) => { - await waitForCookiesDialog(page); - await waitForCoverImages(page); - }, + run: waitForCookiesDialog, }, { name: 'With cover for dark mode', @@ -925,18 +921,12 @@ const testCases: TestsCase[] = [ { name: 'With hero cover', url: 'page-options/page-with-hero-cover', - run: async (page) => { - await waitForCookiesDialog(page); - await waitForCoverImages(page); - }, + run: waitForCookiesDialog, }, { name: 'With cover and no TOC', url: 'page-options/page-with-cover-and-no-toc', - run: async (page) => { - await waitForCookiesDialog(page); - await waitForCoverImages(page); - }, + run: waitForCookiesDialog, screenshot: { waitForTOCScrolling: false, }, diff --git a/packages/gitbook/e2e/util.ts b/packages/gitbook/e2e/util.ts index 6b62dea8c0..c2b3a93004 100644 --- a/packages/gitbook/e2e/util.ts +++ b/packages/gitbook/e2e/util.ts @@ -154,13 +154,6 @@ export async function waitForNotFound(_page: Page, response: Response | null) { expect(response?.status()).toBe(404); } -export async function waitForCoverImages(page: Page) { - // Wait for cover images to exist (not the shimmer placeholder) - await expect(page.locator('img[alt="Page cover"]').first()).toBeVisible({ - timeout: 10_000, - }); -} - /** * Transform test cases into Playwright tests and run it. */ diff --git a/packages/gitbook/src/components/PageBody/PageCover.tsx b/packages/gitbook/src/components/PageBody/PageCover.tsx index 947e092802..0623310519 100644 --- a/packages/gitbook/src/components/PageBody/PageCover.tsx +++ b/packages/gitbook/src/components/PageBody/PageCover.tsx @@ -8,7 +8,6 @@ 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; @@ -23,12 +22,6 @@ export async function PageCover(props: { context: GitBookSiteContext; }) { const { as, page, cover, context } = props; - const height = getCoverHeight(cover); - - if (!height) { - return null; - } - const [resolved, resolvedDark] = await Promise.all([ cover.ref ? resolveContentRef(cover.ref, context) : null, cover.refDark ? resolveContentRef(cover.refDark, context) : null, @@ -85,7 +78,6 @@ export async function PageCover(props: {
(null); - if (isLoading) { - return ( -
-
-
- ); - } + const container = useResizeObserver({ + // @ts-expect-error wrong types + ref: containerRef, + }); return (
@@ -36,9 +49,10 @@ export function PageCoverImage({ imgs, y }: { imgs: Images; y: number }) { sizes={imgs.light.sizes} fetchPriority="high" alt="Page cover" - className={tcls('h-full', 'w-full', 'object-cover', imgs.dark ? 'dark:hidden' : '')} + className={tcls('w-full', 'object-cover', imgs.dark ? 'dark:hidden' : '')} style={{ - objectPosition: `50% ${objectPositionY}%`, + aspectRatio: `${PAGE_COVER_SIZE.width}/${PAGE_COVER_SIZE.height}`, + objectPosition: `50% ${getTop(container, y, imgs.light)}`, }} /> {imgs.dark && ( @@ -48,9 +62,10 @@ export function PageCoverImage({ imgs, y }: { imgs: Images; y: number }) { sizes={imgs.dark.sizes} fetchPriority="low" alt="Page cover" - className={tcls('h-full', 'w-full', 'object-cover', 'dark:inline', 'hidden')} + className={tcls('w-full', 'object-cover', 'dark:inline', 'hidden')} style={{ - objectPosition: `50% ${objectPositionY}%`, + 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 deleted file mode 100644 index e4f227770e..0000000000 --- a/packages/gitbook/src/components/PageBody/coverHeight.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { RevisionPageDocumentCover } from '@gitbook/api'; - -export const DEFAULT_COVER_HEIGHT = 240; -export const MIN_COVER_HEIGHT = 10; -export const MAX_COVER_HEIGHT = 700; - -// Normalize and clamp the cover height between the minimum and maximum heights -function clampCoverHeight(height: number | null | undefined): number { - if (typeof height !== 'number' || Number.isNaN(height)) { - return DEFAULT_COVER_HEIGHT; - } - - return Math.min(MAX_COVER_HEIGHT, Math.max(MIN_COVER_HEIGHT, height)); -} - -export function getCoverHeight( - cover: RevisionPageDocumentCover | null | undefined -): number | undefined { - // Cover (and thus height) is not defined - if (!cover) { - return undefined; - } - - return clampCoverHeight((cover as RevisionPageDocumentCover).height ?? DEFAULT_COVER_HEIGHT); -} diff --git a/packages/gitbook/src/components/PageBody/index.ts b/packages/gitbook/src/components/PageBody/index.ts index 74b91d6169..651c1bdb00 100644 --- a/packages/gitbook/src/components/PageBody/index.ts +++ b/packages/gitbook/src/components/PageBody/index.ts @@ -1,3 +1,2 @@ export * from './PageBody'; export * from './PageCover'; -export * from './useCoverPosition'; diff --git a/packages/gitbook/src/components/PageBody/useCoverPosition.ts b/packages/gitbook/src/components/PageBody/useCoverPosition.ts deleted file mode 100644 index 7d749f48b0..0000000000 --- a/packages/gitbook/src/components/PageBody/useCoverPosition.ts +++ /dev/null @@ -1,109 +0,0 @@ -'use client'; -import { useLayoutEffect, useMemo, useRef, useState } from 'react'; -import { useResizeObserver } from 'usehooks-ts'; - -interface ImageSize { - width: number; - height: number; -} - -interface ImageAttributes { - src: string; - srcSet?: string; - sizes?: string; - width?: number; - height?: number; - size?: ImageSize; -} - -interface Images { - light: ImageAttributes; - dark?: ImageAttributes; -} - -/** - * Hook to calculate the object position Y percentage for a cover image - * based on the y offset, image dimensions, and container dimensions. - */ -export function useCoverPosition(imgs: Images, y: number) { - const containerRef = useRef(null); - const [loadedDimensions, setLoadedDimensions] = useState(null); - const [isLoading, setIsLoading] = useState(!imgs.light.size && !imgs.dark?.size); - - const container = useResizeObserver({ - // @ts-expect-error wrong types - ref: containerRef, - }); - - // Load original image dimensions if not provided in `imgs` - useLayoutEffect(() => { - // Check if we have dimensions from either light or dark image - const hasDimensions = imgs.light.size || imgs.dark?.size; - - if (hasDimensions) { - return; // Already have dimensions - } - - setIsLoading(true); - - // Load the original image (using src, not srcSet) to get true dimensions - // Use dark image if available, otherwise fall back to light - const imageToLoad = imgs.dark || imgs.light; - const img = new Image(); - img.onload = () => { - setLoadedDimensions({ - width: img.naturalWidth, - height: img.naturalHeight, - }); - setIsLoading(false); - }; - img.onerror = () => { - // If image fails to load, use a fallback - setIsLoading(false); - }; - img.src = imageToLoad.src; - }, [imgs.light, imgs.dark]); - - // Use provided dimensions or fall back to loaded dimensions - // Check light first, then dark, then loaded dimensions - const imageDimensions = imgs.light.size ?? imgs.dark?.size ?? loadedDimensions; - - // Calculate ratio and dimensions similar to useCoverPosition hook - const ratio = - imageDimensions && container.height && container.width - ? Math.max( - container.width / imageDimensions.width, - container.height / imageDimensions.height - ) - : 1; - const safeRatio = ratio || 1; - - const scaledHeight = - imageDimensions && container.height ? imageDimensions.height * safeRatio : null; - const maxOffset = - scaledHeight && container.height - ? Math.max(0, (scaledHeight - container.height) / 2 / safeRatio) - : 0; - - // Parse the position between the allowed min/max - const objectPositionY = useMemo(() => { - if (!container.height || !imageDimensions) { - return 50; - } - - const scaled = imageDimensions.height * safeRatio; - if (scaled <= container.height || maxOffset === 0) { - return 50; - } - - const clampedOffset = Math.max(-maxOffset, Math.min(maxOffset, y)); - const relative = (maxOffset - clampedOffset) / (2 * maxOffset); - return relative * 100; - }, [container.height, imageDimensions, maxOffset, safeRatio, y]); - - return { - containerRef, - objectPositionY, - isLoading: !imageDimensions || isLoading, - }; -} From 47aefb747501cda086db2cefab36b09e2888a1cb Mon Sep 17 00:00:00 2001 From: Viktor Renkema Date: Thu, 30 Oct 2025 10:10:42 +0100 Subject: [PATCH 2/2] Disable docs.gradient.network as theyre offline --- packages/gitbook/e2e/customers.spec.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/gitbook/e2e/customers.spec.ts b/packages/gitbook/e2e/customers.spec.ts index 3d79d09848..f0e18037b0 100644 --- a/packages/gitbook/e2e/customers.spec.ts +++ b/packages/gitbook/e2e/customers.spec.ts @@ -112,11 +112,11 @@ const testCases: TestsCase[] = [ contentBaseURL: 'https://adiblar.gitbook.io', tests: [{ name: 'Home', url: '/' }], }, - { - name: 'docs.gradient.network', - contentBaseURL: 'https://docs.gradient.network', - tests: [{ name: 'Home', url: '/' }], - }, + // { + // name: 'docs.gradient.network', + // contentBaseURL: 'https://docs.gradient.network', + // tests: [{ name: 'Home', url: '/' }], + // }, // { // name: 'mygate-network.gitbook.io', // contentBaseURL: 'https://mygate-network.gitbook.io',