UNPKG

react-goodies

Version:

[![Build Status][build-badge]][build] [![Code Coverage][coverage-badge]][coverage] [![downloads][downloads-badge]][npmcharts] [![version][version-badge]][package] [![MIT License][license-badge]][license]

686 lines (536 loc) 21 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('prop-types')) : typeof define === 'function' && define.amd ? define(['exports', 'react', 'prop-types'], factory) : (factory((global.ReactGoodies = {}),global.React,global.PropTypes)); }(this, (function (exports,React,PropTypes) { 'use strict'; var React__default = 'default' in React ? React['default'] : React; PropTypes = PropTypes && PropTypes.hasOwnProperty('default') ? PropTypes['default'] : PropTypes; function noop() {} /** * Takes an argument and if it's an array, returns the first item in the array * otherwise returns the argument * @param {*} arg the maybe-array * @param {*} defaultValue the value if arg is falsey not defined * @return {*} the arg or it's first item */ function unwrapArray(arg, defaultValue) { var _arg = Array.isArray(arg) ? /* istanbul ignore next (preact) */arg[0] : arg; if (!_arg && defaultValue) { return defaultValue; } else { return _arg; } } var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; 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 objectWithoutProperties = function (obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }; 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; }; var ClickOutside = function (_Component) { inherits(ClickOutside, _Component); function ClickOutside() { var _temp, _this, _ret; classCallCheck(this, ClickOutside); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.isTouch = false, _this.setRef = function (ref) { _this.container = ref; }, _this.handle = function (e) { if (e.type === 'touchend') { _this.isTouch = true; } if (e.type === 'click' && _this.isTouch) { return; } var onClickOutside = _this.props.onClickOutside; var el = _this.container; if (!el.contains(e.target)) { onClickOutside(e); } }, _temp), possibleConstructorReturn(_this, _ret); } ClickOutside.prototype.addListener = function addListener() { document.addEventListener('touchend', this.handle, true); document.addEventListener('click', this.handle, true); }; ClickOutside.prototype.removeListener = function removeListener() { document.removeEventListener('touchend', this.handle, true); document.removeEventListener('click', this.handle, true); }; ClickOutside.prototype.componentDidMount = function componentDidMount() { if (!this.props.disabled) { this.addListener(); } }; ClickOutside.prototype.componentDidUpdate = function componentDidUpdate(prevProps) { var disabled = this.props.disabled; /* istanbul ignore else */ if (prevProps.disabled !== disabled) { if (disabled) { this.removeListener(); } else { this.addListener(); } } }; ClickOutside.prototype.componentWillUnmount = function componentWillUnmount() { this.removeListener(); }; ClickOutside.prototype.render = function render() { var children = unwrapArray(this.props.children, noop); return children({ setRef: this.setRef }); }; return ClickOutside; }(React.Component); ClickOutside.propTypes = { children: PropTypes.func, disabled: PropTypes.bool, onClickOutside: PropTypes.func.isRequired }; var IntersectionObserverComp = function (_Component) { inherits(IntersectionObserverComp, _Component); function IntersectionObserverComp() { var _temp, _this, _ret; classCallCheck(this, IntersectionObserverComp); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.state = {}, _this.setRef = function (ref) { _this.domNode = ref; }, _this.onObserve = function (entries) { var thresholds = _this.props.thresholds; _this.setState(Object.keys(thresholds).reduce(function (totalResult, prop) { return _extends({}, totalResult, entries.reduce(function (entriesResult, entry) { var _babelHelpers$extends; return _extends({}, entriesResult, (_babelHelpers$extends = {}, _babelHelpers$extends[prop] = entry.isIntersecting && entry.intersectionRatio >= thresholds[prop], _babelHelpers$extends)); }, {})); }, {})); }, _temp), possibleConstructorReturn(_this, _ret); } IntersectionObserverComp.prototype.componentDidMount = function componentDidMount() { var _props = this.props, thresholds = _props.thresholds, options = _props.options; this.observer = new global.IntersectionObserver(this.onObserve, _extends({}, options, { threshold: Object.keys(thresholds).map(function (prop) { return thresholds[prop]; }) })); this.observer.observe(this.domNode); }; IntersectionObserverComp.prototype.componentWillUnmount = function componentWillUnmount() { if (this.observer && this.observer.disconnect) this.observer.disconnect(); }; IntersectionObserverComp.prototype.render = function render() { var children = unwrapArray(this.props.children, noop); return children(_extends({ setRef: this.setRef }, this.state)); }; return IntersectionObserverComp; }(React.Component); IntersectionObserverComp.propTypes = { children: PropTypes.func.isRequired, options: PropTypes.object, thresholds: PropTypes.object }; IntersectionObserverComp.defaultProps = { thresholds: {}, options: {} }; function unwrapExports (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var getDisplayName_1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.default = getDisplayName; function getDisplayName(Component) { return Component.displayName || Component.name || (typeof Component === 'string' && Component.length > 0 ? Component : 'Unknown'); } }); var getDisplayName = unwrapExports(getDisplayName_1); var isIntersectionObserverSupported = typeof global.IntersectionObserver === 'function'; var withIntersectionObserver = function () { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, thresholds = _ref.thresholds, options = _ref.options, _ref$refKey = _ref.refKey, refKey = _ref$refKey === undefined ? 'setRef' : _ref$refKey; return function (Target) { if (!isIntersectionObserverSupported) { return Target; } var WithIntersectionObserver = function (_Component) { inherits(WithIntersectionObserver, _Component); function WithIntersectionObserver() { var _temp, _this, _ret; classCallCheck(this, WithIntersectionObserver); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.setRef = function (setRef, ref) { setRef(ref); if (typeof _this.props[refKey] === 'function') { _this.props[refKey](ref); } }, _temp), possibleConstructorReturn(_this, _ret); } WithIntersectionObserver.prototype.render = function render() { var _this2 = this; return React__default.createElement( IntersectionObserverComp, { thresholds: thresholds, options: options }, function (_ref2) { var _refProps; var setRef = _ref2.setRef, rest = objectWithoutProperties(_ref2, ['setRef']); var refProps = (_refProps = {}, _refProps[refKey] = _this2.setRef.bind(_this2, setRef), _refProps); return React__default.createElement(Target, _extends({}, _this2.props, refProps, rest)); } ); }; return WithIntersectionObserver; }(React.Component); WithIntersectionObserver.displayName = 'withIntersectionObserverProps(' + getDisplayName(Target) + ')'; return WithIntersectionObserver; }; }; var camel2hyphen = function (str) { return str .replace(/[A-Z]/g, function (match) { return '-' + match.toLowerCase(); }) .toLowerCase(); }; var camel2hyphen_1 = camel2hyphen; var isDimension = function (feature) { var re = /[height|width]$/; return re.test(feature); }; var obj2mq = function (obj) { var mq = ''; var features = Object.keys(obj); features.forEach(function (feature, index) { var value = obj[feature]; feature = camel2hyphen_1(feature); // Add px to dimension features if (isDimension(feature) && typeof value === 'number') { value = value + 'px'; } if (value === true) { mq += feature; } else if (value === false) { mq += 'not ' + feature; } else { mq += '(' + feature + ': ' + value + ')'; } if (index < features.length-1) { mq += ' and '; } }); return mq; }; var json2mq = function (query) { var mq = ''; if (typeof query === 'string') { return query; } // Handling array of media queries if (query instanceof Array) { query.forEach(function (q, index) { mq += obj2mq(q); if (index < query.length-1) { mq += ', '; } }); return mq; } // Handling single media query return obj2mq(query); }; var json2mq_1 = json2mq; var queryToMql = function (query) { return global.matchMedia(json2mq_1(query)); }; var createMediaMatcher = function (query) { var mql = queryToMql(query); return { matches: mql.matches, subscribe: function subscribe(handler) { mql.addListener(handler); return function () { return mql.removeListener(handler); }; } }; }; var MatchMedia = function (_Component) { inherits(MatchMedia, _Component); function MatchMedia(props, context) { classCallCheck(this, MatchMedia); var _this = possibleConstructorReturn(this, _Component.call(this, props, context)); var query = props.query; _this.propsMatchers = Object.keys(query).map(function (prop) { return _extends({ prop: prop }, createMediaMatcher(query[prop])); }); _this.state = _this.propsMatchers.reduce(function (result, propMatcher) { var _babelHelpers$extends; return _extends({}, result, (_babelHelpers$extends = {}, _babelHelpers$extends[propMatcher.prop] = propMatcher.matches, _babelHelpers$extends)); }, {}); return _this; } MatchMedia.prototype.componentDidMount = function componentDidMount() { var _this2 = this; this.unsubscribers = this.propsMatchers.map(function (propMatcher) { return propMatcher.subscribe(function (e) { var _this2$setState; _this2.setState((_this2$setState = {}, _this2$setState[propMatcher.prop] = e.matches, _this2$setState)); }); }); }; MatchMedia.prototype.componentWillUnmount = function componentWillUnmount() { this.unsubscribers.forEach(function (unsubscribe) { return unsubscribe(); }); }; MatchMedia.prototype.render = function render() { var children = unwrapArray(this.props.children, noop); return children(_extends({}, this.state)); }; return MatchMedia; }(React.Component); MatchMedia.propTypes = { query: PropTypes.object, children: PropTypes.func.isRequired }; MatchMedia.defaultProps = { query: {} }; var isMatchMediaSupported = typeof global.matchMedia === 'function'; var withMatchMedia = function () { var query = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return function (Target) { if (!isMatchMediaSupported) { return Target; } var withMatchMedia = function (_Component) { inherits(withMatchMedia, _Component); function withMatchMedia() { classCallCheck(this, withMatchMedia); return possibleConstructorReturn(this, _Component.apply(this, arguments)); } withMatchMedia.prototype.render = function render() { var _this2 = this; return React__default.createElement( MatchMedia, { query: query }, function (props) { return React__default.createElement(Target, _extends({}, _this2.props, props)); } ); }; return withMatchMedia; }(React.Component); withMatchMedia.displayName = 'withMatchMedia(' + getDisplayName(Target) + ')'; return withMatchMedia; }; }; var OnlineStatus = function (_Component) { inherits(OnlineStatus, _Component); function OnlineStatus(props, context) { classCallCheck(this, OnlineStatus); var _this = possibleConstructorReturn(this, _Component.call(this, props, context)); _this.handleOnline = function () { _this.setState({ isOnline: true, isOffline: false }); }; _this.handleOffline = function () { _this.setState({ isOnline: false, isOffline: true }); }; var onLine = global.navigator.onLine; _this.state = { isOnline: onLine, isOffline: !onLine }; return _this; } OnlineStatus.prototype.componentDidMount = function componentDidMount() { global.addEventListener('online', this.handleOnline, false); global.addEventListener('offline', this.handleOffline, false); }; OnlineStatus.prototype.componentWillUnmount = function componentWillUnmount() { global.removeEventListener('online', this.handleOnline); global.removeEventListener('offline', this.handleOffline); }; OnlineStatus.prototype.render = function render() { var children = unwrapArray(this.props.children, noop); return children(_extends({}, this.state)); }; return OnlineStatus; }(React.Component); OnlineStatus.propTypes = { children: PropTypes.func.isRequired }; var isOnlineStatusSupported = global.navigator && typeof global.navigator.onLine !== 'undefined'; var identity = function (x) { return x; }; var withOnlineStatus = function () { var mapStatusToProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : identity; return function (Target) { if (!isOnlineStatusSupported) { return Target; } var withOnlineStatus = function (_Component) { inherits(withOnlineStatus, _Component); function withOnlineStatus() { classCallCheck(this, withOnlineStatus); return possibleConstructorReturn(this, _Component.apply(this, arguments)); } withOnlineStatus.prototype.render = function render() { var _this2 = this; return React__default.createElement( OnlineStatus, null, function (props) { return React__default.createElement(Target, _extends({}, _this2.props, mapStatusToProps(props))); } ); }; return withOnlineStatus; }(React.Component); withOnlineStatus.displayName = 'withOnlineStatus(' + getDisplayName(Target) + ')'; return withOnlineStatus; }; }; var getVisibilityStatus = function (visibilityState) { return { isVisible: visibilityState === 'visible', isHidden: visibilityState === 'hidden', isPrerendered: visibilityState === 'prerender', isUnloaded: visibilityState === 'unloaded' }; }; var PageVisibility = function (_Component) { inherits(PageVisibility, _Component); function PageVisibility(props, context) { classCallCheck(this, PageVisibility); var _this = possibleConstructorReturn(this, _Component.call(this, props, context)); _this.onVibisilityChange = function () { _this.setState(getVisibilityStatus(document.visibilityState)); }; _this.state = getVisibilityStatus(document.visibilityState); return _this; } PageVisibility.prototype.componentDidMount = function componentDidMount() { document.addEventListener('visibilitychange', this.onVibisilityChange, false); }; PageVisibility.prototype.componentWillUnmount = function componentWillUnmount() { document.removeEventListener('visibilitychange', this.onVibisilityChange); }; PageVisibility.prototype.render = function render() { var children = unwrapArray(this.props.children, noop); return children(_extends({}, this.state)); }; return PageVisibility; }(React.Component); PageVisibility.propTypes = { children: PropTypes.func.isRequired }; var isPageVisibilitySupported = global.document && typeof global.document.visibilityState !== 'undefined'; var identity$1 = function (x) { return x; }; var withPageVisibility = function () { var mapStatusToProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : identity$1; return function (Target) { if (!isPageVisibilitySupported) { return Target; } var withPageVisibility = function (_Component) { inherits(withPageVisibility, _Component); function withPageVisibility() { classCallCheck(this, withPageVisibility); return possibleConstructorReturn(this, _Component.apply(this, arguments)); } withPageVisibility.prototype.render = function render() { var _this2 = this; return React__default.createElement( PageVisibility, null, function (props) { return React__default.createElement(Target, _extends({}, _this2.props, mapStatusToProps(props))); } ); }; return withPageVisibility; }(React.Component); withPageVisibility.displayName = 'withPageVisibility(' + getDisplayName(Target) + ')'; return withPageVisibility; }; }; exports.ClickOutside = ClickOutside; exports.IntersectionObserverComp = IntersectionObserverComp; exports.withIntersectionObserver = withIntersectionObserver; exports.MatchMedia = MatchMedia; exports.withMatchMedia = withMatchMedia; exports.OnlineStatus = OnlineStatus; exports.withOnlineStatus = withOnlineStatus; exports.PageVisibility = PageVisibility; exports.withPageVisibility = withPageVisibility; Object.defineProperty(exports, '__esModule', { value: true }); }))); //# sourceMappingURL=react-goodies.umd.js.map