Skip to content

Commit

Permalink
feat(v2): add toc to blog posts (#3274)
Browse files Browse the repository at this point in the history
* refactor TOC into own component

* make layout consistent across blog pages
  • Loading branch information
amy-lei committed Aug 17, 2020
1 parent 3ef965b commit 473d263
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import React from 'react';
import Layout from '@theme/Layout';
import BlogPostItem from '@theme/BlogPostItem';
import BlogPostPaginator from '@theme/BlogPostPaginator';
import TOC from '@theme/TOC';

function BlogPostPage(props): JSX.Element {
const {content: BlogPostContents} = props;
const {frontMatter, metadata} = BlogPostContents;
const {title, description, nextItem, prevItem, editUrl} = metadata;
const {hide_table_of_contents: hideTableOfContents} = frontMatter;

return (
<Layout title={title} description={description}>
Expand Down Expand Up @@ -55,6 +57,11 @@ function BlogPostPage(props): JSX.Element {
</div>
)}
</div>
{!hideTableOfContents && BlogPostContents.rightToc && (
<div className="col col--2">
<TOC headings={BlogPostContents.rightToc} />
</div>
)}
</div>
</div>
)}
Expand Down
47 changes: 4 additions & 43 deletions packages/docusaurus-theme-classic/src/theme/DocItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,53 +11,12 @@ import Head from '@docusaurus/Head';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import useBaseUrl from '@docusaurus/useBaseUrl';
import DocPaginator from '@theme/DocPaginator';
import useTOCHighlight from '@theme/hooks/useTOCHighlight';
import DocVersionSuggestions from '@theme/DocVersionSuggestions';
import TOC from '@theme/TOC';

import clsx from 'clsx';
import styles from './styles.module.css';

const LINK_CLASS_NAME = 'table-of-contents__link';
const ACTIVE_LINK_CLASS_NAME = 'table-of-contents__link--active';
const TOP_OFFSET = 100;

function DocTOC({headings}) {
useTOCHighlight(LINK_CLASS_NAME, ACTIVE_LINK_CLASS_NAME, TOP_OFFSET);
return (
<div className="col col--3">
<div className={styles.tableOfContents}>
<Headings headings={headings} />
</div>
</div>
);
}

/* eslint-disable jsx-a11y/control-has-associated-label */
function Headings({headings, isChild}: {headings; isChild?: boolean}) {
if (!headings.length) {
return null;
}
return (
<ul
className={
isChild ? '' : 'table-of-contents table-of-contents__left-border'
}>
{headings.map((heading) => (
<li key={heading.id}>
<a
href={`#${heading.id}`}
className={LINK_CLASS_NAME}
// Developer provided the HTML, so assume it's safe.
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{__html: heading.value}}
/>
<Headings isChild headings={heading.children} />
</li>
))}
</ul>
);
}

function DocItem(props): JSX.Element {
const {siteConfig = {}} = useDocusaurusContext();
const {url: siteUrl, title: siteTitle} = siteConfig;
Expand Down Expand Up @@ -202,7 +161,9 @@ function DocItem(props): JSX.Element {
</div>
</div>
{!hideTableOfContents && DocContent.rightToc && (
<DocTOC headings={DocContent.rightToc} />
<div className="col col--3">
<TOC headings={DocContent.rightToc} />
</div>
)}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,7 @@
}
}

.tableOfContents {
display: inherit;
max-height: calc(100vh - (var(--ifm-navbar-height) + 2rem));
overflow-y: auto;
position: sticky;
top: calc(var(--ifm-navbar-height) + 2rem);
}

.tableOfContents::-webkit-scrollbar {
width: 7px;
}

.tableOfContents::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}

.tableOfContents::-webkit-scrollbar-thumb {
background: #888;
border-radius: 10px;
}

.tableOfContents::-webkit-scrollbar-thumb:hover {
background: #555;
}

@media only screen and (max-width: 996px) {
.tableOfContents {
display: none;
}

.docItemContainer {
padding: 0 0.3rem;
}
Expand Down
52 changes: 52 additions & 0 deletions packages/docusaurus-theme-classic/src/theme/TOC/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import React from 'react';

import useTOCHighlight from '@theme/hooks/useTOCHighlight';
import styles from './styles.module.css';

const LINK_CLASS_NAME = 'table-of-contents__link';
const ACTIVE_LINK_CLASS_NAME = 'table-of-contents__link--active';
const TOP_OFFSET = 100;

/* eslint-disable jsx-a11y/control-has-associated-label */
function Headings({headings, isChild}: {headings; isChild?: boolean}) {
if (!headings.length) {
return null;
}
return (
<ul
className={
isChild ? '' : 'table-of-contents table-of-contents__left-border'
}>
{headings.map((heading) => (
<li key={heading.id}>
<a
href={`#${heading.id}`}
className={LINK_CLASS_NAME}
// Developer provided the HTML, so assume it's safe.
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{__html: heading.value}}
/>
<Headings isChild headings={heading.children} />
</li>
))}
</ul>
);
}

function TOC({headings}) {
useTOCHighlight(LINK_CLASS_NAME, ACTIVE_LINK_CLASS_NAME, TOP_OFFSET);
return (
<div className={styles.tableOfContents}>
<Headings headings={headings} />
</div>
);
}

export default TOC;
43 changes: 43 additions & 0 deletions packages/docusaurus-theme-classic/src/theme/TOC/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

.tableOfContents {
display: inherit;
max-height: calc(100vh - (var(--ifm-navbar-height) + 2rem));
overflow-y: auto;
position: sticky;
top: calc(var(--ifm-navbar-height) + 2rem);
}

.tableOfContents::-webkit-scrollbar {
width: 7px;
}

.tableOfContents::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}

.tableOfContents::-webkit-scrollbar-thumb {
background: #888;
border-radius: 10px;
}

.tableOfContents::-webkit-scrollbar-thumb:hover {
background: #555;
}

@media only screen and (max-width: 996px) {
.tableOfContents {
display: none;
}

.docItemContainer {
padding: 0 0.3rem;
}
}

2 changes: 2 additions & 0 deletions website/docs/blog.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ author_image_url: https://graph.facebook.com/611217057/picture/?height=200&width
tags: [hello, docusaurus-v2]
description: This is my first post on Docusaurus 2.
image: https://i.imgur.com/mErPwqL.png
hide_table_of_contents: false
---
Welcome to this blog. This blog is created with [**Docusaurus 2 alpha**](https://v2.docusaurus.io/).

Expand All @@ -63,6 +64,7 @@ The only required field is `title`; however, we provide options to add author in
- `draft` - A boolean flag to indicate that the blog post is work-in-progress and therefore should not be published yet. However, draft blog posts will be displayed during development.
- `description`: The description of your post, which will become the `<meta name="description" content="..."/>` and `<meta property="og:description" content="..."/>` in `<head>`, used by search engines. If this field is not present, it will default to the first line of the contents.
- `image`: Cover or thumbnail image that will be used when displaying the link to your post.
- `hide_table_of_contents`: Whether to hide the table of contents to the right. By default it is `false`.

## Summary truncation

Expand Down

0 comments on commit 473d263

Please sign in to comment.