react-event-listener
Version:
A React component that allow to bind events on the global scope
183 lines (148 loc) • 5.32 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var _classCallCheck = _interopDefault(require('@babel/runtime/helpers/classCallCheck'));
var _createClass = _interopDefault(require('@babel/runtime/helpers/createClass'));
var _possibleConstructorReturn = _interopDefault(require('@babel/runtime/helpers/possibleConstructorReturn'));
var _getPrototypeOf = _interopDefault(require('@babel/runtime/helpers/getPrototypeOf'));
var _inherits = _interopDefault(require('@babel/runtime/helpers/inherits'));
var _typeof = _interopDefault(require('@babel/runtime/helpers/typeof'));
var _objectWithoutProperties = _interopDefault(require('@babel/runtime/helpers/objectWithoutProperties'));
var _extends = _interopDefault(require('@babel/runtime/helpers/extends'));
var React = _interopDefault(require('react'));
var PropTypes = _interopDefault(require('prop-types'));
var warning = _interopDefault(require('warning'));
function defineProperty(object, property, attr) {
return Object.defineProperty(object, property, attr);
} // Passive options
// Inspired by https://github.com/Modernizr/Modernizr/blob/master/feature-detects/dom/passiveeventlisteners.js
var passiveOption = function () {
var cache = null;
return function () {
if (cache !== null) {
return cache;
}
var supportsPassiveOption = false;
try {
window.addEventListener('test', null, defineProperty({}, 'passive', {
get: function get() {
supportsPassiveOption = true;
}
}));
} catch (err) {//
}
cache = supportsPassiveOption;
return supportsPassiveOption;
}();
}();
var defaultEventOptions = {
capture: false,
passive: false
};
function mergeDefaultEventOptions(options) {
return _extends({}, defaultEventOptions, options);
}
function getEventListenerArgs(eventName, callback, options) {
var args = [eventName, callback];
args.push(passiveOption ? options : options.capture);
return args;
}
function on(target, eventName, callback, options) {
// eslint-disable-next-line prefer-spread
target.addEventListener.apply(target, getEventListenerArgs(eventName, callback, options));
}
function off(target, eventName, callback, options) {
// eslint-disable-next-line prefer-spread
target.removeEventListener.apply(target, getEventListenerArgs(eventName, callback, options));
}
function forEachListener(props, iteratee) {
var children = props.children,
target = props.target,
eventProps = _objectWithoutProperties(props, ["children", "target"]);
Object.keys(eventProps).forEach(function (name) {
if (name.substring(0, 2) !== 'on') {
return;
}
var prop = eventProps[name];
var type = _typeof(prop);
var isObject = type === 'object';
var isFunction = type === 'function';
if (!isObject && !isFunction) {
return;
}
var capture = name.substr(-7).toLowerCase() === 'capture';
var eventName = name.substring(2).toLowerCase();
eventName = capture ? eventName.substring(0, eventName.length - 7) : eventName;
if (isObject) {
iteratee(eventName, prop.handler, prop.options);
} else {
iteratee(eventName, prop, mergeDefaultEventOptions({
capture: capture
}));
}
});
}
function withOptions(handler, options) {
process.env.NODE_ENV !== "production" ? warning(options, 'react-event-listener: should be specified options in withOptions.') : void 0;
return {
handler: handler,
options: mergeDefaultEventOptions(options)
};
}
var EventListener =
/*#__PURE__*/
function (_React$PureComponent) {
_inherits(EventListener, _React$PureComponent);
function EventListener() {
_classCallCheck(this, EventListener);
return _possibleConstructorReturn(this, _getPrototypeOf(EventListener).apply(this, arguments));
}
_createClass(EventListener, [{
key: "componentDidMount",
value: function componentDidMount() {
this.applyListeners(on);
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
this.applyListeners(off, prevProps);
this.applyListeners(on);
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.applyListeners(off);
}
}, {
key: "applyListeners",
value: function applyListeners(onOrOff) {
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.props;
var target = props.target;
if (target) {
var element = target;
if (typeof target === 'string') {
element = window[target];
}
forEachListener(props, onOrOff.bind(null, element));
}
}
}, {
key: "render",
value: function render() {
return this.props.children || null;
}
}]);
return EventListener;
}(React.PureComponent);
EventListener.propTypes = process.env.NODE_ENV !== "production" ? {
/**
* You can provide a single child too.
*/
children: PropTypes.node,
/**
* The DOM target to listen to.
*/
target: PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired
} : {};
exports.withOptions = withOptions;
exports.default = EventListener;
;