UNPKG

react-event-listener

Version:

A React component that allow to bind events on the global scope

183 lines (148 loc) 5.32 kB
'use strict'; 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;