diff --git a/.changeset/hip-eggs-trade.md b/.changeset/hip-eggs-trade.md new file mode 100644 index 000000000..dabee7f59 --- /dev/null +++ b/.changeset/hip-eggs-trade.md @@ -0,0 +1,5 @@ +--- +'gitbook': patch +--- + +Add scroll margin to the top when there are sections diff --git a/packages/gitbook/src/app/(site)/(content)/[[...pathname]]/PageClientLayout.tsx b/packages/gitbook/src/app/(site)/(content)/[[...pathname]]/PageClientLayout.tsx index 49b29781d..b9febb51a 100644 --- a/packages/gitbook/src/app/(site)/(content)/[[...pathname]]/PageClientLayout.tsx +++ b/packages/gitbook/src/app/(site)/(content)/[[...pathname]]/PageClientLayout.tsx @@ -8,10 +8,10 @@ import { useScrollPage } from '@/components/hooks'; /** * Client component to initialize interactivity for a page. */ -export function PageClientLayout(props: {}) { +export function PageClientLayout(props: { withSections?: boolean }) { // We use this hook in the page layout to ensure the elements for the blocks // are rendered before we scroll to a hash or to the top of the page - useScrollPage(); + useScrollPage({ scrollMarginTop: props.withSections ? 50 : undefined }); useStripFallbackQueryParam(); return null; diff --git a/packages/gitbook/src/app/(site)/(content)/[[...pathname]]/page.tsx b/packages/gitbook/src/app/(site)/(content)/[[...pathname]]/page.tsx index 516fc7867..095e9841a 100644 --- a/packages/gitbook/src/app/(site)/(content)/[[...pathname]]/page.tsx +++ b/packages/gitbook/src/app/(site)/(content)/[[...pathname]]/page.tsx @@ -111,7 +111,7 @@ export default async function Page(props: { /> - + ); diff --git a/packages/gitbook/src/components/hooks/useScrollPage.ts b/packages/gitbook/src/components/hooks/useScrollPage.ts index 48a7bf2be..bf208ac3b 100644 --- a/packages/gitbook/src/components/hooks/useScrollPage.ts +++ b/packages/gitbook/src/components/hooks/useScrollPage.ts @@ -8,13 +8,16 @@ import { useHash } from './useHash'; * to the top of the page when navigating between pages (pathname) * or sections of a page (hash). */ -export function useScrollPage() { +export function useScrollPage(props: { scrollMarginTop?: number }) { const hash = useHash(); const pathname = usePathname(); React.useLayoutEffect(() => { if (hash) { const element = document.getElementById(hash); if (element) { + if (props.scrollMarginTop) { + element.style.scrollMarginTop = `${props.scrollMarginTop}px`; + } element.scrollIntoView({ block: 'start', behavior: 'smooth', @@ -23,5 +26,13 @@ export function useScrollPage() { } else { window.scrollTo(0, 0); } - }, [hash, pathname]); + return () => { + if (hash) { + const element = document.getElementById(hash); + if (element) { + element.style.scrollMarginTop = ''; + } + } + }; + }, [hash, pathname, props.scrollMarginTop]); }