Skip to content

Commit

Permalink
Add active link classes to site navigation menu (#463)
Browse files Browse the repository at this point in the history
  • Loading branch information
microbouji authored and JoelMarcey committed Mar 4, 2018
1 parent 4ea8158 commit 48ee457
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 15 deletions.
12 changes: 12 additions & 0 deletions docs/guides-navigation.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,15 @@ headerLinks: [
{ doc: 'bar', label: 'Bar' },
],
```

## Active Links In Site Navigation Bar

The links in the top navigation bar get `siteNavItemActive` and `siteNavGroupActive` class names to allow you to style the currently active link different from the others. `siteNavItemActive` is applied when there's an exact match between the navigation link and the currently displayed web page.

> This does not include links of type `href` which are meant for external links only. If you manually set an `href` in your headerLinks to an internal page, document, or blog post, it will not get the `siteNavItemActive` class even if that page is being displayed.
`siteNavGroupActive` will be added to these links:
* `doc` links that belong to the same sidebar as the currently displayed document
* The blog link when a blog post, or the blog listing page is being displayed

These are two separate class names so you can have the active styles applied to either exact matches only or a bit more broadly for docs that belong together. If you don't want to make this distinction you can add both classes to the same css rule.
6 changes: 5 additions & 1 deletion lib/core/BlogPageLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ class BlogPageLayout extends React.Component {
const perPage = this.props.metadata.perPage;
const page = this.props.metadata.page;
return (
<Site title="Blog" language="en" config={this.props.config}>
<Site
title="Blog"
language="en"
config={this.props.config}
metadata={{blog: true, blogListing: true}}>
<div className="docMainWrapper wrapper">
<BlogSidebar
language={this.props.language}
Expand Down
3 changes: 2 additions & 1 deletion lib/core/BlogPostLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ class BlogPostLayout extends React.Component {
title={this.props.metadata.title}
language={'en'}
description={this.getDescription()}
config={this.props.config}>
config={this.props.config}
metadata={{blog: true}}>
<div className="docMainWrapper wrapper">
<BlogSidebar
language={'en'}
Expand Down
3 changes: 2 additions & 1 deletion lib/core/DocsLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class DocsLayout extends React.Component {
}
description={content.trim().split('\n')[0]}
language={metadata.language}
version={metadata.version}>
version={metadata.version}
metadata={metadata}>
<div className="docMainWrapper wrapper">
<DocsSidebar metadata={metadata} />
<Container className="mainContainer">
Expand Down
1 change: 1 addition & 0 deletions lib/core/Site.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class Site extends React.Component {
title={this.props.config.title}
language={this.props.language}
version={this.props.version}
current={this.props.metadata}
/>
<div className="navPusher">
{this.props.children}
Expand Down
21 changes: 20 additions & 1 deletion lib/core/nav/HeaderNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const CWD = process.cwd();

const React = require('react');
const fs = require('fs');
const classNames = require('classnames');
const siteConfig = require(CWD + '/siteConfig.js');
const translation = require('../../server/translation.js');
const env = require('../../server/env.js');
Expand Down Expand Up @@ -97,6 +98,8 @@ class HeaderNav extends React.Component {
// function to generate each header link, used with each object in siteConfig.headerLinks
makeLinks(link) {
let href;
let docItemActive = false;
let docGroupActive = false;
if (link.search && this.props.config.algolia) {
// return algolia search bar
return (
Expand Down Expand Up @@ -153,6 +156,10 @@ class HeaderNav extends React.Component {
throw new Error(errorStr);
}
href = this.props.config.baseUrl + Metadata[id].permalink;

const {id: currentID, sidebar} = this.props.current;
docItemActive = currentID && currentID === id;
docGroupActive = sidebar && sidebar === Metadata[id].sidebar;
} else if (link.page) {
// set link to page with current page's language if appropriate
const language = this.props.language || '';
Expand All @@ -172,8 +179,16 @@ class HeaderNav extends React.Component {
// set link to blog url
href = this.props.baseUrl + 'blog';
}
const itemClasses = classNames({
siteNavGroupActive:
(link.doc && docGroupActive) || (link.blog && this.props.current.blog),
siteNavItemActive:
docItemActive ||
(link.blog && this.props.current.blogListing) ||
(link.page && link.page === this.props.current.id),
});
return (
<li key={link.label + 'page'}>
<li key={link.label + 'page'} className={itemClasses}>
<a href={href} target={link.external ? '_blank' : '_self'}>
{translation[this.props.language]
? translation[this.props.language]['localized-strings'][link.label]
Expand Down Expand Up @@ -279,4 +294,8 @@ class HeaderNav extends React.Component {
}
}

HeaderNav.defaultProps = {
current: {},
};

module.exports = HeaderNav;
14 changes: 10 additions & 4 deletions lib/server/generate.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ function execute() {
files.forEach(file => {
// render .js files to strings
if (file.match(/\.js$/)) {
const pageID = path.basename(file, '.js');

// make temp file for sake of require paths
const parts = file.split('pages');
let tempFile = join(__dirname, '..', 'pages', parts[1]);
Expand Down Expand Up @@ -439,7 +441,10 @@ function execute() {
}
translate.setLanguage(language);
const str = renderToStaticMarkup(
<Site language={language} config={siteConfig}>
<Site
language={language}
config={siteConfig}
metadata={{id: pageID}}>
<ReactComp language={language} />
</Site>
);
Expand All @@ -454,7 +459,7 @@ function execute() {
let language = env.translation.enabled ? 'en' : '';
translate.setLanguage(language);
const str = renderToStaticMarkup(
<Site language={language} config={siteConfig}>
<Site language={language} config={siteConfig} metadata={{id: pageID}}>
<ReactComp language={language} />
</Site>
);
Expand All @@ -464,18 +469,19 @@ function execute() {
let language = env.translation.enabled ? 'en' : '';
translate.setLanguage(language);
const str = renderToStaticMarkup(
<Site language={language} config={siteConfig}>
<Site language={language} config={siteConfig} metadata={{id: pageID}}>
<ReactComp language={language} />
</Site>
);
writeFileAndCreateFolder(targetFile.replace('/en/', '/'), str);
}
fs.removeSync(tempFile);
} else if (siteConfig.wrapPagesHTML && file.match(/\.html$/)) {
const pageID = path.basename(file, '.html');
const parts = file.split('pages');
const targetFile = join(buildDir, parts[1]);
const str = renderToStaticMarkup(
<Site language="en" config={siteConfig}>
<Site language="en" config={siteConfig} metadata={{id: pageID}}>
<div
dangerouslySetInnerHTML={{
__html: fs.readFileSync(file, {encoding: 'utf8'}),
Expand Down
10 changes: 8 additions & 2 deletions lib/server/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,10 @@ function execute(port) {
removeModuleAndChildrenFromCache('../core/Site.js');
const Site = require('../core/Site.js');
const str = renderToStaticMarkup(
<Site language="en" config={siteConfig}>
<Site
language="en"
config={siteConfig}
metadata={{id: path.basename(htmlFile, '.html')}}>
<div
dangerouslySetInnerHTML={{
__html: fs.readFileSync(htmlFile, {encoding: 'utf8'}),
Expand Down Expand Up @@ -434,7 +437,10 @@ function execute(port) {
const Site = require('../core/Site.js');
translate.setLanguage(language);
const str = renderToStaticMarkup(
<Site language={language} config={siteConfig}>
<Site
language={language}
config={siteConfig}
metadata={{id: path.basename(userFile, '.js')}}>
<ReactComp language={language} />
</Site>
);
Expand Down
11 changes: 6 additions & 5 deletions lib/static/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,9 @@ pre code {
font-size: 0.9em;
}
.navigationSlider .slidingNav ul li a:focus,
.navigationSlider .slidingNav ul li a:hover {
.navigationSlider .slidingNav ul li a:hover,
.navigationSlider .slidingNav ul li.siteNavItemActive a,
.navigationSlider .slidingNav ul li.siteNavGroupActive a {
background: $primaryColor;
}

Expand Down Expand Up @@ -1195,10 +1197,9 @@ ul#languages li {
height: 32px;
font-size: 1em;
}
.navigationSlider .slidingNav ul li a:hover {
color: #fff;
}
.navigationSlider .slidingNav ul li.navItemActive a {
.navigationSlider .slidingNav ul li a:hover,
.navigationSlider .slidingNav ul li.siteNavItemActive a,
.navigationSlider .slidingNav ul li.siteNavGroupActive a {
color: #fff;
}
}
Expand Down

0 comments on commit 48ee457

Please sign in to comment.