UNPKG

react-mqls

Version:

Javascript media query match for React.js

118 lines (117 loc) 4.35 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = require("react"); const prop_types_1 = __importDefault(require("prop-types")); const pull_1 = __importDefault(require("lodash/pull")); ; const queryPreset = { xs: '(max-width: 575px)', sm: '(min-width: 576px)', md: '(min-width: 768px)', lg: '(min-width: 992px)', xl: '(min-width: 1200px)', xxl: '(min-width: 1600px)', }; class MediaQuery extends react_1.Component { constructor() { super(...arguments); this.mediaQueryList = {}; this.state = { matchedQuery: this.props.queries.reduce((prev, curr) => { return prev.concat(curr.query || queryPreset[curr.preset]); }, []), }; this.getMatched = (targetQuery) => { const { queries } = this.props; if (typeof targetQuery === 'undefined') { return null; } return queries.filter(q => { if (q.query === targetQuery) { return true; } else if (queryPreset[q.preset] === targetQuery) { return true; } return false; })[0]; }; this.cancellableListener = (originQuery, mql) => { if (mql.matches) { const matchedQuery = this.state.matchedQuery.concat(originQuery); this.setState({ matchedQuery, }); } else { const matchedQuery = pull_1.default(this.state.matchedQuery, originQuery); this.setState({ matchedQuery, }); } }; this.cancel = () => { const { queries } = this.props; if (Array.isArray(queries)) { queries.forEach((mql) => { if (this.mediaQueryList[mql.query]) { this.mediaQueryList[mql.query].removeListener(this.cancellableListener); } }); } }; } componentDidMount() { const { targetWindow = window } = this.props; if (typeof targetWindow !== 'object') { return; } if (typeof targetWindow.matchMedia !== 'function') { console.error('Does not support matchMedia'); return; } const { queries } = this.props; if (Array.isArray(queries)) { queries.forEach((mql) => { const { query, preset } = mql; if (query && query.length) { this.mediaQueryList[query] = targetWindow.matchMedia(query); this.cancellableListener(query, this.mediaQueryList[query]); this.mediaQueryList[query].addListener(this.cancellableListener.bind(this, query)); } else if (preset && queryPreset[preset]) { const querySet = queryPreset[preset]; this.mediaQueryList[querySet] = targetWindow.matchMedia(querySet); this.cancellableListener(querySet, this.mediaQueryList[querySet]); this.mediaQueryList[querySet].addListener(this.cancellableListener.bind(this, querySet)); } }); } else { console.error('Does not support type'); return; } } componentWillUnmount() { this.cancel(); } render() { const { matchedQuery } = this.state; const matched = this.getMatched(matchedQuery[matchedQuery.length - 1]); if (matched) { if (typeof matched.component === 'function') { return matched.component(); } return matched.component; } return null; } } MediaQuery.propTypes = { queries: prop_types_1.default.arrayOf(prop_types_1.default.object.isRequired), targetWindow: prop_types_1.default.object, }; exports.default = MediaQuery;