UNPKG

react-media-mixin

Version:

A React mixin to update state in response to media query events.

147 lines (123 loc) 3.8 kB
"use strict"; var _classProps = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; var _extends = function (child, parent) { child.prototype = Object.create(parent.prototype, { constructor: { value: child, enumerable: false, writable: true, configurable: true } }); child.__proto__ = parent; }; "use strict"; var _ref = require("events"); var EventEmitter = _ref.EventEmitter; var Responsive = (function (EventEmitter) { var Responsive = function Responsive(mediaQueries) { if (mediaQueries === undefined) mediaQueries = {}; this.state = { media: {} }; this.mediaQueryLists = {}; if (Responsive.supportsMatchMedia()) { this.addMediaQueries(mediaQueries); } }; _extends(Responsive, EventEmitter); _classProps(Responsive, { supportsMatchMedia: { writable: true, value: function () { return typeof window !== "undefined" && typeof window.matchMedia === "function"; } } }, { addMediaQueries: { writable: true, value: function (mediaQueries) { var _this = this; Object.keys(mediaQueries).forEach(function (key) { _this.mediaQueryLists[key] = {}; var mediaQuery = mediaQueries[key]; var mediaQueryList = matchMedia(mediaQuery); _this.mediaQueryLists[key].mediaQueryList = mediaQueryList; // Create handler var handler = _this.handleMediaChange.bind(_this, key); _this.mediaQueryLists[key].handler = handler; // Set intial value handler(mediaQueryList); // Listen for changes mediaQueryList.addListener(handler); }); } }, setMediaQueryState: { writable: true, value: function (key, doesMatch, emitChange) { if (emitChange === undefined) emitChange = true; if (this.state.media[key] !== doesMatch) { this.state.media[key] = doesMatch; if (emitChange) { this.emit("change"); } return true; } return false; } }, handleMediaChange: { writable: true, value: function (key, mediaQueryList) { var _this2 = this; if (mediaQueryList === undefined) mediaQueryList = this.mediaQueryLists[key]; return (function () { _this2.setMediaQueryState(key, mediaQueryList.matches); })(); } }, destroy: { writable: true, value: function () { var _this3 = this; Object.keys(this.mediaQueryLists).forEach(function (key) { var mediaQueryList = _this3.mediaQueryLists[key].mediaQueryList; var handler = _this3.mediaQueryLists[key].handler; mediaQueryList.removeListener(handler); }); } }, getMediaState: { writable: true, value: function () { return this.state.media; } } }); return Responsive; })(EventEmitter); var responsive = new Responsive(); // Set to unlimited responsive.setMaxListeners(0); var MediaMixin = { getInitialState: function () { return { media: {} }; }, componentDidMount: function () { this.updateMediaState(); responsive.addListener("change", this.updateMediaState); }, componentWillUnmount: function () { responsive.removeListener("change", this.updateMediaState); }, updateMediaState: function () { this.setState({ media: responsive.getMediaState() }); } }; exports = module.exports = MediaMixin; exports.addMediaQueries = responsive.addMediaQueries.bind(responsive); exports.destroy = responsive.destroy.bind(responsive);