我开始用styled-components编写自己的设计系统。但是我一直在努力使组件具有响应能力。
// 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
},{}
)
一切正常。所有CSS都捆绑成块文件,控制台上没有错误或错误出现。我的预期结果是媒体查询值的顺序,该组件的屏幕尺寸后面紧跟max-width
。但是我的实际结果是@media screen and (min-width: 576px) {...}
,它与${isFluid ? '' : media.sm`max-width: 576px;`}
捆绑在一起,覆盖了其他查询。有什么想法吗?