Skip to content

Commit b18c76a

Browse files
authored
Merge pull request #584 from nervosnetwork/v2
fix: merge the scrollbar fixes
2 parents c03c7bb + 1633c0c commit b18c76a

File tree

5 files changed

+129
-67
lines changed

5 files changed

+129
-67
lines changed

website/docusaurus.config.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ const config = {
1313
baseUrl: "/",
1414
organizationName: "nervosnetwork",
1515
projectName: "docs-new",
16-
scripts: ["/js/extra.js", "/js/scrollSidebar.js"],
1716
stylesheets: [
1817
{
1918
href: "https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css",
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
const SIDEBAR_SCROLL_TOP_KEY = "sidebarScrollTop";
2+
3+
export function ensureActiveTabInView() {
4+
const sidebar = document.querySelector("nav[aria-label='Docs sidebar']");
5+
6+
if (sidebar) {
7+
// Hide the scrollbar for better UX
8+
// @ts-ignore
9+
sidebar.style = `
10+
-ms-overflow-style: none; /* IE and Edge */
11+
scrollbar-width: none; /* Firefox */
12+
&::-webkit-scrollbar {
13+
display: none; /* Chrome, Safari and Opera */
14+
}
15+
`;
16+
const lastScrollTop = sessionStorage.getItem(SIDEBAR_SCROLL_TOP_KEY);
17+
if (lastScrollTop !== null) {
18+
sidebar.scrollTop = parseInt(lastScrollTop, 10);
19+
}
20+
}
21+
22+
const activeItems = document.querySelectorAll(".menu__link--active");
23+
24+
if (!activeItems || activeItems.length === 0) {
25+
if (sidebar) {
26+
sessionStorage.setItem(
27+
SIDEBAR_SCROLL_TOP_KEY,
28+
sidebar.scrollTop.toString()
29+
);
30+
}
31+
return;
32+
}
33+
const item = activeItems[activeItems.length - 1];
34+
35+
let isItemVisibleAfterRestore = false;
36+
if (sidebar) {
37+
const itemRect = item.getBoundingClientRect();
38+
const sidebarRect = sidebar.getBoundingClientRect();
39+
// Check if item is visible within the sidebar's viewport
40+
isItemVisibleAfterRestore =
41+
itemRect.top >= sidebarRect.top && itemRect.bottom <= sidebarRect.bottom;
42+
} else {
43+
const bounding = item.getBoundingClientRect();
44+
isItemVisibleAfterRestore =
45+
bounding.top >= 0 &&
46+
bounding.bottom <=
47+
(window.innerHeight || document.documentElement.clientHeight);
48+
}
49+
50+
// Not visible after restoring scroll, so scroll into view.
51+
if (!isItemVisibleAfterRestore) {
52+
item.scrollIntoView({ block: "nearest", inline: "nearest" });
53+
document.body.scrollTop = document.documentElement.scrollTop = 0;
54+
}
55+
56+
if (sidebar) {
57+
sessionStorage.setItem(
58+
SIDEBAR_SCROLL_TOP_KEY,
59+
sidebar.scrollTop.toString()
60+
);
61+
// Restore the scrollbar style
62+
// @ts-ignore
63+
sidebar.style = undefined;
64+
}
65+
}
66+
67+
export function observeDocumentChanges() {
68+
const observer = new MutationObserver((mutationsList) => {
69+
for (const mutation of mutationsList) {
70+
if (
71+
mutation.type === "childList" ||
72+
(mutation.type === "attributes" && mutation.attributeName === "class")
73+
) {
74+
ensureActiveTabInView();
75+
}
76+
}
77+
});
78+
79+
const targetNode = document.getElementById("__docusaurus");
80+
if (targetNode) {
81+
const config = { attributes: true, childList: true, subtree: true };
82+
observer.observe(targetNode, config);
83+
}
84+
return () => {
85+
observer.disconnect();
86+
};
87+
}
88+
89+
export function subscribeSidebarScroll() {
90+
const sidebar = document.querySelector("nav[aria-label='Docs sidebar']");
91+
if (!sidebar) {
92+
return;
93+
}
94+
95+
const handleScroll = () => {
96+
sessionStorage.setItem(
97+
SIDEBAR_SCROLL_TOP_KEY,
98+
sidebar.scrollTop.toString()
99+
);
100+
};
101+
102+
sidebar.addEventListener("scroll", handleScroll);
103+
return () => {
104+
sidebar.removeEventListener("scroll", handleScroll);
105+
};
106+
}

website/src/theme/Navbar/index.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,30 @@
1-
import React from "react";
1+
import { useEffect, useRef } from "react";
22
import NavbarLayout from "@theme/Navbar/Layout";
33
import NavbarContent from "@theme/Navbar/Content";
4+
import { useLocation } from "@docusaurus/router";
5+
import {
6+
ensureActiveTabInView,
7+
observeDocumentChanges,
8+
subscribeSidebarScroll,
9+
} from "./auto-scroll";
410

511
export default function Navbar(): JSX.Element {
12+
const isMounted = useRef(false);
13+
const location = useLocation();
14+
15+
useEffect(() => {
16+
ensureActiveTabInView();
17+
18+
const unsubscribeSidebarScroll = subscribeSidebarScroll();
19+
const unsubscribeDocumentChanges = observeDocumentChanges();
20+
21+
isMounted.current = true;
22+
return () => {
23+
unsubscribeSidebarScroll?.();
24+
unsubscribeDocumentChanges?.();
25+
};
26+
}, [location.pathname]);
27+
628
return (
729
<NavbarLayout>
830
<NavbarContent />

website/static/js/extra.js

Lines changed: 0 additions & 23 deletions
This file was deleted.

website/static/js/scrollSidebar.js

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)