Skip to content

Instantly share code, notes, and snippets.

@namxam
Created August 30, 2016 07:23
Show Gist options
  • Save namxam/d106c2f06fdd641334ae528c1f0d4ba1 to your computer and use it in GitHub Desktop.
Save namxam/d106c2f06fdd641334ae528c1f0d4ba1 to your computer and use it in GitHub Desktop.
import React, { Component } from 'react'
const MOBILE_MAX = 480
const TABLET_MAX = 1024
export const mobile = window.matchMedia(`(max-width: ${MOBILE_MAX}px)`)
export const isMobile = () => mobile.matches
export const tablet = window.matchMedia(`(min-width: ${MOBILE_MAX + 1}px) and (max-width: ${TABLET_MAX}px)`)
export const isTablet = () => tablet.matches
export const desktop = window.matchMedia(`(min-width: ${TABLET_MAX + 1}px)`)
export const isDesktop = () => desktop.matches
export const isAtLeastTablet = () => tablet.matches || desktop.matches
// Wrap your components with it like:
// import responsive, { isMobile } from '…'
//
// const MyComponent = ({ children, isMobile }) => { … }
//
// export default responsive(MyComponent, { isMobile: mobile })
export function responsive(WrappedComponent, options = {}) {
const futureProps = Object.keys(options);
class ResponsiveComponent extends Component {
constructor(props) {
super(props)
this.state = futureProps.reduce((result, key) => ({ ...result, [key]: false }), {})
this.mediaQueryChange = this.mediaQueryChange.bind(this)
}
componentDidMount() {
// Add event listeners for all future props
futureProps.forEach( prop => options[prop].addListener(this.mediaQueryChange(prop)) )
// Trigger all event listeners
futureProps.forEach( prop => this.mediaQueryChange(prop)() )
}
componentWillUnmount() {
futureProps
// Remove event listeners for all future props
.forEach( prop => options[prop].removeListener(this.mediaQueryChange(prop)) )
}
mediaQueryChange(prop) {
return () => this.setState({ [prop]: options[prop].matches });
}
render() {
return <WrappedComponent {...this.props} {...this.state} />
}
}
return ResponsiveComponent
}
export function makeResponsive(options = {}) {
return (WrappedComponent) => responsive(WrappedComponent, options)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment