2018-11-08 10:44:46 +01:00
|
|
|
import React, { Component } from 'react'
|
|
|
|
import PropTypes from 'prop-types'
|
|
|
|
import { Link } from 'gatsby'
|
2019-03-29 16:32:23 +01:00
|
|
|
import { ReactComponent as External } from '../images/external.svg'
|
2018-11-08 10:44:46 +01:00
|
|
|
import styles from './Sidebar.module.scss'
|
|
|
|
|
|
|
|
const SidebarLink = ({ link, title, linkClasses }) => {
|
|
|
|
if (link) {
|
|
|
|
if (link.match(/^\s?http(s?)/gi)) {
|
|
|
|
return (
|
2018-11-23 15:08:58 +01:00
|
|
|
<a
|
|
|
|
href={link}
|
|
|
|
className={linkClasses}
|
|
|
|
target="_blank"
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
>
|
2019-03-29 16:32:23 +01:00
|
|
|
{title} <External className={styles.external} />
|
2018-11-08 10:44:46 +01:00
|
|
|
</a>
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
return (
|
|
|
|
<Link to={link} className={linkClasses}>
|
|
|
|
{title}
|
|
|
|
</Link>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
} else {
|
2018-11-08 11:21:20 +01:00
|
|
|
return title
|
2018-11-08 10:44:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-23 15:08:58 +01:00
|
|
|
SidebarLink.propTypes = {
|
|
|
|
link: PropTypes.string.isRequired,
|
|
|
|
title: PropTypes.string.isRequired,
|
|
|
|
linkClasses: PropTypes.string
|
|
|
|
}
|
|
|
|
|
2019-01-28 11:42:32 +01:00
|
|
|
const SidebarList = ({ items, location, toc, tocComponent }) => (
|
2018-11-23 15:08:58 +01:00
|
|
|
<div className={styles.list}>
|
|
|
|
{toc ? (
|
2019-01-28 11:42:32 +01:00
|
|
|
<div className={styles.toc}>{tocComponent}</div>
|
2018-11-23 15:08:58 +01:00
|
|
|
) : (
|
|
|
|
<ul>
|
|
|
|
{items.map((item, j) => (
|
|
|
|
<li key={j}>
|
|
|
|
<SidebarLink
|
|
|
|
link={item.link}
|
|
|
|
title={item.title}
|
|
|
|
linkClasses={
|
|
|
|
item.link === location.pathname
|
|
|
|
? styles.active
|
|
|
|
: styles.link
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</li>
|
|
|
|
))}
|
|
|
|
</ul>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
|
|
|
|
SidebarList.propTypes = {
|
|
|
|
items: PropTypes.array.isRequired,
|
|
|
|
location: PropTypes.object.isRequired,
|
|
|
|
toc: PropTypes.bool,
|
2019-01-28 11:42:32 +01:00
|
|
|
tocComponent: PropTypes.object
|
2018-11-23 15:08:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const SidebarGroupTitle = ({ group }) => (
|
|
|
|
<h4 className={styles.groupTitle}>
|
|
|
|
{group.items[0].link ? (
|
|
|
|
<SidebarLink
|
|
|
|
link={group.items[0].link}
|
|
|
|
title={group.group}
|
|
|
|
linkClasses={styles.groupTitleLink}
|
|
|
|
/>
|
|
|
|
) : (
|
|
|
|
group.group
|
|
|
|
)}
|
|
|
|
</h4>
|
|
|
|
)
|
|
|
|
|
|
|
|
SidebarGroupTitle.propTypes = {
|
|
|
|
group: PropTypes.object.isRequired
|
|
|
|
}
|
|
|
|
|
|
|
|
const SidebarGroup = ({ i, group, location, ...props }) => (
|
|
|
|
<>
|
|
|
|
<SidebarGroupTitle group={group} />
|
|
|
|
<SidebarList
|
|
|
|
key={i}
|
|
|
|
items={group.items}
|
|
|
|
location={location}
|
|
|
|
{...props}
|
|
|
|
/>
|
|
|
|
</>
|
2018-11-08 10:44:46 +01:00
|
|
|
)
|
|
|
|
|
2019-01-31 11:42:50 +01:00
|
|
|
SidebarGroup.propTypes = {
|
|
|
|
i: PropTypes.number,
|
|
|
|
group: PropTypes.object,
|
|
|
|
location: PropTypes.object
|
|
|
|
}
|
|
|
|
|
2018-11-08 10:44:46 +01:00
|
|
|
export default class Sidebar extends Component {
|
|
|
|
static propTypes = {
|
|
|
|
sidebar: PropTypes.string,
|
2018-11-23 13:49:53 +01:00
|
|
|
location: PropTypes.object.isRequired,
|
2018-11-23 15:08:58 +01:00
|
|
|
collapsed: PropTypes.bool,
|
2018-11-23 13:49:53 +01:00
|
|
|
toc: PropTypes.bool,
|
2019-01-28 11:42:32 +01:00
|
|
|
tocComponent: PropTypes.element
|
2018-11-08 10:44:46 +01:00
|
|
|
}
|
|
|
|
|
2018-11-23 15:08:58 +01:00
|
|
|
static defaultProps = { location: { pathname: '/' } }
|
2018-11-08 10:44:46 +01:00
|
|
|
|
|
|
|
render() {
|
2019-01-28 11:42:32 +01:00
|
|
|
const { sidebar, location, collapsed, toc, tocComponent } = this.props
|
2018-11-08 11:21:20 +01:00
|
|
|
|
2018-11-23 15:08:58 +01:00
|
|
|
if (sidebar) {
|
|
|
|
try {
|
|
|
|
var sidebarfile = require(`../../data/sidebars/${sidebar}.yml`) // eslint-disable-line
|
|
|
|
} catch (e) {
|
|
|
|
throw e
|
|
|
|
}
|
|
|
|
}
|
2018-11-08 10:44:46 +01:00
|
|
|
|
|
|
|
if (!sidebarfile) {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2018-11-08 13:21:39 +01:00
|
|
|
<nav className={styles.sidebar}>
|
2018-11-23 15:08:58 +01:00
|
|
|
{sidebarfile.map((group, i) => (
|
|
|
|
<div key={i}>
|
|
|
|
{collapsed ? (
|
|
|
|
group.items.some(
|
|
|
|
item => item.link === location.pathname
|
|
|
|
) ? (
|
|
|
|
<SidebarGroup
|
|
|
|
i={i}
|
|
|
|
group={group}
|
|
|
|
location={location}
|
|
|
|
toc={toc}
|
2019-01-28 11:42:32 +01:00
|
|
|
tocComponent={tocComponent}
|
2018-11-23 15:08:58 +01:00
|
|
|
/>
|
|
|
|
) : (
|
|
|
|
<SidebarGroupTitle group={group} />
|
|
|
|
)
|
|
|
|
) : (
|
|
|
|
<SidebarGroup
|
|
|
|
i={i}
|
|
|
|
group={group}
|
2018-11-23 13:49:53 +01:00
|
|
|
location={location}
|
|
|
|
/>
|
2018-11-23 15:08:58 +01:00
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
))}
|
2018-11-08 10:44:46 +01:00
|
|
|
</nav>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|