UNPKG

react-swipeable-drawer

Version:
482 lines (411 loc) 14 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var React = require('react'); var React__default = _interopDefault(React); var PropTypes = _interopDefault(require('prop-types')); var DrawerContainer = function DrawerContainer(_ref) { var position = _ref.position, size = _ref.size, swiping = _ref.swiping, translation = _ref.translation, toggleDrawer = _ref.toggleDrawer, handleTouchStart = _ref.handleTouchStart, handleTouchMove = _ref.handleTouchMove, handleTouchEnd = _ref.handleTouchEnd, drawerContent = _ref.drawerContent, overlayStyle = _ref.overlayStyle, contentStyle = _ref.contentStyle; var open = translation > 0; return React__default.createElement( "div", { className: "DrawerContainer" }, React__default.createElement(DrawerOverlay, { position: position, open: open, swiping: swiping, translation: translation, toggleDrawer: toggleDrawer, handleTouchStart: handleTouchStart, handleTouchMove: handleTouchMove, handleTouchEnd: handleTouchEnd, style: overlayStyle }), React__default.createElement(DrawerContentContainer, { position: position, size: size, swiping: swiping, translation: translation, toggleDrawer: toggleDrawer, handleTouchStart: handleTouchStart, handleTouchMove: handleTouchMove, handleTouchEnd: handleTouchEnd, drawerContent: drawerContent, style: contentStyle }) ); }; DrawerContainer.propTypes = { position: PropTypes.oneOf(["left", "right", "top", "bottom"]).isRequired, size: PropTypes.number.isRequired, swiping: PropTypes.bool.isRequired, translation: PropTypes.number.isRequired, toggleDrawer: PropTypes.func.isRequired, handleTouchStart: PropTypes.func.isRequired, handleTouchMove: PropTypes.func.isRequired, handleTouchEnd: PropTypes.func.isRequired, drawerContent: PropTypes.element.isRequired, overlayStyle: PropTypes.object, contentStyle: PropTypes.object }; DrawerContainer.defaultProps = { overlayStyle: {}, contentStyle: {} }; var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; 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; }; }(); 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; }; var inherits = function (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; }; var possibleConstructorReturn = function (self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }; /* eslint jsx-a11y/click-events-have-key-events: 0 */ var transform = function transform(_ref) { var position = _ref.position, swiping = _ref.swiping, open = _ref.open; switch (position) { case "top": return { top: 0, left: 0, right: 0, height: swiping || open ? "100%" : "20px" }; case "right": return { right: 0, top: 0, bottom: 0, width: swiping || open ? "100%" : "20px" }; case "bottom": return { bottom: 0, left: 0, right: 0, height: swiping || open ? "100%" : "20px" }; case "left": default: return { left: 0, top: 0, bottom: 0, width: swiping || open ? "100%" : "20px" }; } }; var transition = function transition(_ref2) { var swiping = _ref2.swiping, open = _ref2.open; if (swiping) { return ""; } else if (open) { return "background-color .2s ease-in-out, width 0s 0s, height 0s 0s"; } return "background-color .2s ease-in-out, width 0s .2s, height 0s 0s"; }; var DrawerOverlay = function DrawerOverlay(_ref3) { var position = _ref3.position, open = _ref3.open, swiping = _ref3.swiping, translation = _ref3.translation, toggleDrawer = _ref3.toggleDrawer, handleTouchStart = _ref3.handleTouchStart, handleTouchMove = _ref3.handleTouchMove, handleTouchEnd = _ref3.handleTouchEnd, style = _ref3.style; return React__default.createElement("div", { className: "DrawerOverlay", onClick: open ? toggleDrawer : null, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove(100), onTouchEnd: handleTouchEnd, style: _extends({ position: "fixed", zIndex: 1, backgroundColor: "rgba(0,0,0," + 0.6 * translation / 100 + ")", transition: transition({ swiping: swiping, open: open }) }, transform({ position: position, swiping: swiping, open: open }), style) }); }; DrawerOverlay.propTypes = { position: PropTypes.oneOf(["left", "right", "top", "bottom"]).isRequired, open: PropTypes.bool.isRequired, swiping: PropTypes.bool.isRequired, translation: PropTypes.number.isRequired, toggleDrawer: PropTypes.func.isRequired, handleTouchStart: PropTypes.func.isRequired, handleTouchMove: PropTypes.func.isRequired, handleTouchEnd: PropTypes.func.isRequired, style: PropTypes.object.isRequired }; var transform$1 = function transform(_ref) { var position = _ref.position, size = _ref.size, translation = _ref.translation; switch (position) { case "top": return { left: 0, right: 0, top: "-" + size + "%", height: size + "%", transform: "translateY(" + translation + "%)" }; case "right": return { top: 0, bottom: 0, right: "-" + size + "%", width: size + "%", transform: "translateX(" + -translation + "%)" }; case "bottom": return { left: 0, right: 0, bottom: "-" + size + "%", height: size + "%", transform: "translateY(" + -translation + "%)" }; case "left": default: return { top: 0, bottom: 0, left: "-" + size + "%", width: size + "%", transform: "translateX(" + translation + "%)" }; } }; var DrawerContentContainer = function DrawerContentContainer(_ref2) { var position = _ref2.position, size = _ref2.size, swiping = _ref2.swiping, translation = _ref2.translation, handleTouchStart = _ref2.handleTouchStart, handleTouchMove = _ref2.handleTouchMove, handleTouchEnd = _ref2.handleTouchEnd, drawerContent = _ref2.drawerContent, style = _ref2.style; return React__default.createElement( "div", { className: "DrawerContentContainer", onTouchStart: handleTouchStart, onTouchMove: handleTouchMove(size), onTouchEnd: handleTouchEnd, style: _extends({ position: "fixed", zIndex: 1, transition: swiping ? "" : "transform .2s ease-in-out" }, transform$1({ position: position, size: size, translation: translation }), style) }, drawerContent ); }; DrawerContentContainer.propTypes = { position: PropTypes.oneOf(["left", "right", "top", "bottom"]).isRequired, size: PropTypes.number.isRequired, swiping: PropTypes.bool.isRequired, translation: PropTypes.number.isRequired, handleTouchStart: PropTypes.func.isRequired, handleTouchMove: PropTypes.func.isRequired, handleTouchEnd: PropTypes.func.isRequired, drawerContent: PropTypes.element.isRequired, style: PropTypes.object.isRequired }; var MainContentContainer = function MainContentContainer(_ref) { var translation = _ref.translation, mainContentScroll = _ref.mainContentScroll, children = _ref.children; var mainContentOpenStyle = translation > 0 ? { position: "fixed", top: -mainContentScroll, left: 0, right: 0 } : {}; return React__default.createElement( "div", { className: "MainContentContainer", style: _extends({}, mainContentOpenStyle) }, children ); }; MainContentContainer.propTypes = { translation: PropTypes.number.isRequired, mainContentScroll: PropTypes.number.isRequired, children: PropTypes.node.isRequired }; var START_TRANSLATION = -10; var STOP_TRANSLATION = 100; var Drawer = function (_Component) { inherits(Drawer, _Component); function Drawer() { var _ref; var _temp, _this, _ret; classCallCheck(this, Drawer); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = Drawer.__proto__ || Object.getPrototypeOf(Drawer)).call.apply(_ref, [this].concat(args))), _this), _this.state = { swiping: false, scrolling: false, translation: START_TRANSLATION, clientX: 0, clientY: 0 }, _this.mainContentScroll = 0, _this.saveScrollPosition = function () { var translation = _this.state.translation; if (translation === START_TRANSLATION) { _this.mainContentScroll = window.pageYOffset; } }, _this.toggleDrawer = function () { _this.saveScrollPosition(); _this.setState(function (_ref2) { var translation = _ref2.translation; return { translation: translation > 50 ? START_TRANSLATION : STOP_TRANSLATION }; }); }, _this.handleTouchStart = function (event) { _this.saveScrollPosition(); var _event$targetTouches$ = event.targetTouches[0], clientX = _event$targetTouches$.clientX, clientY = _event$targetTouches$.clientY; _this.setState({ swiping: true, clientX: clientX, clientY: clientY }); }, _this.handleTouchMove = function (size) { return function (event) { var position = _this.props.position; var _this$state = _this.state, prevClientX = _this$state.clientX, prevClientY = _this$state.clientY, scrolling = _this$state.scrolling; var maxWidth = window.innerWidth; var _event$targetTouches$2 = event.targetTouches[0], clientX = _event$targetTouches$2.clientX, clientY = _event$targetTouches$2.clientY; var diffTranslateX = Math.abs(clientX - prevClientX); var diffTranslateY = Math.abs(clientY - prevClientY); if (scrolling || diffTranslateY > diffTranslateX) { _this.setState({ scrolling: true }); } else if (position === "right") { _this.setState({ translation: Math.min((maxWidth - clientX) / (maxWidth * size / 100) * 100, STOP_TRANSLATION) }); } else { _this.setState({ translation: Math.min(clientX / (maxWidth * size / 100) * 100, STOP_TRANSLATION) }); } }; }, _this.handleTouchEnd = function () { _this.setState(function (_ref3) { var translation = _ref3.translation; return { swiping: false, scrolling: false, translation: translation < 50 ? START_TRANSLATION : STOP_TRANSLATION }; }); }, _temp), possibleConstructorReturn(_this, _ret); } createClass(Drawer, [{ key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { var translation = this.state.translation; if (translation !== prevState.translation && translation === START_TRANSLATION) { window.scrollTo(0, this.mainContentScroll); } } }, { key: "render", value: function render() { var _props = this.props, position = _props.position, size = _props.size, children = _props.children; var _state = this.state, swiping = _state.swiping, translation = _state.translation; return children({ position: position, size: size, swiping: swiping, translation: translation, mainContentScroll: this.mainContentScroll, toggleDrawer: this.toggleDrawer, handleTouchStart: this.handleTouchStart, handleTouchMove: this.handleTouchMove, handleTouchEnd: this.handleTouchEnd }); } }]); return Drawer; }(React.Component); Drawer.propTypes = { position: PropTypes.oneOf(["left", "right", "top", "bottom"]).isRequired, size: PropTypes.number.isRequired, children: PropTypes.func.isRequired }; exports['default'] = Drawer; exports.DrawerContainer = DrawerContainer; exports.DrawerOverlay = DrawerOverlay; exports.DrawerContentContainer = DrawerContentContainer; exports.MainContentContainer = MainContentContainer;