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
JavaScript
(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