Skip to content

Commit d436b04

Browse files
authored
Fix jump when clicking tabs (#3746)
1 parent d159788 commit d436b04

File tree

3 files changed

+35
-21
lines changed

3 files changed

+35
-21
lines changed

packages/gitbook/src/components/DocumentView/Tabs/DynamicTabs.tsx

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,7 @@
22

33
import React, { memo, useCallback, useMemo, type ComponentPropsWithRef } from 'react';
44

5-
import {
6-
NavigationStatusContext,
7-
useHash,
8-
useIsMounted,
9-
useListOverflow,
10-
} from '@/components/hooks';
5+
import { useHash, useIsMounted, useListOverflow } from '@/components/hooks';
116
import { DropdownMenu, DropdownMenuItem } from '@/components/primitives';
127
import { useLanguage } from '@/intl/client';
138
import { tString } from '@/intl/translate';
@@ -74,7 +69,6 @@ export function DynamicTabs(props: {
7469
}) {
7570
const { id, tabs, className } = props;
7671
const router = useRouter();
77-
const { onNavigationClick } = React.useContext(NavigationStatusContext);
7872

7973
const hash = useHash();
8074
const [tabsState, setTabsState] = useTabsState();
@@ -106,8 +100,7 @@ export function DynamicTabs(props: {
106100

107101
const href = `#${tab.id}`;
108102
if (window.location.hash !== href) {
109-
router.replace(href);
110-
onNavigationClick(href);
103+
router.replace(href, { scroll: false });
111104
}
112105

113106
setTabsState((prev) => {
@@ -128,7 +121,7 @@ export function DynamicTabs(props: {
128121
};
129122
});
130123
},
131-
[onNavigationClick, router, setTabsState, tabs, id]
124+
[router, setTabsState, tabs, id]
132125
);
133126

134127
// When the hash changes, we try to select the tab containing the targetted element.
@@ -184,7 +177,10 @@ const TabPanel = memo(function TabPanel(props: {
184177
role="tabpanel"
185178
id={tab.id}
186179
aria-labelledby={getTabButtonId(tab.id)}
187-
className={tcls('p-4', isActive ? null : 'hidden')}
180+
className={tcls(
181+
'scroll-mt-[calc(var(--content-scroll-margin)+var(--spacing)*12)] p-4',
182+
isActive ? null : 'hidden'
183+
)}
188184
>
189185
{tab.body}
190186
</div>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import * as React from 'react';
2+
3+
/**
4+
* Returns the value of the previous render.
5+
*/
6+
export function usePrevious<T>(value: T): T | undefined {
7+
const ref = React.useRef<T | undefined>(undefined);
8+
React.useLayoutEffect(() => {
9+
ref.current = value;
10+
});
11+
return ref.current;
12+
}

packages/gitbook/src/components/hooks/useScrollPage.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { usePathname } from 'next/navigation';
44
import React from 'react';
55

66
import { useHash } from './useHash';
7+
import { usePrevious } from './usePrevious';
78

89
/**
910
* Scroll the page to an anchor point or
@@ -12,8 +13,17 @@ import { useHash } from './useHash';
1213
*/
1314
export function useScrollPage() {
1415
const hash = useHash();
16+
const previousHash = usePrevious(hash);
1517
const pathname = usePathname();
18+
const previousPathname = usePrevious(pathname);
1619
React.useLayoutEffect(() => {
20+
// If there is no change in pathname or hash, do nothing
21+
if (previousHash === hash && previousPathname === pathname) {
22+
return;
23+
}
24+
25+
// If there is a hash
26+
// - Triggered by a change of hash or pathname
1727
if (hash) {
1828
const element = document.getElementById(hash);
1929
if (element) {
@@ -22,16 +32,12 @@ export function useScrollPage() {
2232
behavior: 'smooth',
2333
});
2434
}
25-
} else {
35+
return;
36+
}
37+
38+
// If there was a hash but not anymore, scroll to top
39+
if (previousHash && !hash) {
2640
window.scrollTo(0, 0);
2741
}
28-
return () => {
29-
if (hash) {
30-
const element = document.getElementById(hash);
31-
if (element) {
32-
element.style.scrollMarginTop = '';
33-
}
34-
}
35-
};
36-
}, [hash, pathname]);
42+
}, [hash, previousHash, pathname, previousPathname]);
3743
}

0 commit comments

Comments
 (0)