UNPKG

rezponsive

Version:

React decorator for responsive behaviors

236 lines (189 loc) 9.14 kB
"use strict"; exports.__esModule = true; exports["default"] = Rezponsive; exports.RezponsiveConsumer = RezponsiveConsumer; exports.RezponsiveContext = void 0; var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _extends() { _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; }; return _extends.apply(this, arguments); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var canUseDOM = !!(typeof window !== "undefined" && window.document && window.document.createElement); // eslint-disable-next-line @typescript-eslint/no-var-requires var MQ = require("mediaquery"); var RezponsiveContext = /*#__PURE__*/_react["default"].createContext({}); exports.RezponsiveContext = RezponsiveContext; function isTouchDevice() { // unsupported browser such as IE11 are desktop only and will correctly // return false return window.matchMedia("(pointer: coarse)").matches; } var isObject = function isObject(a) { return a !== undefined && a !== null && typeof a === "object"; }; var isDifferent = function isDifferent(a, b) { return Object.keys(a).some(function (el) { return a[el] !== b[el]; }); }; function Rezponsive(Element) { var RezponsiveComponent = /*#__PURE__*/function (_Component) { _inheritsLoose(RezponsiveComponent, _Component); RezponsiveComponent.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) { if (!canUseDOM) return null; // short circuit for invalid clientMedia if (!isObject(props.clientMedia)) return null; // no previous clientMedia defined if (!isObject(state.prevClientMedia)) { // override the currentMedia with the newly passed clientMedia prop if (isDifferent(props.clientMedia, state.currentMedia) || props.isTouch !== state.isTouch) { return { prevClientMedia: props.clientMedia, currentMedia: props.clientMedia, prevIsTouch: props.isTouch, isTouch: props.isTouch }; } else { return null; } } var needsIsTouchUpdate = props.isTouch !== state.prevIsTouch && props.isTouch !== state.isTouch; var needsClientMediaUpdate = isDifferent(props.clientMedia, state.prevClientMedia) && isDifferent(props.clientMedia, state.currentMedia); // both clientMedia and prevClientMedia are defined and valid if (needsClientMediaUpdate || needsIsTouchUpdate) { return { prevClientMedia: props.clientMedia, currentMedia: props.clientMedia, prevIsTouch: needsIsTouchUpdate ? props.isTouch : props.prevIsTouch, isTouch: needsIsTouchUpdate ? props.isTouch : isTouchDevice() }; } return null; }; function RezponsiveComponent(props) { var _this; _this = _Component.call(this, props) || this; _defineProperty(_assertThisInitialized(_this), "skipInitialCheck", void 0); _defineProperty(_assertThisInitialized(_this), "state", void 0); _defineProperty(_assertThisInitialized(_this), "props", void 0); _this.updateMediaQueries = _this.updateMediaQueries.bind(_assertThisInitialized(_this)); var mq = MQ.asArray(props.mq); if (canUseDOM) { var isTouch = props.isTouch !== undefined ? props.isTouch : isTouchDevice(); var initialCurrentMedia = props.clientMedia || mq.reduce(function (matches, q, index, mq) { if (index === mq.length) { matches[q[0]] = true; } else { matches[q[0]] = false; } return matches; }, {}); _this.skipInitialCheck = props.clientMedia !== undefined; _this.state = { prevClientMedia: props.clientMedia, prevIsTouch: props.isTouch, mm: window.matchMedia, mq: mq, isTouch: isTouch, currentMedia: initialCurrentMedia }; } else { _this.state = { isTouch: props.isTouchOnServer, currentMedia: {} }; _this.state.currentMedia = props.serverMedia; } return _this; } var _proto = RezponsiveComponent.prototype; _proto.componentDidMount = function componentDidMount() { var _this2 = this; if (this.props.disableListeners) return; this.updateMediaQueries(); var _this$state = this.state, mm = _this$state.mm, mq = _this$state.mq; Object.keys(mq).forEach(function (q) { mm(mq[q]).addListener(_this2.updateMediaQueries); }); }; _proto.componentWillUnmount = function componentWillUnmount() { var _this3 = this; if (this.props.disableListeners) return; var _this$state2 = this.state, mm = _this$state2.mm, mq = _this$state2.mq; Object.keys(mq).forEach(function (q) { mm(mq[q]).removeListener(_this3.updateMediaQueries); }); }; _proto.updateMediaQueries = function updateMediaQueries() { var _this$state3 = this.state, mm = _this$state3.mm, mq = _this$state3.mq, currentMedia = _this$state3.currentMedia, skipInitialMatch = _this$state3.skipInitialMatch; if (this.skipInitialCheck) { this.skipInitialCheck = false; return; } var newMedia = mq.reduce(function (matches, q) { matches[q[0]] = mm(q[1]).matches; return matches; }, {}); var needsUpdate = Object.keys(newMedia).reduce(function (shouldUpdate, query) { return shouldUpdate || newMedia[query] !== currentMedia[query]; }, false); if (needsUpdate) { this.setState({ currentMedia: mq.reduce(function (matches, q) { matches[q[0]] = mm(q[1]).matches; return matches; }, {}) }); } }; _proto.render = function render() { return /*#__PURE__*/_react["default"].createElement(RezponsiveContext.Provider, { value: { isTouch: this.state.isTouch, currentMedia: this.state.currentMedia } }, /*#__PURE__*/_react["default"].createElement(Element, _extends({ isTouch: this.state.isTouch, currentMedia: this.state.currentMedia }, this.props))); }; return RezponsiveComponent; }(_react.Component); RezponsiveComponent.propTypes = { mq: _propTypes["default"].object, isTouchOnServer: _propTypes["default"].bool, isTouch: _propTypes["default"].bool, serverMedia: _propTypes["default"].object, clientMedia: _propTypes["default"].object, disableListeners: _propTypes["default"].bool }; RezponsiveComponent.defaultProps = { mq: { all: "all" }, isTouchOnServer: false, serverMedia: { all: true }, disableListeners: false }; return RezponsiveComponent; } function RezponsiveConsumer(Element) { return function (props) { return /*#__PURE__*/_react["default"].createElement(RezponsiveContext.Consumer, null, function (ctx) { return /*#__PURE__*/_react["default"].createElement(Element, _extends({}, ctx, props)); }); }; } //# sourceMappingURL=rezponsive.js.map