Skip to content

Commit 1e3ca89

Browse files
authored
feat: Indicate top-level navigation (#10867)
1 parent 9bdfba3 commit 1e3ca89

File tree

11 files changed

+501
-469
lines changed

11 files changed

+501
-469
lines changed

src/components/dynamicNav.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {Fragment} from 'react';
33
import {serverContext} from 'sentry-docs/serverContext';
44
import {sortPages} from 'sentry-docs/utils';
55

6+
import {NavChevron} from './sidebar/navChevron';
67
import {SidebarLink} from './sidebarLink';
78
import {SmartLink} from './smartLink';
89

@@ -111,6 +112,7 @@ type Props = {
111112
showDepth?: number;
112113
suppressMissing?: boolean;
113114
title?: string;
115+
withChevron?: boolean;
114116
};
115117

116118
export function DynamicNav({
@@ -124,6 +126,7 @@ export function DynamicNav({
124126
suppressMissing = false,
125127
noHeadingLink = false,
126128
headerClassName,
129+
withChevron = false,
127130
}: Props) {
128131
if (root.startsWith('/')) {
129132
root = root.substring(1);
@@ -161,11 +164,12 @@ export function DynamicNav({
161164
parentNode && !noHeadingLink ? (
162165
<SmartLink
163166
to={`/${root}/`}
164-
className={`${headerClassName} ${path.join('/') === root ? 'active' : ''}`}
167+
className={`${headerClassName} ${path.join('/') === root ? 'active' : ''} justify-between`}
165168
activeClassName="active"
166169
data-sidebar-link
167170
>
168171
<h6>{title}</h6>
172+
{withChevron && <NavChevron direction={isActive ? 'down' : 'right'} />}
169173
</SmartLink>
170174
) : (
171175
<div className={headerClassName} data-sidebar-link>
@@ -177,7 +181,7 @@ export function DynamicNav({
177181
<li className="mb-3" data-sidebar-branch>
178182
{header}
179183
{(!collapse || isActive) && entity.children && (
180-
<ul data-sidebar-tree>
184+
<ul data-sidebar-tree className="pl-3">
181185
{prependLinks &&
182186
prependLinks.map(link => (
183187
<SidebarLink to={link[0]} key={link[0]} title={link[1]} path={linkPath} />
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import {Fragment} from 'react';
2+
import {Link} from 'react-feather';
3+
4+
import styles from './style.module.scss';
5+
6+
import {NavChevron} from './navChevron';
7+
import {DefaultSidebarProps, SidebarNode} from './types';
8+
9+
export function DefaultSidebar({node, path}: DefaultSidebarProps) {
10+
const activeClassName = (n: SidebarNode, baseClassName = '') => {
11+
const className = n.path === path.join('/') ? 'active' : '';
12+
return `${baseClassName} ${className}`;
13+
};
14+
15+
const renderChildren = (children: SidebarNode[]) =>
16+
children && (
17+
<ul data-sidebar-tree>
18+
{children
19+
.filter(n => n.frontmatter.sidebar_title || n.frontmatter.title)
20+
.map(n => (
21+
<li className="toc-item" key={n.path} data-sidebar-branch>
22+
<Link
23+
href={'/' + n.path}
24+
data-sidebar-link
25+
className={activeClassName(n, 'flex items-center justify-between gap-1')}
26+
>
27+
{n.frontmatter.sidebar_title || n.frontmatter.title}
28+
{n.children.length > 0 && <NavChevron direction="down" />}
29+
</Link>
30+
{renderChildren(n.children)}
31+
</li>
32+
))}
33+
</ul>
34+
);
35+
36+
return (
37+
<ul data-sidebar-tree>
38+
<li className="mb-3" data-sidebar-branch>
39+
<Fragment>
40+
<Link
41+
href={'/' + node.path}
42+
data-active={node.path === path.join('/')}
43+
className={activeClassName(
44+
node,
45+
[styles['sidebar-title'], 'flex items-center justify-between gap-1'].join(
46+
' '
47+
)
48+
)}
49+
data-sidebar-link
50+
key={node.path}
51+
>
52+
<h6>{node.frontmatter.sidebar_title || node.frontmatter.title}</h6>
53+
</Link>
54+
{renderChildren(node.children)}
55+
</Fragment>
56+
</li>
57+
</ul>
58+
);
59+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import {DocNode, nodeForPath} from 'sentry-docs/docTree';
2+
3+
import styles from './style.module.scss';
4+
5+
import {DynamicNav, toTree} from '../dynamicNav';
6+
import {SidebarLink} from '../sidebarLink';
7+
8+
import {NavNode} from './types';
9+
import {docNodeToNavNode, getNavNodes} from './utils';
10+
11+
const devDocsMenuItems: {root: string; title: string; hideChevron?: boolean}[] = [
12+
{root: 'getting-started', title: 'Getting Started', hideChevron: true},
13+
{root: 'development', title: 'Development'},
14+
{root: 'application', title: 'Application'},
15+
{root: 'frontend', title: 'Frontend'},
16+
{root: 'backend', title: 'Backend'},
17+
{root: 'sdk', title: 'SDK Development'},
18+
{root: 'services', title: 'Services'},
19+
{root: 'integrations', title: 'Integrations'},
20+
{root: 'self-hosted', title: 'Self-Hosted Sentry'},
21+
];
22+
23+
export function DevelopDocsSidebar({
24+
path,
25+
rootNode,
26+
sidebarToggleId,
27+
headerClassName,
28+
}: {
29+
headerClassName: string;
30+
path: string;
31+
rootNode: DocNode;
32+
sidebarToggleId: string;
33+
}) {
34+
const getNavTree = (root: string) => {
35+
const apiNodes: NavNode[] = getNavNodes(
36+
[nodeForPath(rootNode, root)!],
37+
docNodeToNavNode
38+
);
39+
return toTree(apiNodes);
40+
};
41+
return (
42+
<aside className={styles.sidebar}>
43+
<input type="checkbox" id={sidebarToggleId} className="hidden" />
44+
<style>{':root { --sidebar-width: 300px; }'}</style>
45+
<div className="md:flex flex-col items-stretch">
46+
<div className={styles.toc}>
47+
<ul data-sidebar-tree>
48+
{devDocsMenuItems.map(({root, title, hideChevron}) => (
49+
<DynamicNav
50+
key={root}
51+
root={root}
52+
title={title}
53+
tree={getNavTree(root)}
54+
headerClassName={headerClassName}
55+
collapse
56+
withChevron={!hideChevron}
57+
/>
58+
))}
59+
</ul>
60+
<hr />
61+
<ul data-sidebar-tree>
62+
<SidebarLink
63+
to="https://open.sentry.io/code-of-conduct/"
64+
title="Code of Conduct"
65+
path={path}
66+
/>
67+
<SidebarLink
68+
to="https://docs.sentry.io"
69+
title="User Documentation"
70+
path={path}
71+
/>
72+
</ul>
73+
</div>
74+
</div>
75+
</aside>
76+
);
77+
}

0 commit comments

Comments
 (0)