react-media-mixin
Version:
A React mixin to update state in response to media query events.
147 lines (123 loc) • 3.8 kB
JavaScript
;
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;
};
;
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);