fix(client): scroll top and focus an article on guide navigation
This commit is contained in:
@ -29,7 +29,16 @@ const propTypes = {
|
||||
location: PropTypes.object
|
||||
};
|
||||
|
||||
const Layout = ({ children }) => (
|
||||
class Layout extends React.Component {
|
||||
getContentRef = ref => (this.contentRef = ref);
|
||||
|
||||
handleNavigation = () => {
|
||||
this.contentRef.scrollTop = 0;
|
||||
this.contentRef.focus();
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<StaticQuery
|
||||
query={graphql`
|
||||
query LayoutQuery {
|
||||
@ -69,19 +78,24 @@ const Layout = ({ children }) => (
|
||||
>
|
||||
<SideNav
|
||||
expandedState={expandedState}
|
||||
onNavigate={this.handleNavigation}
|
||||
pages={pages}
|
||||
toggleDisplaySideNav={toggleDisplaySideNav}
|
||||
toggleExpandedState={toggleExpandedState}
|
||||
/>
|
||||
</Col>
|
||||
<Col
|
||||
className='content'
|
||||
md={8}
|
||||
smHidden={displaySideNav}
|
||||
xsHidden={displaySideNav}
|
||||
>
|
||||
<main className='main' id='main' tabIndex='-1'>
|
||||
{children}
|
||||
<main
|
||||
className='content'
|
||||
id='main'
|
||||
ref={this.getContentRef}
|
||||
tabIndex='-1'
|
||||
>
|
||||
{this.props.children}
|
||||
</main>
|
||||
</Col>
|
||||
</Row>
|
||||
@ -93,6 +107,8 @@ const Layout = ({ children }) => (
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Layout.displayName = 'Layout';
|
||||
Layout.propTypes = propTypes;
|
||||
|
@ -4,17 +4,23 @@ import Link from 'gatsby-link';
|
||||
|
||||
const propTypes = {
|
||||
isStubbed: PropTypes.bool,
|
||||
onNavigate: PropTypes.func.isRequired,
|
||||
path: PropTypes.string,
|
||||
router: PropTypes.object,
|
||||
title: PropTypes.string,
|
||||
toggleDisplaySideNav: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
function NavItem(props) {
|
||||
const { isStubbed, path, title } = props;
|
||||
class NavItem extends React.Component {
|
||||
handleClick = () => {
|
||||
this.props.toggleDisplaySideNav();
|
||||
this.props.onNavigate();
|
||||
};
|
||||
render() {
|
||||
const { isStubbed, path, title } = this.props;
|
||||
return (
|
||||
<li>
|
||||
<Link data-navitem='true' onClick={props.toggleDisplaySideNav} to={path}>
|
||||
<Link data-navitem='true' onClick={this.handleClick} to={path}>
|
||||
<span className={'navItemTitle' + (isStubbed ? ' stubbed' : '')}>
|
||||
{title}
|
||||
</span>
|
||||
@ -22,6 +28,7 @@ function NavItem(props) {
|
||||
</li>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
NavItem.displayName = 'NavItem';
|
||||
NavItem.propTypes = propTypes;
|
||||
|
@ -9,6 +9,7 @@ const propTypes = {
|
||||
handleClick: PropTypes.func.isRequired,
|
||||
hasChildren: PropTypes.bool,
|
||||
isExpanded: PropTypes.bool,
|
||||
onNavigate: PropTypes.func.isRequired,
|
||||
path: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
toggleDisplaySideNav: PropTypes.func.isRequired
|
||||
@ -52,9 +53,10 @@ class NavPanel extends Component {
|
||||
}
|
||||
|
||||
handleTitleClick() {
|
||||
const { path, toggleDisplaySideNav } = this.props;
|
||||
const { path, toggleDisplaySideNav, onNavigate } = this.props;
|
||||
toggleDisplaySideNav();
|
||||
navigate(path);
|
||||
onNavigate();
|
||||
}
|
||||
|
||||
renderHeader() {
|
||||
@ -94,8 +96,6 @@ class NavPanel extends Component {
|
||||
return (
|
||||
<Panel
|
||||
bsClass='panelStyle panel'
|
||||
collapsible={true}
|
||||
expanded={isExpanded}
|
||||
id={`${dashedName}-panel`}
|
||||
role='listitem'
|
||||
>
|
||||
|
@ -7,6 +7,7 @@ import NavItem from './NavItem';
|
||||
|
||||
const propTypes = {
|
||||
expandedState: PropTypes.object,
|
||||
onNavigate: PropTypes.func.isRequired,
|
||||
pages: PropTypes.arrayOf(PropTypes.object),
|
||||
parents: PropTypes.arrayOf(PropTypes.object),
|
||||
toggleDisplaySideNav: PropTypes.func.isRequired,
|
||||
@ -42,7 +43,9 @@ class SideNav extends Component {
|
||||
const [category] = pages.filter(page => page.path === path);
|
||||
const { title, hasChildren, dashedName } = category;
|
||||
|
||||
const children = this.renderChildren(childrenForParent, pages);
|
||||
const children = isExpanded
|
||||
? this.renderChildren(childrenForParent, pages)
|
||||
: null;
|
||||
return (
|
||||
<NavPanel
|
||||
dashedName={dashedName}
|
||||
@ -50,11 +53,12 @@ class SideNav extends Component {
|
||||
hasChildren={hasChildren}
|
||||
isExpanded={isExpanded}
|
||||
key={parent.path}
|
||||
onNavigate={this.props.onNavigate}
|
||||
path={parent.path}
|
||||
title={title}
|
||||
toggleDisplaySideNav={this.props.toggleDisplaySideNav}
|
||||
>
|
||||
{isExpanded ? children : null}
|
||||
{children}
|
||||
</NavPanel>
|
||||
);
|
||||
}
|
||||
@ -68,6 +72,7 @@ class SideNav extends Component {
|
||||
<NavItem
|
||||
isStubbed={child.isStubbed}
|
||||
key={child.path}
|
||||
onNavigate={this.props.onNavigate}
|
||||
path={child.path}
|
||||
title={child.title}
|
||||
toggleDisplaySideNav={this.props.toggleDisplaySideNav}
|
||||
|
@ -84,36 +84,6 @@
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* 404 */
|
||||
|
||||
.flexWrapper {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 50vh;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.verticalAlign {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.button {
|
||||
color: #006400;
|
||||
background: #fff;
|
||||
border-color: #006400;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
color: #fff;
|
||||
background: #006400;
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
/* SideNav */
|
||||
|
||||
.caretStyle {
|
||||
@ -197,6 +167,6 @@
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.article {
|
||||
.content {
|
||||
outline: 0;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { graphql } from 'gatsby';
|
||||
import Helmet from 'react-helmet';
|
||||
@ -13,20 +13,7 @@ const propTypes = {
|
||||
})
|
||||
};
|
||||
|
||||
class GuideArticle extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.article = null;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.article && document.activeElement.hasAttribute('data-navitem')) {
|
||||
this.article.focus();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const GuideArticle = props => {
|
||||
const {
|
||||
location: { pathname },
|
||||
data: {
|
||||
@ -37,7 +24,7 @@ class GuideArticle extends Component {
|
||||
}
|
||||
},
|
||||
pageContext: { meta }
|
||||
} = this.props;
|
||||
} = props;
|
||||
return (
|
||||
<Fragment>
|
||||
<Helmet>
|
||||
@ -63,15 +50,11 @@ class GuideArticle extends Component {
|
||||
className='article'
|
||||
dangerouslySetInnerHTML={{ __html: html }}
|
||||
id='article'
|
||||
ref={article => {
|
||||
this.article = article;
|
||||
}}
|
||||
tabIndex='-1'
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
GuideArticle.displayName = 'GuideArticle';
|
||||
GuideArticle.propTypes = propTypes;
|
||||
|
Reference in New Issue
Block a user