react-hammerjs
Version:
ReactJS / HammerJS integration. Support touch events in your React app.
173 lines (148 loc) • 5.66 kB
JavaScript
import PropTypes from 'prop-types';
import React from 'react';
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; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(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; }
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; }
// require('hammerjs') when in a browser. This is safe because Hammer is only
// invoked in componentDidMount, which is not executed on the server.
var Hammer = typeof window !== 'undefined' ? require('hammerjs') : undefined;
var privateProps = {
children: true,
direction: true,
options: true,
recognizeWith: true,
vertical: true
};
/**
* Hammer Component
* ================
*/
var handlerToEvent = {
action: 'tap press',
onDoubleTap: 'doubletap',
onPan: 'pan',
onPanCancel: 'pancancel',
onPanEnd: 'panend',
onPanStart: 'panstart',
onPinch: 'pinch',
onPinchCancel: 'pinchcancel',
onPinchEnd: 'pinchend',
onPinchIn: 'pinchin',
onPinchOut: 'pinchout',
onPinchStart: 'pinchstart',
onPress: 'press',
onPressUp: 'pressup',
onRotate: 'rotate',
onRotateCancel: 'rotatecancel',
onRotateEnd: 'rotateend',
onRotateMove: 'rotatemove',
onRotateStart: 'rotatestart',
onSwipe: 'swipe',
onSwipeRight: 'swiperight',
onSwipeLeft: 'swipeleft',
onSwipeUp: 'swipeup',
onSwipeDown: 'swipedown',
onTap: 'tap'
};
Object.keys(handlerToEvent).forEach(function (i) {
privateProps[i] = true;
});
function updateHammer(hammer, props) {
if (props.hasOwnProperty('vertical')) {
console.warn('vertical is deprecated, please use `direction` instead');
}
var directionProp = props.direction;
if (directionProp || props.hasOwnProperty('vertical')) {
var direction = directionProp ? directionProp : props.vertical ? 'DIRECTION_ALL' : 'DIRECTION_HORIZONTAL';
hammer.get('pan').set({ direction: Hammer[direction] });
hammer.get('swipe').set({ direction: Hammer[direction] });
}
if (props.options) {
Object.keys(props.options).forEach(function (option) {
if (option === 'recognizers') {
Object.keys(props.options.recognizers).forEach(function (gesture) {
var recognizer = hammer.get(gesture);
recognizer.set(props.options.recognizers[gesture]);
if (props.options.recognizers[gesture].requireFailure) {
recognizer.requireFailure(props.options.recognizers[gesture].requireFailure);
}
}, this);
} else {
var key = option;
var optionObj = {};
optionObj[key] = props.options[option];
hammer.set(optionObj);
}
}, this);
}
if (props.recognizeWith) {
Object.keys(props.recognizeWith).forEach(function (gesture) {
var recognizer = hammer.get(gesture);
recognizer.recognizeWith(props.recognizeWith[gesture]);
}, this);
}
Object.keys(props).forEach(function (p) {
var e = handlerToEvent[p];
if (e) {
hammer.off(e);
hammer.on(e, props[p]);
}
});
}
var HammerComponent = function (_React$Component) {
_inherits(HammerComponent, _React$Component);
function HammerComponent() {
_classCallCheck(this, HammerComponent);
return _possibleConstructorReturn(this, (HammerComponent.__proto__ || Object.getPrototypeOf(HammerComponent)).apply(this, arguments));
}
_createClass(HammerComponent, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.hammer = new Hammer(this.domElement);
updateHammer(this.hammer, this.props);
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate() {
if (this.hammer) {
updateHammer(this.hammer, this.props);
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
if (this.hammer) {
this.hammer.stop();
this.hammer.destroy();
}
this.hammer = null;
}
}, {
key: 'render',
value: function render() {
var props = {};
Object.keys(this.props).forEach(function (i) {
if (!privateProps[i]) {
props[i] = this.props[i];
}
}, this);
var self = this;
props.ref = function (domElement) {
if (self.props.ref) {
self.props.ref(domElement);
}
self.domElement = domElement;
};
// Reuse the child provided
// This makes it flexible to use whatever element is wanted (div, ul, etc)
return React.cloneElement(React.Children.only(this.props.children), props);
}
}]);
return HammerComponent;
}(React.Component);
HammerComponent.displayName = 'Hammer';
HammerComponent.propTypes = {
className: PropTypes.string
};
export default HammerComponent;