This package has been deprecated

Author message:

Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

@klosser/responsive-style
TypeScript icon, indicating that this package has built-in type declarations

1.0.0-apha.2 • Public • Published

@klosser/responsive-style

Functions that take a value or multiple values grouped by breakpoints, and returns an object with CSS declarations and media queries that can be passed to a CSS-in-JS library of choice.

createResponsiveStyle('blue', => color => ({ color }))
// ({ color: blue })

createResponsiveStyle(['blue', { 700: 'red' }], color => ({ color }))
/*({
  color: blue,
  '@media (min-width: 700px)': {
    color: 'red'
  }
})*/

You can also map the values to something else

createResponsiveStyle(color, value => thmeColors[value])
createResponsiveStyle(size, value => ({ textSize: value }))
createResponsiveStyle(variant, value => ({
  backgroundColor: variant === 'dark' ? 'black' : 'white',
  '--text-color': variant !== 'dark' ? 'black' : 'white',
}))

Extractors

Sometimes you want to allow a style like margin or padding to be expressed like:

{ margin: 4 }
{ margin: '30px auto' }
{ margin: { top: 4, x: 'auto' } }
{ margin: [{ y: 8 }, { 400: { top: 20 }}] }

Create a reuseable mapping function that you use in your base components, or use the one provided with in this package.

import { BoxSpacingMapper, createResponsiveStyle } from '@klosser/responsive-style'
createResponsiveStyle(margin, BoxSpacingMapper)
createResponsiveStyle(padding, BoxSpacingMapper)

Media queries

Media queries can either be written manually which can like:

;[
  { color: 'black' },
  {
    '@media (min-width: 700px) and (prefers-color-scheme: dark)': {
      color: 'white',
    },
  },
]

or by just passing a number as a breakpoint:

[{ color: 'red', { 500: { color: 'blue' }}}]

By default those breakpoints assume you implement mobile first, thus the breakpoints are set in (min-width: [breakpoint]px). This can be changed in (options)[#options].

Predefined media queries

If you pass predefined media queries in (options)[#options] you can set them by breakpoint names instead:

const breakpoints = {
  large: 1200,
  medium: 600,
  small: 460,
}
function Text({
  color,
}: {
  color: ResponsiveStyle<keyof typeof themeColors, keyof typeof breakpoints>
}) {
  return (
    <div
      className={css(
        createResponsiveStyle(color, value => themeColors[value]),
        { breakpoints }
      )}
    />
  )
}

;<Text color={['purple-20', { large: 'orange-20' }]} />

Media query collisions

If you merge responsive styles to an object like this example:

className={css({
  ...createResponsiveStyle(color, value => themeColors[value]),
  ...createResponsiveStyle(display),
})}

If both responsive styles include the same media query, only the last one will be included. Either:

  1. Pass a key as the third argument: createResponsiveStyle(color, value => themeColors[value], 'color')
  2. Create unique classnames: cs(css(createResponsiveStyle(display), createResponsiveStyle(textSize)))

Examples

This is a basic example of how you can create a reuseable component that can take a color as a prop, or multiple grouped by breakpoints. The rest of the examples will be shown in tsx.

import React from 'react'
import css from 'emotion'
import { createResponsiveStyle } from '@klosser/responsive-style'

export default function Text({ color, ...rest }) {
  return <div className={css(createResponsiveStyle(color => ({ color })))} {...rest} />
}
import Text from './Text'

export const Example = () => (
  <Text color={['magenta', { 700: 'criomson', 1200: 'black' }]}>Hello World!</Text>
)
<style>
  .gwe3w {
    color: magenta;
  }
  @media (min-width: 700px) {
    .gwe3w {
      color: criomson;
    }
  }
  @media (min-width: 1200px) {
    .gwe3w {
      color: black;
    }
  }
</style>

<div class="gwe3w">Hello World!</div>

Margin & padding
import Box from './Box'

export const Example = () => (
  <Box
    backgroundColor="magenta-20"
    margin={[
      { top: 20 },
      {
        700: {
          top: 40,
          bottom: 20,
        },
      },
    ]}
  />
)
Custom mapping
import Box from './Box'

export const Example = () => (
  <Box
    backgroundColor="magenta-20"
    margin={[
      { top: 20 },
      {
        700: {
          top: 40,
          bottom: 20,
        },
      },
    ]}
  />
)

Readme

Keywords

none

Package Sidebar

Install

npm i @klosser/responsive-style

Weekly Downloads

0

Version

1.0.0-apha.2

License

ISC

Unpacked Size

24.9 kB

Total Files

20

Last publish

Collaborators

  • einarlove