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

@dbernardi/use-media-query

v1.0.6

Published

A custom React hook for managing javacript based media queries

Downloads

3

Readme

useMediaQuery

useMediaQuery is a custom react hook that allows the use of css media queries in a react environment. It uses the matchMedia api to subscribe to media queries and returns the current breakpoint state. It also provides helper functions to make it easier to use the breakpoint state in your components.

Installation

pnpm add @dbernardi/use-media-query

Usage

While the useMediaQuery hook can be called directly by each component that needs to use it, it is recommended to utilize a global state library to manage the state of the hook in a centralized location. This allows the hook to be consumed by any component in the app, and makes sure the media query state is only subscribed to once.

You can use any state library, for example Redux or Zustand. However, the simplest way to do this is to use React context, which is a built-in feature of React.

Examples are provided in typescript below, but the same concepts apply to javascript. Just remove the type annotations.

  1. Create a context provider that subscribes to the useMediaQuery hook.
// context.tsx
import { createContext } from 'react';
import { useMediaQuery } from '@dbernardi/use-media-query';
import type { UseMediaQueryReturnType, Options } from '@dbernardi/use-media-query';

export const MediaQueryContext = createContext<UseMediaQueryReturnType>({} as UseMediaQueryReturnType);

export const MediaQueryProvider = ({ children, options }: { children: React.ReactElement, options?: Options }) => {
  const mediaQuery = useMediaQuery(options ?? {});
  
  return (
    <MediaQueryContext.Provider value={mediaQuery}> 
      { children }
    </MediaQueryContext.Provider>
  )
}
  1. Wrap the provider around a component high in your app chain and pass in the options you want to use.
// App.tsx
import { MediaQueryProvider } from './context';

function App({children}: {children: React.ReactElement}) {
  return (
    <MediaQueryProvider options={{ breakpoints: { sm: 600, md: 900, lg: 1200 }, rule: 'max-width' }}>
      {children}
    </MediaQueryProvider>
  )
}

export default App;
  1. Now, you can use react's useContext hook in conjuction with MediaQueryContext to consume the breakpoint state:
import { MediaQueryContext } from './context';
import { useContext } from 'react';

function Component() {
  const {
    setClass,
    bpIsGT,
    bpIsLT,
    breakpoints,
  } = useContext(MediaQueryContext);

  return (
    <div style={{ backgroundColor: setClass({default: 'pink', lg: 'red', md: 'blue', sm: 'green'}) }}>
      {bpIsGT('md') && <h1>Show me above md - {breakpoints.md}</h1>}
      {bpIsLT('md') && <h1>Show me below md - {breakpoints.md}</h1>}
    </div>
  )
}

export default Component;

Options

The following options can be passed to the useMediaQuery hook:

| Option | Description | | --- | --- | | breakpoints | An object containing the breakpoints you want to use. The key should be the name of the breakpoint and the value should be the size in pixels. | | rule | The rule to use when subscribing to the media query. Can be either 'min-width' or 'max-width' to denote whether to use a mobile-first or desktop-first media query. Media queries will be constucted as followed: only screen and (${rule}: ${breakpoints[key]}px). |

Default options

The default options are as follows:

breakpoints

const defaultBreakpoints = {
  desktopLg: 1400,
  desktopMd: 1300,
  desktopSm: 1200,
  tabletLg: 1040,
  tabletMd: 991,
  tabletSm: 840,
  mobileLg: 767,
  mobileMd: 540,
  mobileSm: 400,
  mobileXsm: 350
};

rule

'max-width'

Helper functions & return values

In order to allow your components to make use of the breakpoint state, we've provided a series of helper functions, these are automatically returned from the useMediaQuery hook.

const {
  currentBreakpoint,
  bpIsGT,
  bpIsLT,
  setClass,
  breakpoints,
} = useContext(MediaQueryContext);

currentBreakpoint

currentBreakpoint is an object that contains the current breakpoint state. It has the following properties:

| Property | Description | | --- | --- | | name | The name of the current breakpoint. This matches one of the keys in the breakpoints object passed to the useMediaQuery hook. | | value | The size of the current breakpoint in pixels. | | query | The MediaQueryList object that is subscribed to the current breakpoint. | | rule | The rule used to subscribe to the current breakpoint. This is the same as the rule option passed to the useMediaQuery hook. |

bpIsGT - breakpointIsGreaterThan

This function returns a boolean indicating whether the currently active breakpoint is larger than the passed breakpoint param. The breakpoint param is a string that matches one of the keys in breakpoints.

bpIsGt('md')
  ? <p>I will only appear on screens larger than 900px</p>
  : <p>I will only appear on screens smaller than 900px</p>

bpIsLT - breakpointIsLessThan

This function returns a boolean indicating whether the currently active breakpoint is smaller than the passed breakpoint param. The breakpoint param is a string that matches one of the keys in breakpoints.

bpIsLt('md')
  ? <p>I will only appear on screens smaller than 900px</p>
  : <p>I will only appear on screens larger than 900px</p>

setClass

This function is used to return a string (often but not limited to a className) that matches / is adjacent to the currently active breakpoint.

It accepts an object as a param with key value pairs describing which strings should be returned for which matched breakpoints. For each breakpoint, the value of the match will be returned. When the rule option is set to max-width, the breakpoints are read in reverse order, with larger breakpoints active first. This behavior is reversed when the rule option is set to min-width, with smaller breakpoints being active first. When a breakpoint is active, it will remain active until the next breakpoint key finds a match. It is not necessary to provide values for all of the available breakpoints, only the breakpoints at which point the string should change.

This is most commonly used to change the className of an element based on the active breakpoint:

<div className={ setClass({
    default: 'larger-than-md',
    md: 'md-and-below-but-greater-than-sm',
    sm: 'sm-and-below'
  }) }>
  Some content
</div>

However, it can also be used anywhere a string can be used. Another example is to use setClass in association with inline styles:

import { MediaQueryContext } from './context.ts';

const Component = (props) => {
  const { setClass } = useContext(MediaQueryContext);

  const dynamicStyles = {
    width: setClass({ default: '300px', md: '500px' })
  };

  return (
    <div style={ dynamicStyles }>
      Some content
    </div>
  )
}

breakpoints

breakpoints is an object that lists all the available breakpoints. This is identical to the breakpoints option passed to the useMediaQuery hook.