style(v2): basic sidebar component (#1020)

This commit is contained in:
Yangshun Tay 2018-10-07 01:23:41 -07:00 committed by Endilie Yacop Sucipto
parent aae5c4dc85
commit 2e9656917c
7 changed files with 110 additions and 48 deletions

View file

@ -13,11 +13,12 @@ module.exports = {
rules: {
'no-console': OFF,
'func-names': OFF,
'react/jsx-closing-bracket-location': OFF, // Conflicts with Prettier.
'react/jsx-filename-extension': OFF,
'react/jsx-one-expression-per-line': OFF,
'react/prop-types': OFF,
'react/destructuring-assignment': OFF, // too many lines
'import/no-unresolved': WARNING, // because it couldn't resolve webpack alias
'react/destructuring-assignment': OFF, // Too many lines.
'import/no-unresolved': WARNING, // Because it couldn't resolve webpack alias.
'react/prefer-stateless-function': WARNING,
},
};

View file

@ -3,50 +3,13 @@ import React from 'react';
import {Link} from 'react-router-dom';
import Helmet from 'react-helmet';
import Layout from '@theme/Layout'; // eslint-disable-line
import DocsPaginator from '@theme/DocsPaginator'; // eslint-disable-line
import Layout from '@theme/Layout'; // eslint-disable-line
import Sidebar from '@theme/Sidebar'; // eslint-disable-line
import styles from './styles.css';
export default class Docs extends React.Component {
renderSidebar(metadata, docsSidebars, docsMetadatas) {
const {sidebar, language, id: thisID} = metadata;
if (!sidebar || !docsSidebars) {
return null;
}
const thisSidebar = docsSidebars[sidebar];
return (
thisSidebar &&
Object.keys(thisSidebar).map(categoryName => {
return (
<div className="navGroup" key={categoryName}>
<h3 className="navGroupCategoryTitle">{categoryName}</h3>
<ul>
{thisSidebar[categoryName].map(rawLinkID => {
const linkID = (language ? `${language}-` : '') + rawLinkID;
const linkMetadata = docsMetadatas[linkID];
if (!linkMetadata) {
throw new Error(
`Improper sidebars.json file, document with id '${linkID}' not found.`,
);
}
const linkClassName =
linkID === thisID ? 'navListItemActive' : 'navListItem';
return (
<li className={linkClassName} key={linkID}>
<Link className="navItem" to={linkMetadata.permalink}>
{linkMetadata.sidebar_label || linkMetadata.title}
</Link>
</li>
);
})}
</ul>
</div>
);
})
);
}
render() {
const {
route,
@ -64,9 +27,17 @@ export default class Docs extends React.Component {
{language && <meta name="docsearch:language" content={language} />}
{version && <meta name="docsearch:version" content={version} />}
</Helmet>
<div>{this.renderSidebar(metadata, docsSidebars, docsMetadatas)}</div>
<div className={styles.mainContainer}>{this.props.children}</div>
<DocsPaginator docsMetadatas={docsMetadatas} metadata={metadata} />
<div className={styles.mainContainer}>
<Sidebar
docsMetadatas={docsMetadatas}
docsSidebars={docsSidebars}
metadata={metadata}
/>
<div className={styles.docContent}>
{this.props.children}
<DocsPaginator docsMetadatas={docsMetadatas} metadata={metadata} />
</div>
</div>
</Layout>
);
}

View file

@ -1,10 +1,13 @@
.mainContainer {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-top: 40px;
margin-bottom: 30px;
margin-left: auto;
margin-right: auto;
justify-content: center;
}
margin-top: 40px;
justify-content: space-between;
}
.docContent {
flex-grow: 1;
}

View file

@ -1,6 +1,8 @@
import React from 'react';
import Footer from '@theme/Footer'; // eslint-disable-line
import './styles.css';
/* eslint-disable react/prefer-stateless-function */
export default class Layout extends React.Component {
render() {

View file

@ -0,0 +1,4 @@
:global(body) {
margin: 0;
padding: 0;
}

View file

@ -0,0 +1,51 @@
import React from 'react';
import {Link} from 'react-router-dom';
import classnames from 'classnames';
import styles from './styles.css';
function Sidebar(props) {
const {metadata, docsSidebars, docsMetadatas} = props;
const {sidebar, language, id: thisID} = metadata;
if (!sidebar || !docsSidebars) {
return null;
}
const thisSidebar = docsSidebars[sidebar];
return (
thisSidebar && (
<div className={styles.sidebar}>
{Object.keys(thisSidebar).map(categoryName => (
<div className={styles.sidebarGroup} key={categoryName}>
<h3 className={styles.sidebarGroupTitle}>{categoryName}</h3>
<ul className={styles.sidebarList}>
{thisSidebar[categoryName].map(rawLinkID => {
const linkID = (language ? `${language}-` : '') + rawLinkID;
const linkMetadata = docsMetadatas[linkID];
if (!linkMetadata) {
throw new Error(
`Improper sidebars.json file, document with id '${linkID}' not found.`,
);
}
const activeItem = linkID === thisID;
return (
<li key={linkID}>
<Link
className={classnames(styles.sidebarLink, {
[styles.sidebarLinkActive]: activeItem,
})}
to={linkMetadata.permalink}>
{linkMetadata.sidebar_label || linkMetadata.title}
</Link>
</li>
);
})}
</ul>
</div>
))}
</div>
)
);
}
export default Sidebar;

View file

@ -0,0 +1,30 @@
.sidebar {
width: 300px;
padding: 0 20px;
}
.sidebarGroup {
margin-bottom: 20px;
}
.sidebarGroupTitle {
margin: 0;
}
.sidebarList {
list-style-type: none;
padding-left: 0;
}
.sidebarLink {
color: #717171;
display: block;
padding: 8px 0;
text-decoration: none;
transition: color .3s;
}
.sidebarLink:hover,
.sidebarLinkActive {
color: #2e8555;
}