Skip to content

Commit 71fcf6c

Browse files
prateekbhskipjack
authored andcommitted
swipable sidebar on mobile
1 parent e811652 commit 71fcf6c

File tree

2 files changed

+92
-8
lines changed

2 files changed

+92
-8
lines changed

components/sidebar-mobile/sidebar-mobile-style.scss

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,44 @@
33

44
.sidebar-mobile {
55
position: fixed;
6-
width: 280px;
6+
width: 295px;
77
height: 100vh;
88
z-index: 100;
99
top: 0;
1010
overflow-y: auto;
1111
overflow-x: hidden;
1212
-webkit-overflow-scrolling: touch;
13-
background: getColor(white);
1413
transform: translate3D(-100%, 0, 0);
14+
transform: translate3D(calc(-100% + 5px), 0, 0);
1515
transition: all 500ms;
1616

1717
@include break {
1818
display: none;
1919
}
20-
20+
2121
&--visible {
2222
transform: translate3D(0, 0, 0);
23-
box-shadow: 0 0 5px getColor(emperor);
23+
}
24+
25+
&.no-delay{
26+
transition-duration: 0ms;
27+
}
28+
29+
.opener{
30+
position: absolute;
31+
top: 0;
32+
bottom: 0;
33+
width: 10px;
34+
left: 285px;
35+
}
36+
37+
.sidebar-content{
38+
position: relative;
39+
width: 285px;
40+
height: 100vh;
41+
overflow-x: hidden;
42+
background: map-get($colors, white);
43+
box-shadow: 0 0 5px map-get($colors, emperor);
2444
}
2545
}
2646

components/sidebar-mobile/sidebar-mobile.jsx

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import React from 'react';
22
import Link from '../link/link';
33
import './sidebar-mobile-style';
44

5+
let initialTouchPosition = {};
6+
let lastTouchPosition = {};
7+
58
export default class SidebarMobile extends React.Component {
69
constructor(props) {
710
super(props);
@@ -11,11 +14,21 @@ export default class SidebarMobile extends React.Component {
1114

1215
render() {
1316
return (
14-
<nav className="sidebar-mobile" ref={ ref => this.container = ref }>
15-
<i className="sidebar-mobile__close icon-cross"
17+
<nav className="sidebar-mobile" ref={ ref => this.container = ref }
18+
onTouchStart={this._handleTouchStart.bind(this)}
19+
onTouchMove={this._handleTouchMove.bind(this)}
20+
onTouchEnd={this._handleTouchEnd.bind(this)}>
21+
<div className="opener"
22+
onTouchStart={this._handleTouchStart.bind(this)}
23+
onTouchMove={this._handleOpenerTouchMove.bind(this)}
24+
onTouchEnd={this._handleTouchEnd.bind(this)}>
25+
</div>
26+
<div className="sidebar-content">
27+
<i className="sidebar-mobile__close icon-cross"
1628
onClick={ this._close.bind(this) } />
17-
18-
{ this._getSections() }
29+
30+
{ this._getSections() }
31+
</div>
1932
</nav>
2033
);
2134
}
@@ -101,4 +114,55 @@ export default class SidebarMobile extends React.Component {
101114
'sidebar-mobile--visible'
102115
);
103116
}
117+
118+
_open() {
119+
this.container.classList.add(
120+
'sidebar-mobile--visible'
121+
);
122+
}
123+
124+
_handleTouchStart(e){
125+
initialTouchPosition.x = e.touches[0].pageX;
126+
initialTouchPosition.y = e.touches[0].clientY;
127+
//for instant transform along with the touch
128+
this.container.classList.add("no-delay");
129+
}
130+
131+
_handleTouchMove(e){
132+
let xDiff = initialTouchPosition.x - e.touches[0].pageX;
133+
let yDiff = initialTouchPosition.y - e.touches[0].pageY;
134+
let factor = Math.abs(yDiff/xDiff);
135+
//factor makes sure horizontal and vertical scroll dont take place together
136+
if(xDiff>0 && factor < 0.8){
137+
e.preventDefault();
138+
this.container.style.transform="translateX(-"+xDiff+"px)";
139+
lastTouchPosition.x = e.touches[0].pageX;
140+
lastTouchPosition.y = e.touches[0].clientY;
141+
}
142+
}
143+
144+
_handleOpenerTouchMove(e){
145+
let xDiff = e.touches[0].pageX - initialTouchPosition.x;
146+
let yDiff = initialTouchPosition.y - e.touches[0].pageY;
147+
let factor = Math.abs(yDiff/xDiff);
148+
//factor makes sure horizontal and vertical scroll dont take place together
149+
if(xDiff>0 && xDiff<295 && factor < 0.8){
150+
e.preventDefault();
151+
this.container.style.transform="translateX(calc(-100% + "+xDiff+"px))";
152+
lastTouchPosition.x = e.touches[0].pageX;
153+
lastTouchPosition.y = e.touches[0].clientY;
154+
}
155+
}
156+
157+
_handleTouchEnd(e){
158+
//free up all the inline styling
159+
this.container.classList.remove("no-delay");
160+
this.container.style="";
161+
if(initialTouchPosition.x - lastTouchPosition.x > 100){
162+
this._close();
163+
} else if(lastTouchPosition.x - initialTouchPosition.x > 100){
164+
this._open();
165+
}
166+
167+
}
104168
}

0 commit comments

Comments
 (0)