markdown-toc.tsx
Overview
markdown-toc.tsx is a React functional component designed to dynamically generate and display a Table of Contents (ToC) for markdown content rendered on a webpage. It scans the document for headings (<h2> and <h3>) within markdown content and organizes them hierarchically. The ToC allows users to quickly navigate to different sections of the markdown by clicking on the generated anchor links.
This component uses Ant Design's Anchor component to render the ToC with smooth scrolling and link highlighting features. The ToC is displayed as a fixed-position sidebar on the right side of the viewport, providing persistent navigation while the user scrolls through the content.
Detailed Documentation
Imports
AnchorandAnchorLinkItemPropsfrom antd: Used for rendering anchor navigation links.React,useEffect,useState: React hooks for component state and lifecycle management.
Interface: MarkdownTocProps
interface MarkdownTocProps {
content: string;
}
content: A string representing the markdown content. Although not directly parsed inside the component, this prop is used as a dependency for the effect that generates the ToC, ensuring the ToC updates when the content changes.
Component: MarkdownToc
const MarkdownToc: React.FC<MarkdownTocProps> = ({ content }) => { ... }
Purpose:
Renders a fixed-position sidebar containing a Table of Contents derived from markdown headings (h2andh3) found within a container with class.wmde-markdown.Parameters:
content: Markdown content string (used as a trigger to regenerate the ToC when it changes).
State:
items(AnchorLinkItemProps[]): Array of anchor link items representing the ToC structure, passed to the Ant DesignAnchorcomponent.
Internal Function: generateTocItems
Purpose:
Extracts all<h2>and<h3>headings from the DOM element with class.wmde-markdownand constructs a nested structure of anchor items for the ToC.Algorithm:
Selects all
h2andh3elements inside.wmde-markdown.Iterates over each heading:
Retrieves its text content and
id.Creates an anchor item with
key,href, andtitle.
For
h2elements:Starts a new top-level ToC item.
For
h3elements:Adds as a child to the most recently found
h2item.If no
h2is present, adds directly to the root list.
Updates the component state with the generated list, slicing off the first item (likely to omit an unwanted heading).
Timeout Usage:
The function is executed inside asetTimeoutwith 100ms delay to ensure the DOM is fully rendered before querying headings.
React Hook: useEffect
Dependencies:
[content]Behavior:
TriggersgenerateTocItemswhenever thecontentprop changes, updating the ToC accordingly.
JSX Render
<div className="markdown-toc ...style props">
<Anchor items={items} affix={false} />
</div>
Container Div:
Styled as a fixed sidebar on the right with scrolling enabled.Anchorcomponent:
Displays the hierarchical ToC with clickable links that scroll to the corresponding headings.Affix Disabled:
affix={false}disables the default sticky behavior of theAnchorcomponent because the container itself is already fixed.
Usage Example
import React from 'react';
import MarkdownToc from './markdown-toc';
// Assume markdown content is rendered somewhere with class "wmde-markdown"
const markdownContent = `
## Section 1
### Subsection 1.1
## Section 2
### Subsection 2.1
`;
const Page = () => (
<div>
<div className="wmde-markdown" dangerouslySetInnerHTML={{ __html: markdownToHtml(markdownContent) }} />
<MarkdownToc content={markdownContent} />
</div>
);
MarkdownToclistens for changes incontentand updates the ToC accordingly.The markdown content must be rendered inside an element with class
.wmde-markdownfor the ToC to detect headings.
Implementation Details and Notes
Heading Selection:
Only<h2>and<h3>tags are considered to keep the ToC concise and manageable.Hierarchy Construction:
The ToC supports two-level nesting:h2elements create top-level items.h3elements are nested as children under the nearest precedingh2.
DOM Querying:
The component directly queries the DOM (document.querySelectorAll) instead of parsing markdown content or using React refs. This assumes that the rendered markdown is present in the DOM with proper heading IDs.Delay With
setTimeout:
Adding a delay of 100ms helps ensure the markdown content is rendered before heading elements are queried, improving reliability.Slicing Items:
The first item in the generated list is removed (slice(1)). This is likely to exclude a top-level heading that is not relevant for the ToC or a placeholder.Styling:
The component uses utility classes (bg-bg-base,text-text-primary, etc.) indicating a CSS framework or design system is in use for consistent theming.
Interaction With Other Parts of the System
Markdown Content Rendering:
The component expects markdown content to be rendered elsewhere in the DOM with the class.wmde-markdownand with proper heading IDs. This is usually handled by a markdown rendering component or library.Anchor Navigation:
Relies on Ant Design'sAnchorcomponent for smooth scrolling and active link highlighting.Content Prop:
Thecontentprop passed to this component must change whenever the markdown content changes, triggering ToC regeneration.
Visual Diagram
componentDiagram
direction LR
MarkdownToc <|-- React.FC
MarkdownToc : +content: string
MarkdownToc : +items: AnchorLinkItemProps[]
MarkdownToc : +generateTocItems()
MarkdownToc --> Anchor : renders with items
MarkdownToc ..> document.querySelectorAll : queries headings h2, h3 in .wmde-markdown
Anchor : Displays ToC links
Summary
markdown-toc.tsx provides a reusable React component that dynamically builds a hierarchical Table of Contents for markdown content based on <h2> and <h3> headings. It leverages direct DOM access to detect headings and Ant Design's Anchor component to render the ToC with smooth navigation. This component improves user experience by offering quick section navigation, especially in long markdown documents. It integrates tightly with markdown renderers that produce HTML with consistent heading IDs inside an element with class .wmde-markdown.