2.2.1 • Published 4 years ago

styled-break v2.2.1

Weekly downloads
2
License
MIT
Repository
github
Last release
4 years ago

styled-break

npm GitHub PRs Welcome tylim88

🍨 Create your responsive styled components with breeze using custom Styled Components HOC!

  • minimalist api, less import more styling!
  • declarative, highly abstracted yet powerful!
  • 0 dependency, small footprint!
  • tested and production ready!

🙌 Mapping now available in 2.0.0!

🚨 Latest update 2.1.0: fix React unrecognized prop warning.

Installation

npm i styled-break

Demo

Try it at Code Sandbox!

Usage

import React from 'react'
import { render } from 'react-dom'
import styledBreak from 'styled-break'
import { css } from 'styled-components'

const config = {
	breakpoints: {
		xs: 0,
		sx: 501,
		sm: 576,
		md: 768,
		lg: 992,
		xl: 1200,
	},
	sLevel: 3,
}

const { styledHOC } = styledBreak(config)

const DivStyled = styledHOC((
	// disable eslint for next line
	// eslint-disable-next-line
	{ width, bottomLeftRadius, color, ...restProps } // avoid passing prop to DOM element
) => <div {...restProps} />)()

const mappingProp = JSON.stringify({
	_: [5, 5, 5],
	xs_m: [10, 10, 10],
	sm_md: [20, 20, 20],
	xl: [30, 30, 30],
})

const mappingValue = (a, b, c) => css`
	border-radius: ${a}px ${b}px ${c}px ${props => props.bottomLeftRadius}px;
`

const Demo = () => {
	return (
		<DivStyled
			width='500'
			bottomLeftRadius={50}
			color='cyan'
			styledCss={{
				_: `background-color: green;
          width: 150px;
          height: 150px;
        `,
				xs_m: `width: 100px;
          height: 100px;
          background-color: blue;
        `,
				sm_md: css({
					width: '200px',
					height: '200px',
					backgroundColor: 'red',
				}),
				lg: props => `background-color:${props.color};`,
				xl: css`
					${props =>
						`width: ${props.width}px;
          height: 300px;
          background-color: purple;`}
				`,
				[mappingProp]: mappingValue,
			}}
		/>
	)
}

render(<Demo />, document.getElementById('root'))

which is equivalent to

background-color: green;
width: 150px;
height: 150px;
border-radius: 5px 5px 5px 50px;

@media (max-width: 500.98px) {
	width: 100px;
	height: 100px;
	background-color: blue;
}

@media (min-width: 576px) and (max-width: 991.98px) {
	width: 200px;
	height: 200px;
	background-color: red;
}

@media (min-width: 1200px) {
	width: 500px;
	height: 300px;
	background-color: purple;
}

@media (max-width: 500.98px) {
	border-radius: 10px 10px 10px 50px;
}

@media (min-width: 576px) and (max-width: 991.98px) {
	border-radius: 20px 20px 20px 50px;
}

@media (min-width: 992px) {
	background-color: cyan;
}

@media (min-width: 1200px) {
	border-radius: 30px 30px 30px 50px;
}

Core utilities

1. styledBreak(config)

const config = {
	breakpoints: {
		xs: 0,
		sx: 501,
		sm: 576,
		md: 768,
		lg: 992,
		xl: 1200,
	},
	sLevel: 3,
}

const { cssR, styledR, styledHOC } = styledBreak(config)

config

  • config(optional): object made of breakpoints and sLevel props.

    • breakpoints(optional): object where default value is bootstrap breakpoints: {xs: 0, sm: 576, md: 768, lg: 992, xl: 1200}. You can define as many breakpoints you want.
      • props: you can name your breakpoint whatever name you want, ⚠️however please avoid including underscore _ in props name.
      • values: The value should be the minimum value of your breakpoint (the unit is px).
    • sLevel(optional): is global setting of class specificity level, default value is one. You can nest specificity level individually to have finer control on class specificity level.

the output of styledBreak are styledR and styledHOC HOC plus a cssR helper function.

2. styledCss

const styledCss = {
	xs_m: `width: 100px;`,
	sm_md: `width: 200px;`,
	xl: css`
		${props => `width: ${props.width}px;`}
	`,
}

this is your responsive object, the props name have 4 combination for every breakpoint, let take break point xs, sm and md as example where minimum of xs is 0, sm is 576 and md is 768.

here is how you do without, max, min, only, and between query:

a.without

to write style with no media query, name your prop as _

const styledCss = { _: `width: 100px;` }

which equivalent to

width: 100px;

this advantage of this over String Form is, this can be written together with media queries.

b.min

append _n or nothing anything to the breakpoint prop name:

const styledCss = { xs: `width: 100px;` }
// OR
const styledCss = { xs_n: `width: 100px;` }

which equivalent to

@media (min-width: 0px) {
	width: 100px;
}

c.max

append _m to the breakpoint prop name:

const styledCss = { sm_m: `width: 100px;` }

which equivalent to

@media (max-width: 575.98px) {
	width: 100px;
}

the value max width is next breakpoint - 0.02

if there is no next breakpoint, the value is 999999

d.between

append _anotherBreakpointName to the breakpoint prop name:

const styledCss = { xs_sm: `width: 100px;` }

which equivalent to

@media (min-width: 0px) and (max-width: 767.98px) {
	width: 100px;
}

it takes xs min width and md max width.

e.only

append _o or _theSameBreakpointName to the breakpoint prop name:

const styledCss = { xs_o: `width: 100px;` }
// OR
const styledCss = { xs_xs: `width: 100px;` }

which equivalent to

@media (min-width: 0px) and (max-width: 575.98px) {
	width: 100px;
}

It takes xs min width and xs max width.

Default Values

if the 1st breakpoint doesn't exist, the whole media query doesn't exist, no style would be applied.

if the 1st breakpoint exist but 2nd breakpoint doesn't exist, such as appending _randomZT2t2, there would be no 2nd media query, which mean, it has only min media query.

String Form

styledCss can also be just string without any breakpoint needed, which mean the style is applied without any media query.

const styledCss = `width: 100px;`

However if you need to write non media query style together with media query style, it is better to use without.

Function Interpolation

Of course you can interpolate function just like you do in Styled Component (because that is the whole point), simply use Styled Component css helper function.

import { css } from 'styled-components'

// with breakpoints
const styledCss = {
	xs_o: css`
		${props => `width: ${props.width}px;`}
	`,
}

// or without any breakpoint
const styledCss = css`
	${props => `width: ${props.width}px;`}
`

you don't need css helper if you are not doing function interpolation, this is stated in Styled Component doc.

However you can pass function without css helper if the the function is not interpolated in template string:

const styledCss = props => `width: ${props.width}px;`

Class Specificity Level

On top of the septicity you set, you can control individual css property specificity level, the end result is global specificity level times individual specificity level.

// if your global specificity level is 3
const styledCss = {
	_: `width: 50px;`,
	xs: `&&{ width: 100px; }`, // the total specificity level is 2*3 = 6
	md: `width: 200px;`, // the total specificity level is 3
}

Mapping

Mapping is added in 2.0.0, this is useful if you want to repeat a style with different arguments, mapping is carried out by adding a prop in styledCss object.

  • Mapping props: an stringified object literal where:
    • prop: obey the same rule as config breakpoint prop.
    • value: can be array or single value, it will be passed as argument to the mapping value.
  • Mapping value: callback that accept the value from Mapping prop and return string or interpolated string (with the help of css helper).
const mappingProp = JSON.stringify({
	xs_xs: [5, 10, 15, 20],
	_: [100, 100, 100, 100],
	sm_m: [20, 15, 10, 5],
})

const mappingValue = (a, b, c, d) =>
	`border-radius: ${a}px ${b}px ${c}px ${d}px;`

const styledCss = { mappingProp: mappingValue }

which equivalent to

border-radius: 100px 100px 100px 100px;

@media (min-width: 0px) and (max-width: 575.98px) {
	border-radius: 5px 10px 15px 20px;
}

@media (max-width: 575.98px) {
	border-radius: 20px 15px 10px 5px;
}

If you have only one argument, in this case you can drop the array notation(no issue if you keep it as array), finally you can of course do function interpolation.

import { css } from 'styled-components'

const mappingProp = JSON.stringify({ _: 50 })
const mappingValue = a =>
	css`
		border-radius: ${props => props.extraRadius + a}px;
	`

const styledCss = { mappingProp: mappingValue }

Create Responsive Styled Component

1. styledHOC(component)(level) <--Recommended

creates a component that accept styledCSS prop that take styledCSS object (see styledCss for more information).

  • component(required): the component can be Html or React component, see below code for example
  • level(optional): override the sLevel pass to styledBreak, the default value is styledBreak's sLevel.
import { css } from 'styled-components'
//or you also could import it from styled-break
// import { css } from 'styled-break'

// to create styled html component
const DivStyled = styledHOC('div')(1)

// to create a styled react component
const ButtonStyled = styledHOC(Button)(2)

const Demo = () => {
  return (<>
    <ButtonStyled
      styledCss=`width: 100px;`
    />
    <DivStyled
      width='500'
      styledCss={{
        _:`width: 50px;`,
        xs_m: `width:100px;`,
        sm_md: `width:200px;`,
        xl: css`${props =>`width:${props.width}px;`}`,
      }}
    />
  </>
  )
}

reminder: always use css helper to interpolate the function.

2. styledR(component)(styledCss,level)

styledR is basically an extended styled of Styled Component

  • component(required): same as component object described in styledHOC.
  • styledCss(required): same as styledCss object described in styledCss.
  • level(optional): same as level number described in styledHOC.

usage example

// to create styled html component
const DivStyled = styledR('div')(
	{
		xs_o: css`
			${props => `width: ${props.width}px;`}
		`,
	},
	1
)

// to create a styled react component
const ButtonStyled = styledR(Button)(`width: 100px;`, 2)

3. cssR(styledCss,level)

if you don't like to create responsive styled component with styledR or styledHOC and you want to use the convention styled api of Styled Component, then this is what you need.

  • styledCss(required): same as styledCss object described in styledCss.
  • level(optional): same as level number described in styledHOC.
import styled, { css } from 'styled-components'

const DivStyled = styled.div`
  ${cssR({
        _:`width: 50px;`,
        xs_m: `width: 100px;`
        sm_md: `width: 200px;`
        xl: css`${props =>
            `width: ${props.width}px;`
            }`
      }
      ,3 // specificity level (optional)
      )}
`

reminder: always use css helper to interpolate the function.

Acknowledgement

To Do

  • add styledCss prop name for non media query
  • implement map api
  • add more media type
  • further abstraction
2.2.1

4 years ago

2.2.0

4 years ago

2.1.2

4 years ago

2.1.1

4 years ago

2.1.0

4 years ago

2.0.3

4 years ago

2.0.2

4 years ago

2.0.1

4 years ago

2.0.0

4 years ago

2.0.0-beta.0

4 years ago

1.1.0

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago

0.1.10

4 years ago

0.1.11

4 years ago

0.1.12

4 years ago

0.1.8

4 years ago

0.1.9

4 years ago

0.1.7

4 years ago

0.1.6

4 years ago

0.1.5

4 years ago

0.1.4

4 years ago

0.1.2

4 years ago

0.1.3

4 years ago

0.1.1

4 years ago

0.1.0

4 years ago

0.0.10

4 years ago

0.0.11

4 years ago

0.0.9

4 years ago

0.0.8

4 years ago

0.0.7

4 years ago

0.0.6

4 years ago

0.0.5

4 years ago

0.0.4

4 years ago

0.0.1

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.0

4 years ago