Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d436b04

Browse files
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)

AltStyle によって変換されたページ (->オリジナル) /