Fix scrolling to anchor positionning (#3521)

This commit is contained in:
Greg Bergé
2025-08-01 15:44:27 +02:00
committed by GitHub
parent 2cdba53451
commit 185cdb4883
5 changed files with 20 additions and 10 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"gitbook": patch
---
Fix scrolling to anchor positionning
@@ -26,7 +26,7 @@ export function Heading(props: BlockProps<DocumentBlockHeading>) {
'heading',
'flex',
'items-baseline',
'scroll-m-12',
'scroll-mt-(--content-scroll-margin)',
getTextAlignment(block.data.align),
hashLinkButtonWrapperStyles,
style,
@@ -8,10 +8,10 @@ import { useScrollPage } from '@/components/hooks';
/**
* Client component to initialize interactivity for a page.
*/
export function PageClientLayout(props: { withSections?: boolean }) {
export function PageClientLayout() {
// 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({ scrollMarginTop: props.withSections ? 108 : 64 });
useScrollPage();
useStripFallbackQueryParam();
return null;
@@ -11,6 +11,7 @@ import { getPagePath } from '@/lib/pages';
import { isPageIndexable, isSiteIndexable } from '@/lib/seo';
import { getResizedImageURL } from '@/lib/images';
import { tcls } from '@/lib/tailwind';
import { PageContextProvider } from '../PageContext';
import { PageClientLayout } from './PageClientLayout';
import { type PagePathParams, fetchPageData, getPathnameParam } from './fetch';
@@ -70,7 +71,14 @@ export async function SitePage(props: SitePageProps) {
<PageCover as="full" page={page} cover={page.cover} context={context} />
) : null}
{/* We use a flex row reverse to render the aside first because the page is streamed. */}
<div className="flex grow flex-row-reverse justify-end">
<div
className={tcls(
'flex grow flex-row-reverse justify-end',
withSections
? '[--content-scroll-margin:calc(var(--spacing)*27)]'
: '[--content-scroll-margin:calc(var(--spacing)*16)]'
)}
>
<PageAside
page={page}
document={document}
@@ -88,7 +96,7 @@ export async function SitePage(props: SitePageProps) {
/>
</div>
<React.Suspense fallback={null}>
<PageClientLayout withSections={withSections} />
<PageClientLayout />
</React.Suspense>
</PageContextProvider>
);
@@ -10,16 +10,13 @@ import { useHash } from './useHash';
* to the top of the page when navigating between pages (pathname)
* or sections of a page (hash).
*/
export function useScrollPage(props: { scrollMarginTop?: number }) {
export function useScrollPage() {
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',
@@ -36,5 +33,5 @@ export function useScrollPage(props: { scrollMarginTop?: number }) {
}
}
};
}, [hash, pathname, props.scrollMarginTop]);
}, [hash, pathname]);
}