Skip to content

Commit 9b7882d

Browse files
committed
sticky table of content
1 parent 9d9f447 commit 9b7882d

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

src/index.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/pages/Doc/single doc/index.jsx

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect, useState } from 'react';
1+
import React, { useEffect, useRef, useState } from 'react';
22
import { useParams } from 'react-router-dom';
33
import ReactMarkdown from 'react-markdown';
44
import remarkGfm from 'remark-gfm';
@@ -13,6 +13,20 @@ const DocDetail = () => {
1313
const [loading, setLoading] = useState(true);
1414
const [error, setError] = useState(null);
1515
const [headings, setHeadings] = useState([]);
16+
const tableRef = useRef(null);
17+
18+
useEffect(() => {
19+
const handleScroll = () => {
20+
if (tableRef.current) {
21+
const rect = tableRef.current.getBoundingClientRect();
22+
const isTableVisible = rect.top <= 0 && rect.bottom >= 100;
23+
setIsSticky(isTableVisible);
24+
}
25+
};
26+
27+
window.addEventListener('scroll', handleScroll);
28+
return () => window.removeEventListener('scroll', handleScroll);
29+
}, []);
1630

1731
useEffect(() => {
1832
const fetchContent = async () => {
@@ -52,8 +66,9 @@ const DocDetail = () => {
5266
}, [content]);
5367

5468
useEffect(() => {
55-
if (window.location.hash) {
56-
const id = window.location.hash.substring(1);
69+
const hash = window.location.hash;
70+
if (hash) {
71+
const id = hash.substring(1);
5772
const element = document.getElementById(id);
5873
if (element) {
5974
element.scrollIntoView({ behavior: 'smooth' });
@@ -66,17 +81,20 @@ const DocDetail = () => {
6681

6782
return (
6883
<Layout>
69-
<section className="container mx-auto p-4">
84+
<section className="container mx-auto p-4 min-h-screen">
7085
<h3 className="text-2xl md:text-3xl capitalize text-center my-10 mb-20 font-semibold">
7186
{slug.replace(/-/g, ' ')}
7287
</h3>
73-
<div className="flex sticky top-20">
74-
<aside className="w-1/4 p-4">
88+
<div className="flex">
89+
<aside ref={tableRef} className="sticky top-20 w-1/4 p-4 h-0">
7590
<h2 className="text-xl font-bold mb-2">Table of Contents</h2>
7691
<ul>
7792
{headings.map((heading, index) => (
7893
<li key={index} className={`ml-${heading.level}`}>
79-
<a href={`#${heading.title.replace(/\s+/g, '-').toLowerCase()}`}>
94+
<a href={`#${heading.title.replace(/\s+/g, '-').toLowerCase()}`}
95+
96+
onClick={() => console.log(heading.title.replace(/\s+/g, '-').toLowerCase())}
97+
>
8098
{heading.title}
8199
</a>
82100
</li>
@@ -105,13 +123,13 @@ const DocDetail = () => {
105123
);
106124
},
107125
h1({ node, children }) {
108-
return <h1 className='text-xl font-normal mt-5' id={children[0].toLowerCase().replace(/\s+/g, '-')}> {children}</h1>;
126+
return <h1 className='text-xl font-normal mt-10 mb-3' id={children.toLowerCase().replace(/\s+/g, '-')}> {children}</h1>;
109127
},
110128
h2({ node, children }) {
111-
return <h2 className='text-xl font-normal mt-5' id={children[0].toLowerCase().replace(/\s+/g, '-')}>🌿 {children}</h2>;
129+
return <h2 className='text-xl font-normal mt-10 mb-3' id={children.toLowerCase().replace(/\s+/g, '-')}>🌿 {children}</h2>;
112130
},
113131
h3({ node, children }) {
114-
return <h3 className='text-xl font-normal mt-5' id={children[0].toLowerCase().replace(/\s+/g, '-')}>🌿 {children}</h3>;
132+
return <h3 className='text-xl font-normal mt-10 mb-3' id={children.toLowerCase().replace(/\s+/g, '-')}>🌿 {children}</h3>;
115133
},
116134
// Handle other heading levels if needed
117135
}}

0 commit comments

Comments
 (0)