I started to write my own design system with styled-components. But I'm struggling with making my components responsive.
// Container.tsx
import React from 'react'
import styled from 'styled-components'
import { media } from '../utils/mediaQuery'
export const StyledContainer = (isFluid: boolean) => {
return styled(
({ element: Component, containerRef, ...props }) => {
console.log(isFluid)
return (
<Component ref={containerRef} {...props}>
{props.children}
</Component>
)
}
)`
width: 100%; /* Fix component tight to center*/
margin-right: auto;
margin-left: auto;
padding-right: ${({ theme }) => theme.container.paddingX}rem;
padding-left: ${({ theme }) => theme.container.paddingX}rem;
${isFluid ? '' : media.xl`max-width: 1040px;`}
${isFluid ? '' : media.lg`max-width: 960px;`}
${isFluid ? '' : media.md`max-width: 720px;`}
${isFluid ? '' : media.sm`max-width: 576px;`}
`
}
type CProps = {
fluid?: boolean
element?: React.Component | string
children: React.ReactNode | React.ReactNode[]
}
const Container = React.forwardRef(
(props: CProps, ref: React.Ref<HTMLElement>) => {
const { fluid = false, children, element = 'div' } = props
const BaseContainer = StyledContainer(fluid)
return (
<BaseContainer element={element} containerRef={ref}>
{children}
</BaseContainer>
)
}
)
export default Container
// ../../utils/mediaQuery
import {
css,
SimpleInterpolation,
CSSObject,
FlattenSimpleInterpolation,
} from 'styled-components'
export const breakpoints: { [key: string]: number } = {
xl: 1200,
lg: 992,
md: 768,
sm: 576,
xs: 376
}
export const media = Object.keys(breakpoints).reduce(
(
accumulator: {
[key: string]: (
styles: CSSObject | TemplateStringsArray,
...interpolations: SimpleInterpolation[]
) => FlattenSimpleInterpolation
},
label: string
) => {
const size = breakpoints[label]
Object.assign(accumulator, {
[label]: (
styles: CSSObject | TemplateStringsArray,
...interpolations: SimpleInterpolation[]
) => css`
@media screen and (min-width: ${size}px) {
${css(styles, ...interpolations)}
}
`
})
return accumulator
},
{}
)
Everything worked normally. All CSS was bundled into chunked files, there is no bugs or errors appearing on console. My expected result is the order of media queries' values, which component has max-width
following to screen size. But my actual result was @media screen and (min-width: 576px) {...}
, which was bundled from ${isFluid ? '' : media.sm`max-width: 576px;`}
, overriding other queries. Have any ideas what happened?