Giter VIP home page Giter VIP logo

react-responsive's Introduction

react-responsive NPM version Downloads

Information

Packagereact-responsive
Description Media queries in react for responsive design
Browser Version >= IE6*
Demo

The best supported, easiest to use react media query module.

Install

$ npm install react-responsive --save

Example Usage

With Hooks

Hooks is a new feature available in 8.0.0!

import React from 'react'
import { useMediaQuery } from 'react-responsive'

const Example = () => {
  const isDesktopOrLaptop = useMediaQuery({
    query: '(min-width: 1224px)'
  })
  const isBigScreen = useMediaQuery({ query: '(min-width: 1824px)' })
  const isTabletOrMobile = useMediaQuery({ query: '(max-width: 1224px)' })
  const isPortrait = useMediaQuery({ query: '(orientation: portrait)' })
  const isRetina = useMediaQuery({ query: '(min-resolution: 2dppx)' })

  return <div>
    <h1>Device Test!</h1>
    {isDesktopOrLaptop && <p>You are a desktop or laptop</p>}
    {isBigScreen && <p>You  have a huge screen</p>}
    {isTabletOrMobile && <p>You are a tablet or mobile phone</p>}
    <p>Your are in {isPortrait ? 'portrait' : 'landscape'} orientation</p>
    {isRetina && <p>You are retina</p>}
  </div>
}

With Components

import MediaQuery from 'react-responsive'

const Example = () => (
  <div>
    <h1>Device Test!</h1>
    <MediaQuery minWidth={1224}>
      <p>You are a desktop or laptop</p>
      <MediaQuery minWidth={1824}>
        <p>You also have a huge screen</p>
      </MediaQuery>
    </MediaQuery>
    <MediaQuery minResolution="2dppx">
      {/* You can also use a function (render prop) as a child */}
      {(matches) =>
        matches
          ? <p>You are retina</p>
          : <p>You are not retina</p>
      }
    </MediaQuery>
  </div>
)

API

Using Properties

To make things more idiomatic to react, you can use camel-cased shorthands to construct media queries.

For a list of all possible shorthands and value types see https://github.com/contra/react-responsive/blob/master/src/mediaQuery.ts#L9.

Any numbers given as shorthand will be expanded to px (1234 will become '1234px').

The CSS media queries in the example above could be constructed like this:

import React from 'react'
import { useMediaQuery } from 'react-responsive'

const Example = () => {
  const isDesktopOrLaptop = useMediaQuery({ minWidth: 1224 })
  const isBigScreen = useMediaQuery({ minWidth: 1824 })
  const isTabletOrMobile = useMediaQuery({ maxWidth: 1224 })
  const isPortrait = useMediaQuery({ orientation: 'portrait' })
  const isRetina = useMediaQuery({ minResolution: '2dppx' })

  return (
    <div>
      ...
    </div>
  )
}

Forcing a device with the device prop

At times you may need to render components with different device settings than what gets automatically detected. This is especially useful in a Node environment where these settings can't be detected (SSR) or for testing.

Possible Keys

orientation, scan, aspectRatio, deviceAspectRatio, height, deviceHeight, width, deviceWidth, color, colorIndex, monochrome, resolution and type

Possible Types

type can be one of: all, grid, aural, braille, handheld, print, projection, screen, tty, tv or embossed

Note: The device property always applies, even when it can be detected (where window.matchMedia exists).

import { useMediaQuery } from 'react-responsive'

const Example = () => {
  const isDesktopOrLaptop = useMediaQuery(
     { minDeviceWidth: 1224 },
     { deviceWidth: 1600 } // `device` prop
  )

  return (
    <div>
      {isDesktopOrLaptop &&
        <p>
          this will always get rendered even if device is shorter than 1224px,
          that's because we overrode device settings with 'deviceWidth: 1600'.
        </p>
      }
    </div>
  )
}

Supplying through Context

You can also pass device to every useMediaQuery hook in the components tree through a React Context. This should ease up server-side-rendering and testing in a Node environment, e.g:

Server-Side Rendering
import { Context as ResponsiveContext } from 'react-responsive'
import { renderToString } from 'react-dom/server'
import App from './App'

...
  // Context is just a regular React Context component, it accepts a `value` prop to be passed to consuming components
  const mobileApp = renderToString(
    <ResponsiveContext.Provider value={{ width: 500 }}>
      <App />
    </ResponsiveContext.Provider>
  )
...
Testing
import { Context as ResponsiveContext } from 'react-responsive'
import { render } from '@testing-library/react'
import ProductsListing from './ProductsListing'

describe('ProductsListing', () => {
  test('matches the snapshot', () => {
    const { container: mobile } = render(
      <ResponsiveContext.Provider value={{ width: 300 }}>
        <ProductsListing />
      </ResponsiveContext.Provider>
    )
    expect(mobile).toMatchSnapshot()

    const { container: desktop } = render(
      <ResponsiveContext.Provider value={{ width: 1000 }}>
        <ProductsListing />
      </ResponsiveContext.Provider>
    )
    expect(desktop).toMatchSnapshot()
  })
})

Note that if anything has a device prop passed in it will take precedence over the one from context.

onChange

You can use the onChange callback to specify a change handler that will be called when the media query's value changes.

import React from 'react'
import { useMediaQuery } from 'react-responsive'

const Example = () => {

  const handleMediaQueryChange = (matches) => {
    // matches will be true or false based on the value for the media query
  }
  const isDesktopOrLaptop = useMediaQuery(
    { minWidth: 1224 }, undefined,  handleMediaQueryChange
  );

  return (
    <div>
      ...
    </div>
  )
}
import React from 'react'
import MediaQuery from 'react-responsive'

const Example = () => {

  const handleMediaQueryChange = (matches) => {
    // matches will be true or false based on the value for the media query
  }

  return (
    <MediaQuery minWidth={1224} onChange={handleMediaQueryChange}>
      ...
    </MediaQuery>
  )
}

Easy Mode

That's it! Now you can create your application specific breakpoints and reuse them easily. Here is an example:

import { useMediaQuery } from 'react-responsive'

const Desktop = ({ children }) => {
  const isDesktop = useMediaQuery({ minWidth: 992 })
  return isDesktop ? children : null
}
const Tablet = ({ children }) => {
  const isTablet = useMediaQuery({ minWidth: 768, maxWidth: 991 })
  return isTablet ? children : null
}
const Mobile = ({ children }) => {
  const isMobile = useMediaQuery({ maxWidth: 767 })
  return isMobile ? children : null
}
const Default = ({ children }) => {
  const isNotMobile = useMediaQuery({ minWidth: 768 })
  return isNotMobile ? children : null
}

const Example = () => (
  <div>
    <Desktop>Desktop or laptop</Desktop>
    <Tablet>Tablet</Tablet>
    <Mobile>Mobile</Mobile>
    <Default>Not mobile (desktop or laptop or tablet)</Default>
  </div>
)

export default Example

And if you want a combo (the DRY way):

import { useMediaQuery } from "react-responsive"

const useDesktopMediaQuery = () =>
  useMediaQuery({ query: "(min-width: 1280px)" })

const useTabletAndBelowMediaQuery = () =>
  useMediaQuery({ query: "(max-width: 1279px)" })

const Desktop = ({ children }) => {
  const isDesktop = useDesktopMediaQuery()

  return isDesktop ? children : null
}

const TabletAndBelow = ({ children }) => {
  const isTabletAndBelow = useTabletAndBelowMediaQuery()

  return isTabletAndBelow ? children : null
}

Browser Support

Out of the box

Chrome 9
Firefox (Gecko) 6
MS Edge All
Internet Explorer 10
Opera 12.1
Safari 5.1

With Polyfills

Pretty much everything. Check out these polyfills:

react-responsive's People

Contributors

bessonov avatar borozcod avatar brkc avatar cesarandreu avatar chozzz avatar chrisski avatar colindresj avatar comonadd avatar eightypop avatar frederickfogerty avatar herdismaria avatar ignatiusreza avatar isacjunior avatar jdlehman avatar jessepinho avatar jesstelford avatar jordrake avatar kud avatar michalpleszczynski avatar modosc avatar ncochard avatar pekeler avatar phated avatar rexxars avatar rmdort avatar skydan avatar sonaye avatar tomekmularczyk avatar vbfox avatar yocontra avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.