npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-match-breakpoints

v2.0.1

Published

Lightweight, performant and easy to use media query library for React📱 💻 🖥️

Downloads

178

Readme

Define breakpoints configuration once using standard media queries and use it across your project either as components, hooks, HOC, or by simply passing configuration dictionary around.

npm Size PRs Welcome RMB PR Checks CodeFactor Coverage

Table of contents

Motivation

React Match Breakpoints (RMB) goal is to provide a consistent way of handling responsiveness in your React app. RMB works great with CSS-in-JS libraries like styled-components, but you can also find it useful in every tech stack of your choosing. Some highlights:

  • Universal - can be used with ease both in declarative and imperative code. You can use it as a Component, HOC, or hook. It also handles SSR well

  • Consistent - regardless of how it will be used, initial configuration is SSOT.

  • Flexible - allows any media query string that is supported by matchMedia method

  • Performant - built on top of matchMedia API. No window.onresize handlers

  • Lightweight - no dependencies and it only weighs around 2kb (minified and gzipped)

  • Mature - Build using Typescript and tested

Installation

$ npm install react-match-breakpoints

or

$ yarn add react-match-breakpoints

Basic usage

To initialize RMB use initBreakpoints method and wrap your application with returned Provider.

:warning: notice that initBreakpoints is called before the actual app starts to render. This is an intentional and required way of setting up RMB :warning:

import React from 'react'
import { initBreakpoints } from 'react-match-breakpoints'
import App from './App'

const breakpointsConfig = {
  mobile: 'screen and (max-width: 767px)',
  tablet: 'screen and (min-width: 768px) and (max-width: 1024px)',
}

const BreakpointsProvider = initBreakpoints(breakpointsConfig)

ReactDOM.render(
  <BreakpointsProvider>
    <App />
  </BreakpointsProvider>,
  document.getElementById('root'),
)

Using Breakpoint component:

Breakpoint is a singleton and is aware of the configuration that you provided to initBreakpoints method

import React from 'react'
import { Breakpoint } from 'react-match-breakpoints'

const ResponsiveComponent = () => {
  return (
    <Breakpoint.mobile>
      <span>I will be shown on mobile devices</span>
    </Breakpoint.mobile>

    <Breakpoint.tablet>
      <span>I will be shown on tablet devices</span>
    </Breakpoint.tablet>
  )
}

Using useBreakpoints hook

import React from 'react'
import { useBreakpoints } from 'react-match-breakpoints'

const ResponsiveComponent = () => {
  const breakpoints = useBreakpoints()

  const text = breakpoints.mobile ? 'I will be showed on mobile devices' : 'I will be showed on nonmobile devices'

  return <span>{text}</span>
}

Using withBreakpoints HOC

import React from 'react'
import { withBreakpoints } from 'react-match-breakpoints'

const ResponsiveComponent = props => {
  const text = props.breakpoints.mobile ? 'I will be shown on mobile devices' : 'I will be shown on other devices'

  return <span>{text}</span>
}

export default withBreakpoints(ResponsiveComponent)

Support

RMB is supported basically by every browser that implements the full ES5 spec. It might be a good idea to include matchMedia polyfill for some older browsers.

:warning: On browsers that don't support Proxy you won't see warnings if you try to access Breakpoints components that are not defined :warning:

Usage with Typescript

To fully utilize RMB Typescript support you will have to inform RMB of your breakpoints configuration structure. You could do that using declaration merging. First, let's create rmb.d.ts file and extend UserConfig type:

// rmb.d.ts
import { UserConfig } from 'react-match-breakpoints'

declare module 'react-match-breakpoints' {
  export interface UserConfig extends {
    mobile: string,
    tablet: string
  }
}

If you don't want to maintain types separately from your configuration dictionary you can pass it using typeof operator:

// rmb.d.ts
import { UserConfig } from 'react-match-breakpoints'
import config from './breakpoints-config.ts'

type BreakpointsConfig = typeof config

declare module 'react-match-breakpoints' {
  export interface UserConfig extends BreakpointsConfig {}
}

Usage with SSR

RMB can be used together with Server Side Rendering. You have to provide additional breakpoints configuration specific to a server environment. It has to have the same structure as primary configuration with boolean values

import React from 'react'
import { initBreakpoints } from 'react-match-breakpoints'
import App from './App'

const breakpointsConfig = {
  mobile: 'screen and (max-width: 767px)',
  tablet: 'screen and (min-width: 768px) and (max-width: 1024px)',
}

const serverBreakpointsConfig = {
  mobile: true,
  tablet: false,
}

const BreakpointsProvider = initBreakpoints(breakpointsConfig, {
  ssr: {
    config: serverBreakpointsConfig,
  },
})

ReactDOM.render(
  <BreakpointsProvider>
    <App />
  </BreakpointsProvider>,
  document.getElementById('root'),
)

Additionally, you can try to guess the breakpoint during server render using libraries such as useragent. If the breakpoint is guessed incorrectly RMB automatically rerenders this component to show the actual state. This behavior could be disabled using ssr.rehydrate option set to false

API

initBreakpoints(Config, Options)

Used for initializing RMB. Has to be invoked before your application first render

Config

Configuration object. All values should be proper media query strings that could be interpreted by matchMedia method

Options

Options object

| Property | Default value | Description | | ------------------ | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | breakpointCSSClass | false | Controls adding css class to Breakpoint children. Could be useful for example during SSR to visually hide badly guessed breakpoints | | log | process.env.NODE_ENV !== 'production' | Controls debug mode. By default, RMB shows logs only in the development environment | | isServer | typeof window === 'undefined' | Tells RMB if matchMedia should be used or not | | ssr.rehydrate | true | By default RMB will rerender badly guessed breakpoints during SSR. You can turn this behavior off by setting this value to false | | ssr.config | null | SSR configuration object that should resemble the main Config with boolean values |

Arguments

Config (Object): configuration object. See below for details Options (Object): options object. See below for details

Returns

Provider: Provider that has to wrap your application

Example

{
  breakpointCSSClass: false
  log: process.env.NODE_ENV !== 'production',
  isServer: typeof window === 'undefined',
  ssr: {
    rehydrate: false,
    config: null,
  },
}

Breakpoint

Used for accessing Components created from your configuration. Every child of the component will be shown or hidden depending on provided media queries.

Returns

FunctionComponent | nested config part

Example:

import React from 'react'
import { Breakpoint } from 'react-match-breakpoints'

// Provided configuration

// {
//   mobile: {
//     small: 'screen and (max-width: 320px)',
//     big: 'screen and (max-width: 425px)'
//   },
//   tablet: 'screen and (max-width: 425px)'
// }

const ResponsiveComponent = () => {
  return (
    <>
      <Breakpoint.mobile.small>I will be shown on small mobile devices</Breakpoint.mobile.small>

      <Breakpoint.mobile.big>I will be shown on big mobile devices</Breakpoint.mobile.big>

      <Breakpoint.tablet>I will be shown on tablet devices</Breakpoint.tablet>
    </>
  )
}

useBreakpoints()

Hook used for obtaining current breakpoints state.

Returns

Object: An object that resembles provided configuration with boolean values.

Example

import React from 'react'
import { useBreakpoint } from 'react-match-breakpoints'

// Provided configuration

// {
//   mobile: {
//     small: 'screen and (max-width: 320px)',
//     big: 'screen and (max-width: 425px)'
//   },
//   tablet: 'screen and (max-width: 425px)'
// }

const ResponsiveComponent = () => {
  const { mobile, tablet} = useBreakpoints()

  const text = mobile.small
    ? 'I will be shown on mobile devices'
    : tablet
    ? 'I will be shown on tablet devices'
    : 'I will be shown on non-mobile devices' '

  return <span>{text}</span>
}

License

MIT, Copyright © 2018-present Michal Klim