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

responsive-props

v2.0.1

Published

Responsive props for Styled Components

Downloads

17

Readme

codecov Travis Commitizen friendly semantic-release Greenkeeper badge

Responsive Props 💅

Responsive props for Styled Components.

alt text

responsive-props is a HOC that enhances a styled component with a responsive API, to handle styling based on any number of media queries.

This is useful when a styled component needs to have different styles based on one or more media queries, in different contexts of an application.

A common example of this is a column in a grid, where a column can have a different widths depending on a matching media query. For this particular use case, responsive-props can provide the following API:

// Possibility to target specific media queries and apply styles accordingly
<Row>
  <Column span={{ m: 6, l: 4, xl: 3 }} />
</Row>
// Or pass a single value that will apply styles without any media queries
<Row>
  <Column span={6} />
</Row>

The above example is take from the Styled Flexbox Grid library, which uses responsive-props.

Installation

yarn add responsive-props
# or
npm install responsive-props

Basic Example

The default export of responsive-props is a HOC that takes two parameters. The first parameter is the component to be wrapped/enhanced, and the second parameter is an object containing functions/mixins, that will generate styles for a given media query.

import React from "react";
import styled, { css } from "styled-components";
// responsive-props HOC
import withResponsiveProps from "responsive-props";

// Create a styled-components
const StyledComponent = styled.div`
  width: 200px;
  height: 200px;
  background: palevioletred;

  // Styles returned from mixins targeting specific media queries will be added here
  ${({ responsiveProps }) => responsiveProps}
`;

// Define the mixin `background`
const background = bg => css`
  background: ${bg};
`;

// Wrap `StyledComponent with the `responsive-props` HOC
const WrappedStyledComponent = withResponsiveProps(
  // Wraps `StyledComponent
  StyledComponent,
  {
    // registers ´background` as a mixin
    background: background
  }
);

// Define the breakpoints, passed to `WrappedStyledComponent` `breakpoints` prop bellow
const breakpoints = { xs: 320, s: 576, m: 768, l: 992, xl: 1200 };

// WrappedStyledComponent can now be used in the following way
const Example = () => (
  <WrappedStyledComponent
    background={{ s: "#002635", m: "#013440", l: "#AB1A25" }}
    breakpoints={breakpoints}
  />
);

export default Example;

The above component WrappedStyledComponent, will result in a div in the shaped of a square, with different background colors depending on what media query is matching.

alt text

Notice how different breakpoint are targeted inside of the background prop of WrappedStyledComponent. The value for each breakpoint (#002635, #013430 and #AB1A25) will be passed as the bg parameter of the background mixin, and generate corresponding styled for each media query.

<WrappedStyledComponent
  background={{ s: "#002635", m: "#013440", l: "#AB1A25" }}
  breakpoints={breakpoints}
/>

Also notice that the name of the prop background, matches that of the key background in the object of mixins that is passed to the withResponsiveProps HOC.

const WrappedStyledComponent = withResponsiveProps(
  // Wraps `StyledComponent
  StyledComponent,
  {
    // registers ´background` as a mixin
    background: background
  }
);

Important: The line ${({ responsiveProps }) => responsiveProps} is where styles of each media queries will be inserted. Without this no media queries will be applied to the styled component.

It is possible to register any number of breakpoints with a naming convention of your choice. In the above examples we used the naming convention: xs, s, m, l, xl. However if you for example prefer the convention used by Twitter Bootstrap (xs, sm, md, lg, xl) you could configure the breakpoints like this:

// Define the breakpoints, passed to `WrappedStyledComponent` `breakpoints` prop bellow
const breakpoints = { xs: 320, sm: 576, md: 768, lg: 992, xl: 1200 };

// WrappedStyledComponent can now be used in the following way
const Example = () => (
  <WrappedStyledComponent
    background={{ sm: "papayawhip", md: "palevioletred", lg: "#AB1A25" }}
    breakpoints={breakpoints}
  />
);

Register breakpoints

There are two ways to register the breakpoints for components enhanced by responsive-props.

The first (which has already been demonstrated in the Basic Example is to pass to pass an object of breakpoints to the enhanced component via the breakpoints prop. The other more convenient way is to register the breakpoints inside a theme of the styled-components ThemeProvider.

Via <ThemeProvider /> (recommended)

Putting the breakpoints inside a theme has the benefit of only having to define them once, and not having to remember to include for every component. The breakpoints should be put under the namespace responsiveProps.breakpoints of the theme, as demonstrated bellow.

import React from 'react';
import { ThemeProvider } from 'styled-components';
const theme = {
  responsiveProps: {
    breakpoints: {
      xs: 320,
      s: 576,
      m: 768,
      l: 992,
      xl: 1200
    }
  }
}

// The `breakpoints` prop from the `Basic Example` can now be omitted
const Example = () => (
  <ThemeProvider theme={theme}>
    <WrappedStyledComponent background={{ s: '#002635', m: '#013440', l: '#AB1A25' }} />
  <ThemeProvider theme={theme}>
);

Of course this is a contrived example where the benefit of theme isn't very clear. Normally the ThemeProvider would be placed somewhere higher up the component three, where any component inside the ThemeProvider can omit the breakpoints prop.

Via the breakpoints prop

If your application doesn't make use of ThemeProvider (or you would like to override the default breakpoints provided by theme) it is possible to pass breakpoints via the breakpoints prop, of a component enhanced by responsive-props.

<WrappedStyledComponent breakpoint={{ xs: 320,s: 576,m: 768,l: 992, xl: 1200 }} >

API

The API of a component enhanced by responsive-props is centered around the format of the value, that is passed to the props of the component. They can either be in the form of an object to target specific media queries or a single value to seamlessly act as regular adaptational props.

In React terms the pattern implemented by responsive-props is known as Props Proxy.

Target specific media queries

To target a specific breakpoint an object of breakpoints is passed as the value of the prop. The keys of the of object should be present in the registered breakpoints in order to work.

Bellow the keys (s, m, and l) are the breakpoints to target. The values (#002635, #013440 and #AB1A25) are parameter that will be passed to a mixin/function namned background, responsible for generating styles for the specified breakpoints.

<WrappedStyledComponent
  background={{ s: "#002635", m: "#013440", l: "#AB1A25" }}
/>

This will result in different background colors (#002635, #013440 and #AB1A25) for each breakpoint (s, m, and l).

Single value (without media queries)

If a style should be applied without media queries (i.e. independent of the bowser/viewport width) it is possible to only pass a single value to the same prop, instead of an object of breakpoints.

<WrappedStyledComponent background="#002635" />

This will result in a background color of #002635 for all viewports.

Mixins with multiple parameters

If a mixin accept more than one parameter it is possible to pass the parameter for a given breakpoint in the form on an array. In the example bellow the verticalPadding mixin takes two parameters, the first for top padding and the second for bottom padding.

<WrappedStyledComponent verticalPadding={{ s: ['2rem', '1rem'], m: ['3rem', '2rem'] }}

More detailed snippet of the above example:

// Define the mixin `background`
const verticalPadding = (paddingBottom, paddingTop = 0) => css`
  padding: ${paddingTop} 0 ${paddingBottom} 0;
`;

// Wrap `StyledComponent with the `responsive-props` HOC
const WrappedStyledComponent = withResponsiveProps(
  // Wraps `StyledComponent`
  StyledComponent,
  {
    // registers `verticalPadding` as a mixin
    verticalPadding: verticalPadding
  }
);

// WrappedStyledComponent can now be used in the following way
const Example = () => (
  <WrappedStyledComponent
    verticalPadding={{ s: ["2rem", "1rem"], m: ["3rem", "2rem"] }}
  />
);

v2 migration instructions

innerRef and nodeRef is deprecated as of responsive-props v2. Instead V2 implements the new React.forwardRef API and expects the use of ref prop to get the underlaying DOM element.

responsive-props v2 is compatible with styled-components: ^4.0.0 and react ^16.3.0. Make sure to match these dependencies or consider using an older version.

If you wish to use styled-components v3 use version 1.2.1 of responsive-props. Note that if you're using later versions of React this may throw warnings, updating is recommended.