1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', {
|
4 | value: true
|
5 | });
|
6 |
|
7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
8 |
|
9 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
10 |
|
11 | var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
12 |
|
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
14 |
|
15 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
16 |
|
17 | function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
18 |
|
19 | var _react = require('react');
|
20 |
|
21 | var _react2 = _interopRequireDefault(_react);
|
22 |
|
23 | var _reactDom = require('react-dom');
|
24 |
|
25 | var _reactDom2 = _interopRequireDefault(_reactDom);
|
26 |
|
27 | var CANCEL_DISTANCE_ON_SCROLL = 20;
|
28 |
|
29 | var styles = {
|
30 | root: {
|
31 | position: 'absolute',
|
32 | top: 0,
|
33 | left: 0,
|
34 | right: 0,
|
35 | bottom: 0,
|
36 | overflow: 'hidden'
|
37 | },
|
38 | sidebar: {
|
39 | zIndex: 2,
|
40 | position: 'absolute',
|
41 | top: 0,
|
42 | bottom: 0,
|
43 | transition: 'transform .3s ease-out',
|
44 | WebkitTransition: '-webkit-transform .3s ease-out',
|
45 | willChange: 'transform',
|
46 | overflowY: 'auto'
|
47 | },
|
48 | content: {
|
49 | position: 'absolute',
|
50 | top: 0,
|
51 | left: 0,
|
52 | right: 0,
|
53 | bottom: 0,
|
54 | overflow: 'auto',
|
55 | transition: 'left .3s ease-out, right .3s ease-out'
|
56 | },
|
57 | overlay: {
|
58 | zIndex: 1,
|
59 | position: 'fixed',
|
60 | top: 0,
|
61 | left: 0,
|
62 | right: 0,
|
63 | bottom: 0,
|
64 | opacity: 0,
|
65 | visibility: 'hidden',
|
66 | transition: 'opacity .3s ease-out',
|
67 | backgroundColor: 'rgba(0,0,0,.3)'
|
68 | },
|
69 | dragHandle: {
|
70 | zIndex: 1,
|
71 | position: 'fixed',
|
72 | top: 0,
|
73 | bottom: 0
|
74 | }
|
75 | };
|
76 |
|
77 | var Sidebar = (function (_React$Component) {
|
78 | _inherits(Sidebar, _React$Component);
|
79 |
|
80 | function Sidebar(props) {
|
81 | _classCallCheck(this, Sidebar);
|
82 |
|
83 | _get(Object.getPrototypeOf(Sidebar.prototype), 'constructor', this).call(this, props);
|
84 |
|
85 | this.state = {
|
86 |
|
87 | sidebarWidth: 0,
|
88 |
|
89 |
|
90 | touchIdentifier: null,
|
91 | touchStartX: null,
|
92 | touchStartY: null,
|
93 | touchCurrentX: null,
|
94 | touchCurrentY: null,
|
95 |
|
96 |
|
97 | dragSupported: typeof window === 'object' && 'ontouchstart' in window
|
98 | };
|
99 |
|
100 | this.overlayClicked = this.overlayClicked.bind(this);
|
101 | this.onTouchStart = this.onTouchStart.bind(this);
|
102 | this.onTouchMove = this.onTouchMove.bind(this);
|
103 | this.onTouchEnd = this.onTouchEnd.bind(this);
|
104 | this.onScroll = this.onScroll.bind(this);
|
105 | }
|
106 |
|
107 | _createClass(Sidebar, [{
|
108 | key: 'componentDidMount',
|
109 | value: function componentDidMount() {
|
110 | this.saveSidebarWidth();
|
111 | }
|
112 | }, {
|
113 | key: 'componentDidUpdate',
|
114 | value: function componentDidUpdate() {
|
115 |
|
116 | if (!this.isTouching()) {
|
117 | this.saveSidebarWidth();
|
118 | }
|
119 | }
|
120 | }, {
|
121 | key: 'onTouchStart',
|
122 | value: function onTouchStart(ev) {
|
123 |
|
124 | if (!this.isTouching()) {
|
125 | var touch = ev.targetTouches[0];
|
126 | this.setState({
|
127 | touchIdentifier: touch.identifier,
|
128 | touchStartX: touch.clientX,
|
129 | touchStartY: touch.clientY,
|
130 | touchCurrentX: touch.clientX,
|
131 | touchCurrentY: touch.clientY
|
132 | });
|
133 | }
|
134 | }
|
135 | }, {
|
136 | key: 'onTouchMove',
|
137 | value: function onTouchMove(ev) {
|
138 | if (this.isTouching()) {
|
139 | for (var ind = 0; ind < ev.targetTouches.length; ind++) {
|
140 |
|
141 | if (ev.targetTouches[ind].identifier === this.state.touchIdentifier) {
|
142 | this.setState({
|
143 | touchCurrentX: ev.targetTouches[ind].clientX,
|
144 | touchCurrentY: ev.targetTouches[ind].clientY
|
145 | });
|
146 | break;
|
147 | }
|
148 | }
|
149 | }
|
150 | }
|
151 | }, {
|
152 | key: 'onTouchEnd',
|
153 | value: function onTouchEnd() {
|
154 | if (this.isTouching()) {
|
155 |
|
156 | var touchWidth = this.touchSidebarWidth();
|
157 |
|
158 | if (this.props.open && touchWidth < this.state.sidebarWidth - this.props.dragToggleDistance || !this.props.open && touchWidth > this.props.dragToggleDistance) {
|
159 | this.props.onSetOpen(!this.props.open);
|
160 | }
|
161 |
|
162 | this.setState({
|
163 | touchIdentifier: null,
|
164 | touchStartX: null,
|
165 | touchStartY: null,
|
166 | touchCurrentX: null,
|
167 | touchCurrentY: null
|
168 | });
|
169 | }
|
170 | }
|
171 |
|
172 |
|
173 |
|
174 |
|
175 | }, {
|
176 | key: 'onScroll',
|
177 | value: function onScroll() {
|
178 | if (this.isTouching() && this.inCancelDistanceOnScroll()) {
|
179 | this.setState({
|
180 | touchIdentifier: null,
|
181 | touchStartX: null,
|
182 | touchStartY: null,
|
183 | touchCurrentX: null,
|
184 | touchCurrentY: null
|
185 | });
|
186 | }
|
187 | }
|
188 |
|
189 |
|
190 | }, {
|
191 | key: 'inCancelDistanceOnScroll',
|
192 | value: function inCancelDistanceOnScroll() {
|
193 | var cancelDistanceOnScroll = undefined;
|
194 |
|
195 | if (this.props.pullRight) {
|
196 | cancelDistanceOnScroll = Math.abs(this.state.touchCurrentX - this.state.touchStartX) < CANCEL_DISTANCE_ON_SCROLL;
|
197 | } else {
|
198 | cancelDistanceOnScroll = Math.abs(this.state.touchStartX - this.state.touchCurrentX) < CANCEL_DISTANCE_ON_SCROLL;
|
199 | }
|
200 | return cancelDistanceOnScroll;
|
201 | }
|
202 | }, {
|
203 | key: 'isTouching',
|
204 | value: function isTouching() {
|
205 | return this.state.touchIdentifier !== null;
|
206 | }
|
207 | }, {
|
208 | key: 'overlayClicked',
|
209 | value: function overlayClicked() {
|
210 | if (this.props.open) {
|
211 | this.props.onSetOpen(false);
|
212 | }
|
213 | }
|
214 | }, {
|
215 | key: 'saveSidebarWidth',
|
216 | value: function saveSidebarWidth() {
|
217 | var width = _reactDom2['default'].findDOMNode(this.refs.sidebar).offsetWidth;
|
218 |
|
219 | if (width !== this.state.sidebarWidth) {
|
220 | this.setState({ sidebarWidth: width });
|
221 | }
|
222 | }
|
223 |
|
224 |
|
225 | }, {
|
226 | key: 'touchSidebarWidth',
|
227 | value: function touchSidebarWidth() {
|
228 |
|
229 |
|
230 |
|
231 | if (this.props.pullRight) {
|
232 | if (this.props.open && window.innerWidth - this.state.touchStartX < this.state.sidebarWidth) {
|
233 | if (this.state.touchCurrentX > this.state.touchStartX) {
|
234 | return this.state.sidebarWidth + this.state.touchStartX - this.state.touchCurrentX;
|
235 | }
|
236 | return this.state.sidebarWidth;
|
237 | }
|
238 | return Math.min(window.innerWidth - this.state.touchCurrentX, this.state.sidebarWidth);
|
239 | }
|
240 |
|
241 | if (this.props.open && this.state.touchStartX < this.state.sidebarWidth) {
|
242 | if (this.state.touchCurrentX > this.state.touchStartX) {
|
243 | return this.state.sidebarWidth;
|
244 | }
|
245 | return this.state.sidebarWidth - this.state.touchStartX + this.state.touchCurrentX;
|
246 | }
|
247 | return Math.min(this.state.touchCurrentX, this.state.sidebarWidth);
|
248 | }
|
249 | }, {
|
250 | key: 'render',
|
251 | value: function render() {
|
252 | var sidebarStyle = _extends({}, styles.sidebar);
|
253 | var contentStyle = _extends({}, styles.content);
|
254 | var overlayStyle = _extends({}, styles.overlay);
|
255 | var useTouch = this.state.dragSupported && this.props.touch;
|
256 | var isTouching = this.isTouching();
|
257 | var rootProps = {
|
258 | style: styles.root
|
259 | };
|
260 | var dragHandle = undefined;
|
261 |
|
262 |
|
263 | if (this.props.pullRight) {
|
264 | sidebarStyle.right = 0;
|
265 | sidebarStyle.transform = 'translateX(100%)';
|
266 | sidebarStyle.WebkitTransform = 'translateX(100%)';
|
267 | if (this.props.shadow) {
|
268 | sidebarStyle.boxShadow = '-2px 2px 4px rgba(0, 0, 0, 0.15)';
|
269 | }
|
270 | } else {
|
271 | sidebarStyle.left = 0;
|
272 | sidebarStyle.transform = 'translateX(-100%)';
|
273 | sidebarStyle.WebkitTransform = 'translateX(-100%)';
|
274 | if (this.props.shadow) {
|
275 | sidebarStyle.boxShadow = '2px 2px 4px rgba(0, 0, 0, 0.15)';
|
276 | }
|
277 | }
|
278 |
|
279 | if (isTouching) {
|
280 | var percentage = this.touchSidebarWidth() / this.state.sidebarWidth;
|
281 |
|
282 |
|
283 | if (this.props.pullRight) {
|
284 | sidebarStyle.transform = 'translateX(' + (1 - percentage) * 100 + '%)';
|
285 | sidebarStyle.WebkitTransform = 'translateX(' + (1 - percentage) * 100 + '%)';
|
286 | } else {
|
287 | sidebarStyle.transform = 'translateX(-' + (1 - percentage) * 100 + '%)';
|
288 | sidebarStyle.WebkitTransform = 'translateX(-' + (1 - percentage) * 100 + '%)';
|
289 | }
|
290 |
|
291 |
|
292 | overlayStyle.opacity = percentage;
|
293 | overlayStyle.visibility = 'visible';
|
294 | } else if (this.props.docked) {
|
295 |
|
296 | if (this.state.sidebarWidth !== 0) {
|
297 | sidebarStyle.transform = 'translateX(0%)';
|
298 | sidebarStyle.WebkitTransform = 'translateX(0%)';
|
299 | }
|
300 |
|
301 |
|
302 | if (this.props.pullRight) {
|
303 | contentStyle.right = this.state.sidebarWidth + 'px';
|
304 | } else {
|
305 | contentStyle.left = this.state.sidebarWidth + 'px';
|
306 | }
|
307 | } else if (this.props.open) {
|
308 |
|
309 | sidebarStyle.transform = 'translateX(0%)';
|
310 | sidebarStyle.WebkitTransform = 'translateX(0%)';
|
311 |
|
312 |
|
313 | overlayStyle.opacity = 1;
|
314 | overlayStyle.visibility = 'visible';
|
315 | }
|
316 |
|
317 | if (isTouching || !this.props.transitions) {
|
318 | sidebarStyle.transition = 'none';
|
319 | sidebarStyle.WebkitTransition = 'none';
|
320 | contentStyle.transition = 'none';
|
321 | overlayStyle.transition = 'none';
|
322 | }
|
323 |
|
324 | if (useTouch) {
|
325 | if (this.props.open) {
|
326 | rootProps.onTouchStart = this.onTouchStart;
|
327 | rootProps.onTouchMove = this.onTouchMove;
|
328 | rootProps.onTouchEnd = this.onTouchEnd;
|
329 | rootProps.onTouchCancel = this.onTouchEnd;
|
330 | rootProps.onScroll = this.onScroll;
|
331 | } else {
|
332 | var dragHandleStyle = _extends({}, styles.dragHandle);
|
333 | dragHandleStyle.width = this.props.touchHandleWidth;
|
334 |
|
335 |
|
336 | if (this.props.pullRight) {
|
337 | dragHandleStyle.right = 0;
|
338 | } else {
|
339 | dragHandleStyle.left = 0;
|
340 | }
|
341 |
|
342 | dragHandle = _react2['default'].createElement('div', { style: dragHandleStyle,
|
343 | onTouchStart: this.onTouchStart, onTouchMove: this.onTouchMove,
|
344 | onTouchEnd: this.onTouchEnd, onTouchCancel: this.onTouchEnd });
|
345 | }
|
346 | }
|
347 |
|
348 | return _react2['default'].createElement(
|
349 | 'div',
|
350 | rootProps,
|
351 | _react2['default'].createElement(
|
352 | 'div',
|
353 | { style: sidebarStyle, ref: 'sidebar' },
|
354 | this.props.sidebar
|
355 | ),
|
356 | _react2['default'].createElement('div', { style: overlayStyle,
|
357 | onClick: this.overlayClicked, onTouchTap: this.overlayClicked }),
|
358 | _react2['default'].createElement(
|
359 | 'div',
|
360 | { style: contentStyle },
|
361 | dragHandle,
|
362 | this.props.children
|
363 | )
|
364 | );
|
365 | }
|
366 | }]);
|
367 |
|
368 | return Sidebar;
|
369 | })(_react2['default'].Component);
|
370 |
|
371 | Sidebar.propTypes = {
|
372 |
|
373 | children: _react2['default'].PropTypes.node.isRequired,
|
374 |
|
375 |
|
376 | sidebar: _react2['default'].PropTypes.node.isRequired,
|
377 |
|
378 |
|
379 | docked: _react2['default'].PropTypes.bool,
|
380 |
|
381 |
|
382 | open: _react2['default'].PropTypes.bool,
|
383 |
|
384 |
|
385 | transitions: _react2['default'].PropTypes.bool,
|
386 |
|
387 |
|
388 | touch: _react2['default'].PropTypes.bool,
|
389 |
|
390 |
|
391 | touchHandleWidth: _react2['default'].PropTypes.number,
|
392 |
|
393 |
|
394 | pullRight: _react2['default'].PropTypes.bool,
|
395 |
|
396 |
|
397 | shadow: _react2['default'].PropTypes.bool,
|
398 |
|
399 |
|
400 | dragToggleDistance: _react2['default'].PropTypes.number,
|
401 |
|
402 |
|
403 | onSetOpen: _react2['default'].PropTypes.func
|
404 | };
|
405 |
|
406 | Sidebar.defaultProps = {
|
407 | docked: false,
|
408 | open: false,
|
409 | transitions: true,
|
410 | touch: true,
|
411 | touchHandleWidth: 20,
|
412 | pullRight: false,
|
413 | shadow: true,
|
414 | dragToggleDistance: 30,
|
415 | onSetOpen: function onSetOpen() {}
|
416 | };
|
417 |
|
418 | exports['default'] = Sidebar;
|
419 | module.exports = exports['default']; |
\ | No newline at end of file |