forked from newrelic/docs-website
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTableOfContents.js
More file actions
120 lines (106 loc) · 3.32 KB
/
Copy pathTableOfContents.js
File metadata and controls
120 lines (106 loc) · 3.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import { css } from '@emotion/react';
import { graphql } from 'gatsby';
import { useMedia } from 'react-use';
import { Icon, PageTools } from '@newrelic/gatsby-theme-newrelic';
import useActiveHash from '../hooks/useActiveHash';
import GithubSlugger from 'github-slugger';
import { parseHeading } from '../../plugins/gatsby-remark-custom-heading-ids/utils/heading';
const prop = (name) => (obj) => obj[name];
const TableOfContents = ({ page }) => {
const { mdxAST } = page;
const headings = useMemo(() => {
const slugs = new GithubSlugger();
return mdxAST.children
.filter(
(node) =>
node.type === 'heading' &&
node.depth === 2 &&
node.children.length > 0
)
.map((heading) => {
const { id, text } = parseHeading(heading);
return { id: id || slugs.slug(text), text };
});
}, [mdxAST]);
const headingIds = useMemo(() => headings.map(prop('id')), [headings]);
const activeHash = useActiveHash(headingIds);
const isMobileScreen = useMedia('(max-width: 1240px)');
return headings.length === 0 ? null : (
<PageTools.Section>
<PageTools.Title>On this page</PageTools.Title>
<nav
css={css`
max-height: 60vh;
overflow-y: auto;
`}
>
<ul
css={css`
list-style: none;
padding: 0;
margin: 0;
`}
>
{headings.map(({ id, text }) => {
const isActive = activeHash === id;
return (
<li
key={id}
css={css`
margin: 0;
`}
>
<a
href={`#${id}`}
className={isActive && !isMobileScreen ? 'active' : null}
css={css`
display: flex;
align-items: center;
border-radius: 0.25rem;
font-size: 0.875rem;
padding: 0.5rem 0;
color: var(--primary-text-color);
transition: color 0.2s ease-out;
text-decoration: none;
&.active {
background: var(--primary-hover-color);
padding-left: 0.5rem;
padding-right: 0.5rem;
.dark-mode & {
background: var(
--system-background-selected-low-contrast-dark
);
}
}
`}
>
<Icon
name="fe-arrow-left"
css={css`
display: ${isActive && !isMobileScreen
? 'inline-block'
: 'none'};
margin-right: 0.5rem;
`}
/>
{text}
</a>
</li>
);
})}
</ul>
</nav>
</PageTools.Section>
);
};
TableOfContents.propTypes = {
page: PropTypes.shape({ mdxAST: PropTypes.object }).isRequired,
};
export const query = graphql`
fragment TableOfContents_page on Mdx {
mdxAST
}
`;
export default TableOfContents;