React table of content
Provides hooks and utility functions to create a custom and reusable autogenerated table of content for a React project, works really well with markdown content as well.
!NPM Downloads
!GitHub License
!NPM Version
Table of Contents
- React table of content
- Table of Contents
- Features
- Installation
- Usage
- Example implementation
- API
- Hooks
- useTableOfContent
- Arguments
- Return value
- Utility functions
- addIdToHeadingTags
- Arguments
- Return value
- Usage and example
- dashCase
- Arguments
- Return value
- Usage and example
- makeLinksExternal
- Arguments
- Return value
- Usage and example
- readTime
- Arguments
- Return value
- Usage and example
- Testing
- License
- Author
Features
- Generates a table of content based on the headings in a React component.
- Supports custom selectors for headings.
- Supports custom dependencies to watch for changes.
- Provides utility functions to add IDs to heading tags in HTML.
- Provides utility functions to convert strings to dash case.
- Provides utility functions to convert links in HTML to external links (open in new tab).
- Lightweight and easy to use.
- No dependencies.
Installation
``bash
npm install react-table-of-content
`
Usage
`jsx
import React from "react";
import { useTableOfContent } from "react-table-of-content";
export const TableOfContent: React.FC<{}> = () => {
const { headingLinks, contentIsActive } = useTableOfContent();
// return (
// <>JSX>
// )
};
`
Example implementation
You can create a reusable component that generates a table of content for your page using the hook. See the example below.
Reusable custom TableOfContent component
`jsx
import React from "react";
import { useTableOfContent } from "react-table-of-content";
export const TableOfContent: React.FC<{}> = () => {
const { headingLinks, contentIsActive } = useTableOfContent({
selectors: "article h1, article h2, article h3",
});
if (!headingLinks || headingLinks.length < 1) return null;
return (
ON THIS PAGE
{headingLinks.map((link) => {
const isActive = contentIsActive(link.id); return (
className={${
isActive ? "text-gray-800 font-semibold" : "text-gray-500"
}
${["h3", "h4"].includes(link.tagName.toLowerCase()) && "pl-2"}
${["h5", "h6"].includes(link.tagName.toLowerCase()) && "pl-4"}
hover:text-gray-700 transition-colors duration-200
}
href={#${link.id}}
>
{link.title}
);
})}
);
};
`
You can then use the component in your page like so:
Example App component that has needs table of content
`
jsx
import React from "react";
import { TableOfContent } from "./TableOfContent";export const App: React.FC = () => {
return (
);
};
`
Below is an example of an article component that has headings.
Simple Article component with headings
`
jsx
import React from "react";const Article = () => {
const headingTags = ["h1", "h2", "h3", "h4", "h5", "h6"];
const dummyText =
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Laborum vero accusamus alias cumque numquam atque eius ullam nobis at! Necessitatibus, corporis earum? Quidem, corporis blanditiis sapiente veritatis saepe debitis expedita!.";
return (
{headingTags.map((tag, index) => {
const headingElement = createElement(
tag,
{ key: index, id: ${tag}-heading
},
${tag.toUpperCase()} heading
);
return (
{headingElement}
{/ Returns something like this: ${tag}-heading}>{tag.toUpperCase()} heading
/}
{dummyText}
);
})}
);
};
`
API
$3
####
useTableOfContent
The
useTableOfContent
hook generates a table of content for a React component based on the headings in the component.##### Arguments
| Name | Type | Required | Default | Description |
| ----------- | --------- | -------- | -------------- | ------------------------------------------------------------------------------ |
|
selectors
| string
| Optional | "h1, h2, h3"
| A string of comma-separated selectors to use to generate the table of content. |
| deps
| unknown
| Optional | undefined
| An item to be used within the dependency array to watch for changes. |##### Return value
An object with the following properties:
| Name | Type | Description |
| ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
headingLinks
| array
| It contains an array of objects that have the following properties:id
(string): The ID of the heading, title
(string): The text content of the heading, tagName
(string): The tag name of the heading. |
| contentIsActive
| function
| A function that takes an ID of the headingLink
and returns a boolean
indicating whether the content with that ID is active. |$3
The package also exports utility functions that can be used to generate the table of content.
####
addIdToHeadingTags
The
addIdToHeadingTags
function adds an ID to each heading tag in a string of HTML.##### Arguments
Accepts 1 argument of type
string
containing the HTML to add IDs to heading tags.##### Return value
A
string
of HTML with IDs added to the heading tags.##### Usage and example
`
js
import { addIdToHeadingTags } from "react-table-of-content";const html =
Heading 1
Content 1
Heading 2
Content 2
;const newHtml = addIdToHeadingTags(html);
console.log(newHtml);
// Output:
//
Heading 1
// Content 1
// Heading 2
// Content 2
`
####
dashCase
It's a function that converts a string to dash case.
##### Arguments
Accepts 1 argument of type
string
to be transformed to a dash cased format.##### Return value
A string in dash case.
##### Usage and example
`
js
import { dashCase } from "react-table-of-content";const str = "This is a string";
const newStr = dashCase(str);
console.log(newStr);
// Output:
// this-is-a-string
`
####
makeLinksExternal
It's a function that converts all links in a string of HTML to external links.
##### Arguments
Accepts 1 argument of type
string
containing the HTML to convert links to external links.##### Return value
A string of HTML with links converted to external links.
##### Usage and example
`
js
import { makeLinksExternal } from "react-table-of-content";const html =
About Contact;const newHtml = makeLinksExternal(html);
console.log(newHtml);
// Output:
// About
// Contact
`
####
readTime
It's a function that calculates the read time of a string of text.
##### Arguments
Accepts 1 argument of type
string
containing the text to calculate the read time.##### Return value
An
object
with minutes
property of type number
in minutes and a readTime
property describing the number in words e.g. "1 min read".##### Usage and example
`
js
import { readTime } from "react-table-of-content";const text =
"This is a string of text that will be used to calculate the read time.";
const time = readTime(text);
console.log(time);
// Output:
// { minutes: 1, readTime: "1 min read" }
`
Testing
Unit and integration tests are written using Jest and React Testing Library. To run the tests, use the command below:
`
bash
npm run test
`
You can mock the package in your tests like so:
`
js
jest.mock("react-table-of-content", () => ({
addIdToHeadingTags: jest.fn((content) => content),
useTableOfContent: jest.fn(() => ({
headingLinks: [
{
id: "id",
title: "title",
tagName: "h1",
},
],
contentIsActive: jest.fn(() => true),
})),
makeLinksExternal: jest.fn((content) => content),
}));
``
License
MIT
Author
Precious OSSAI
Developer Website