Skip to content

Commit a0c67c3

Browse files
authored
[Gatsby Docs Update] Tutorial: Clicking an anchor tag should auto-close mobile nav (#10844)
* [Gatsby Docs Update] Tutorial: Clicking an anchor tag should auto-close mobile nav **what is the change?:** We create a prop to close the mobile nav and then pass it all the way down through to the links for the tutorial page - ``` <StickyResponsiveSidebar> -> sends down handler to close mobile nav V <Sidebar> V <Section> V <GatsbyLink> -> receives onClick to close mobile nav ``` **why make this change?:** So that the menu doesn't stay open after people click a link :) We considered listening to 'onhashchange' and ran into two problems; - React doesn't support listening to `onhashchange` on DOMComponents, and I'm not sure that would work anyway - When listening to `window.onhashchange` it didn't seem to fire - Better to pass something down than to add another global event listener imo **test plan:** Manual testing AND I ran `yarn build` **issue:** Checklist item on this wiki; https://github.com/bvaughn/react/wiki/Gatsby-check-list Sidebar Component > Tutorial: Clicking an anchor tag should auto-close mobile nav * ran prettier * Fix label on tutorial page **what is the change?:** Skim through the items in the 'defaultActiveSection' and find the one matching the current location hash. **why make this change?:** On the tutorial page it feels weird if the navbar section doesn't match the section you are on. **test plan:** Manual testing + `yarn build` * fix bad resolution of rebase conflict * ran prettier * Tutorial links now update active highlight on-click * Renamed some Section props for clarity * Refactored createLink() to use named params
1 parent 1369261 commit a0c67c3

File tree

5 files changed

+67
-25
lines changed

5 files changed

+67
-25
lines changed

www/src/components/StickyResponsiveSidebar/StickyResponsiveSidebar.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,18 @@ class StickyResponsiveSidebar extends Component {
2222
this.state = {
2323
open: false,
2424
};
25-
this.toggleOpen = this._toggleOpen.bind(this);
25+
this._openNavMenu = this._openNavMenu.bind(this);
26+
this._closeNavMenu = this._closeNavMenu.bind(this);
2627
}
2728

28-
_toggleOpen() {
29+
_openNavMenu() {
2930
this.setState({open: !this.state.open});
3031
}
3132

33+
_closeNavMenu() {
34+
this.setState({open: false});
35+
}
36+
3237
render() {
3338
const {open} = this.state;
3439
const smallScreenSidebarStyles = {
@@ -53,6 +58,7 @@ class StickyResponsiveSidebar extends Component {
5358
const menuOpacity = open ? 1 : 0;
5459
const menuOffset = open ? 0 : 40;
5560

61+
// TODO: role and aria props for 'close' button?
5662
return (
5763
<div>
5864
<div
@@ -123,7 +129,7 @@ class StickyResponsiveSidebar extends Component {
123129
tranform: 'none !important',
124130
},
125131
}}>
126-
<Sidebar {...this.props} />
132+
<Sidebar closeParentMenu={this._closeNavMenu} {...this.props} />
127133
</div>
128134
</div>
129135
<div
@@ -141,7 +147,7 @@ class StickyResponsiveSidebar extends Component {
141147
boxShadow: '0 0 20px rgba(0, 0, 0, 0.3)',
142148
[media.lessThan('small')]: smallScreenBottomBarStyles,
143149
}}
144-
onClick={this.toggleOpen}>
150+
onClick={this._openNavMenu}>
145151
<Container>
146152
<div
147153
css={{

www/src/templates/components/Sidebar/Section.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,17 @@ import ChevronSvg from '../ChevronSvg';
1717
// TODO Update isActive link as document scrolls past anchor tags
1818
// Maybe used 'hashchange' along with 'scroll' to set/update active links
1919

20-
const Section = ({createLink, isActive, location, onClick, section}) => (
20+
const Section = ({
21+
createLink,
22+
isActive,
23+
location,
24+
onLinkClick,
25+
onSectionTitleClick,
26+
section,
27+
}) => (
2128
<div>
2229
<MetaTitle
23-
onClick={onClick}
30+
onClick={onSectionTitleClick}
2431
cssProps={{
2532
marginTop: 10,
2633

@@ -59,13 +66,23 @@ const Section = ({createLink, isActive, location, onClick, section}) => (
5966
css={{
6067
marginTop: 5,
6168
}}>
62-
{createLink(location, section, item)}
69+
{createLink({
70+
item,
71+
location,
72+
onLinkClick,
73+
section,
74+
})}
6375

6476
{item.subitems &&
6577
<ul css={{marginLeft: 20}}>
6678
{item.subitems.map(subitem => (
6779
<li key={subitem.id}>
68-
{createLink(location, section, subitem)}
80+
{createLink({
81+
item: subitem,
82+
location,
83+
onLinkClick,
84+
section,
85+
})}
6986
</li>
7087
))}
7188
</ul>}

www/src/templates/components/Sidebar/Sidebar.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class Sidebar extends Component {
2424
}
2525

2626
render() {
27-
const {createLink, location, sectionList} = this.props;
27+
const {closeParentMenu, createLink, location, sectionList} = this.props;
2828
const {activeSection} = this.state;
2929

3030
return (
@@ -51,7 +51,8 @@ class Sidebar extends Component {
5151
isActive={activeSection === section || sectionList.length === 1}
5252
key={index}
5353
location={location}
54-
onClick={() => this._toggleSection(section)}
54+
onLinkClick={closeParentMenu}
55+
onSectionTitleClick={() => this._toggleSection(section)}
5556
section={section}
5657
/>
5758
))}

www/src/templates/tutorial.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,26 @@ import React from 'react';
1515
import {createLinkTutorial} from 'utils/createLink';
1616
import {sectionListTutorial} from 'utils/sectionList';
1717

18-
const Tutorial = ({data, location}) => (
19-
<MarkdownPage
20-
createLink={createLinkTutorial}
21-
location={location}
22-
markdownRemark={data.markdownRemark}
23-
sectionList={sectionListTutorial}
24-
titlePostfix=" - React"
25-
/>
26-
);
18+
const Tutorial = ({data, location}) => {
19+
// HACK The injected location prop doesn't update when hash changes
20+
// This might be a gatsby issue, or a react-router/history issue,
21+
// Or we might be using either library incorrectly.
22+
// For now this patch keeps the hash in sync by JIT copying it from window.
23+
// The undefined check prevents us from breaking on production build.
24+
if (typeof window !== 'undefined' && typeof window.location !== 'undefined') {
25+
location.hash = window.location.hash;
26+
}
27+
28+
return (
29+
<MarkdownPage
30+
createLink={createLinkTutorial}
31+
location={location}
32+
markdownRemark={data.markdownRemark}
33+
sectionList={sectionListTutorial}
34+
titlePostfix=" - React"
35+
/>
36+
);
37+
};
2738

2839
Tutorial.propTypes = {
2940
data: PropTypes.object.isRequired,

www/src/utils/createLink.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import isItemActive from 'utils/isItemActive';
1818
import slugify from 'utils/slugify';
1919
import {colors, media} from 'theme';
2020

21-
const createLinkBlog = (location, section, item) => {
21+
const createLinkBlog = ({item, location, section}) => {
2222
const isActive = isItemActive(location, item);
2323

2424
return (
@@ -29,7 +29,7 @@ const createLinkBlog = (location, section, item) => {
2929
);
3030
};
3131

32-
const createLinkCommunity = (location, section, item) => {
32+
const createLinkCommunity = ({item, location, section}) => {
3333
if (item.href) {
3434
return (
3535
<a css={[linkCss]} href={item.href}>
@@ -45,11 +45,15 @@ const createLinkCommunity = (location, section, item) => {
4545
</a>
4646
);
4747
} else {
48-
return createLinkDocs(location, section, item);
48+
return createLinkDocs({
49+
item,
50+
location,
51+
section,
52+
});
4953
}
5054
};
5155

52-
const createLinkDocs = (location, section, item) => {
56+
const createLinkDocs = ({item, location, section}) => {
5357
const isActive = isItemActive(location, item);
5458

5559
return (
@@ -62,11 +66,14 @@ const createLinkDocs = (location, section, item) => {
6266
);
6367
};
6468

65-
const createLinkTutorial = (location, section, item) => {
69+
const createLinkTutorial = ({item, location, onLinkClick, section}) => {
6670
const isActive = isItemActive(location, item);
6771

6872
return (
69-
<Link css={[linkCss, isActive && activeLinkCss]} to={item.href}>
73+
<Link
74+
css={[linkCss, isActive && activeLinkCss]}
75+
onClick={onLinkClick}
76+
to={item.href}>
7077
{isActive && <span css={activeLinkBefore} />}
7178
{item.title}
7279
</Link>

0 commit comments

Comments
 (0)