Skip to content

Commit 8b7ba92

Browse files
Muntermontogeek
authored andcommitted
Rebuild: Make mobile sidebar work again (#2429)
- Fixed broken urls in section headings - Fixed active marker of the section and avoided marking a sections index page as active when a sub page was active - Hooked close button up - Made drag-to-open work - Made outside click to close menu work
1 parent 0ba4025 commit 8b7ba92

File tree

4 files changed

+46
-56
lines changed

4 files changed

+46
-56
lines changed

src/components/SidebarMobile/SidebarMobile.jsx

Lines changed: 37 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@ import React from 'react';
22
import Link from '../Link/Link';
33
import './SidebarMobile.scss';
44

5-
// TODO: Finish updating close and swipe behaviors
65
// TODO: Check to make sure all pages are shown and properly sorted
76
export default class SidebarMobile extends React.Component {
87
_container = null
98
_initialTouchPosition = {}
109
_lastTouchPosition = {}
1110

1211
render() {
13-
let { open } = this.props;
14-
let openMod = open ? 'sidebar-mobile--visible' : '';
12+
let { isOpen, toggle } = this.props;
13+
let openMod = isOpen ? ' sidebar-mobile--visible' : '';
14+
15+
this._toggleBodyListener(isOpen);
1516

1617
return (
1718
<nav
18-
className={ `sidebar-mobile ${openMod}` }
19+
className={ `sidebar-mobile${openMod}` }
1920
ref={ ref => this._container = ref }
2021
onTouchStart={ this._handleTouchStart }
2122
onTouchMove={ this._handleTouchMove }
@@ -30,26 +31,17 @@ export default class SidebarMobile extends React.Component {
3031
<div className="sidebar-mobile__content">
3132
<i
3233
className="sidebar-mobile__close icon-cross"
33-
onClick={ this.props.toggle } />
34+
onClick={ toggle.bind(null, false) } />
3435

3536
{ this._getSections() }
3637
</div>
3738
</nav>
3839
);
3940
}
4041

41-
componentDidMount() {
42-
if (typeof window !== 'undefined') {
43-
// window.addEventListener('click', this._handleBodyClick);
44-
window.addEventListener('touchstart', this._handleBodyClick);
45-
}
46-
}
47-
48-
componentWillUnmount() {
49-
if (typeof window !== 'undefined') {
50-
// window.removeEventListener('click', this._handleBodyClick);
51-
window.removeEventListener('touchstart', this._handleBodyClick);
52-
}
42+
_toggleBodyListener(add) {
43+
let actionName = add ? 'addEventListener' : 'removeEventListener';
44+
window[actionName]('mousedown', this._handleBodyClick);
5345
}
5446

5547
/**
@@ -60,23 +52,22 @@ export default class SidebarMobile extends React.Component {
6052
_getSections() {
6153
let pathname = '';
6254

63-
if (window.location !== undefined) {
55+
if (window && window.location !== undefined) {
6456
pathname = window.location.pathname;
6557
}
6658

6759
return this.props.sections.map(section => {
68-
let active = pathname === section.url || pathname.includes(`/${section.url}`),
69-
absoluteUrl = (section.url == '/') ? '/' : `/${section.url}`;
60+
let active = section.url !== '/' && pathname.startsWith(section.url);
7061

7162
return (
7263
<div
7364
className={ `sidebar-mobile__section ${active ? 'sidebar-mobile__section--active' : ''}` }
74-
key={ absoluteUrl }>
65+
key={ section.url }>
7566
<Link
7667
className="sidebar-mobile__section-header"
77-
key={ absoluteUrl }
78-
to={ absoluteUrl }
79-
onClick={ this.props.toggle }>
68+
key={ section.url }
69+
to={ section.url }
70+
onClick={ this.props.toggle.bind(null, false) }>
8071
<h3>{ section.title || section.url }</h3>
8172
</Link>
8273

@@ -101,14 +92,14 @@ export default class SidebarMobile extends React.Component {
10192

10293
return pages.map(page => {
10394
let url = `${page.url}`,
104-
active = pathname === url || pathname.includes(`${url}/`);
95+
active = pathname === url;
10596

10697
return (
10798
<Link
10899
key={ url }
109100
className={ `sidebar-mobile__page ${active ? 'sidebar-mobile__page--active' : ''}` }
110101
to={ url }
111-
onClick={ this.props.toggle }>
102+
onClick={ this.props.toggle.bind(null, false) }>
112103
{ page.title }
113104
</Link>
114105
);
@@ -120,30 +111,14 @@ export default class SidebarMobile extends React.Component {
120111
*
121112
* @param {object} e - Native click event
122113
*/
123-
// _handleBodyClick = e => {
124-
// if (
125-
// this.props.open &&
126-
// !this._container.contains(e.target)
127-
// ) {
128-
// this._close();
129-
// }
130-
// }
131-
132-
/**
133-
* Hide the sidebar
134-
*
135-
*/
136-
// _close() {
137-
// this._container.classList.remove(
138-
// 'sidebar-mobile--visible'
139-
// );
140-
// }
141-
142-
// _open() {
143-
// this._container.classList.add(
144-
// 'sidebar-mobile--visible'
145-
// );
146-
// }
114+
_handleBodyClick = e => {
115+
if (
116+
this.props.isOpen &&
117+
!this._container.contains(e.target)
118+
) {
119+
this.props.toggle(false);
120+
}
121+
}
147122

148123
_handleTouchStart = e => {
149124
this._initialTouchPosition.x = e.touches[0].pageX;
@@ -159,7 +134,7 @@ export default class SidebarMobile extends React.Component {
159134
let factor = Math.abs(yDiff / xDiff);
160135

161136
// Factor makes sure horizontal and vertical scroll dont take place together
162-
if (xDiff>0 && factor < 0.8) {
137+
if (xDiff > 0 && factor < 0.8) {
163138
e.preventDefault();
164139
this._container.style.transform = `translateX(-${xDiff}px)`;
165140
this._lastTouchPosition.x = e.touches[0].pageX;
@@ -182,14 +157,21 @@ export default class SidebarMobile extends React.Component {
182157
}
183158

184159
_handleTouchEnd = e => {
160+
const { isOpen } = this.props;
161+
const threshold = 20;
162+
185163
// Free up all the inline styling
186164
this._container.classList.remove('no-delay');
187165
this._container.style.transform = '';
188166

189-
if (this._initialTouchPosition.x - this._lastTouchPosition.x > 100) {
190-
this._close();
191-
} else if (this._lastTouchPosition.x - this._initialTouchPosition.x > 100) {
192-
this._open();
167+
// are we open?
168+
if (isOpen && this._initialTouchPosition.x - this._lastTouchPosition.x > threshold) {
169+
// this is in top level nav callback
170+
this.props.toggle(false);
171+
} else if (!isOpen && this._lastTouchPosition.x - this._initialTouchPosition.x > threshold) {
172+
this.props.toggle(true);
173+
e.preventDefault();
174+
e.stopPropagation();
193175
}
194176
}
195177
}

src/components/SidebarMobile/SidebarMobile.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020

2121
&--visible {
2222
transform: translate3D(0, 0, 0);
23+
24+
.sidebar-mobile__toggle {
25+
display: none;
26+
}
2327
}
2428

2529
&.no-delay{

src/components/Site/Site.jsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ class Site extends React.Component {
6363
]}
6464
/>
6565

66-
{isClient ? <SidebarMobile open={mobileSidebarOpen} sections={this._strip(Content.children)} /> : null}
66+
{isClient ? <SidebarMobile
67+
isOpen={mobileSidebarOpen}
68+
sections={this._strip(Content.children)}
69+
toggle={this._toggleSidebar} /> : null}
6770

6871
<Switch>
6972
<Route path="/" exact component={Splash} />

src/components/SplashViz/SplashViz.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
max-height: 720px;
1111
background: getColor(elephant);
1212
flex-direction: column;
13+
overflow: hidden;
1314

1415
&__heading {
1516
color: getColor(white);

0 commit comments

Comments
 (0)