【问题标题】:How to use styled-system responsive props如何使用样式系统响应式道具
【发布时间】:2020-11-14 04:52:27
【问题描述】:

我可以使用styled-system 来实现这样的目标吗?

<MyComponent  
  backgroundImage={{
    default: "https://placekitten.com/380/80",
    sm: "https://placekitten.com/340/80"
  }}
/>

或者这个(因为我知道其他“样式道具”也可以这样做,例如 width,但我更喜欢使用带键的对象):

<MyComponent  
  backgroundImage={[
    "https://placekitten.com/300/80",
    "https://placekitten.com/500/80"
  ]}
/>

我认为上面的代码示例是自我描述的,它们遵循库的模式,但为了清楚起见,我将值(图像源)映射到断点(默认和下一个)。

例如,这是开箱即用的:

<Box
  width={[
    default: 1,
    sm: 1/3,
  ]}
/>

输出是这样的:

.QWojd {
    width: 100%;
}

@media screen and (min-width: 24em) {
    .QWojd {
        width: 33.33333333333333%;
    }
}

我一直在研究源代码,这部分让我觉得它也应该与 backgroundImage 一起使用:

很遗憾,它不起作用,结果是 CSS 输出中的字符串化对象(或串联的数组值)。

我想不出variant 函数在这里会有什么用,正如人们所建议的那样。我尝试使用 system 函数,但我就是无法理解文档。 ResponsiveValue 类型给了我一个提示,但当我试图了解内部结构时,我感觉就像在黑暗中爬行。

最终,我想将“断点对象”(或数组)与我喜欢的任何自定义道具一起使用,如下所示:

<Box
  myProp={[
    default: 'foo',
    sm: 'bar',
  ]}
/>

注意:我(根据经验)了解到,您可以只使用“断点数组”版本(无需在主题中设置断点并将其传递给提供程序),这会将值映射到前 2 个默认断点(不确定它们来自哪里)但是如果您想使用带有键的对象,则需要使用带有您自己断点的主题对象的 ThemeProvider

注意 2:到目前为止,我可以理解样式系统文档:https://styled-system.com/custom-props。当我到达这里时,我觉得这就是我正在寻找的东西,但我无法理解这个例子,这个解释让我更加困惑,我在网上找不到任何例子。

注意 3:Spectrum Chat 有一个风格化系统频道,图书馆作者也在其中,但遗憾的是我无法在那里发送任何消息(不断的网络错误)

Examples

【问题讨论】:

    标签: reactjs typescript styled-components styled-system


    【解决方案1】:

    好的,所以根据文档 (https://styled-system.com/custom-props/),为了创建自定义道具(或者在这种情况下,替换现有道具),您应该使用 system 实用程序。由于我不是该库 (styled-system) 的用户,因此我不能 100% 确定这是正确的方法,但我在您的示例代码之上进行了测试,它似乎可以按您的意愿工作。

    带有数组的组件声明(它也适用于您想要的对象):

    <ResponsiveImageBox
      color="white"
      backgroundImage={[
        "https://placekitten.com/300/80",
        "https://placekitten.com/500/80"
      ]}
    >
      Box 8
    </ResponsiveImageBox>
    

    对象:

    <ResponsiveImageBox
      color="white"
      backgroundImage={{
        default: "https://placekitten.com/300/80",
        sm: "https://placekitten.com/500/80"
      }}
    >
      Box 8
    </ResponsiveImageBox>
    

    这是组件代码:

    export const ResponsiveImageBox = styled(Box)(
      ({ myCustomProp }) => { 
        return css`
          ${system({
            backgroundImage: {
              property: "backgroundImage",
              transform: value => `url(${value})`
            }
          })}
        `
      });
    

    正如您在示例 4、5 和 8 (https://stackblitz.com/edit/styled-system-mccqje?file=Examples.tsx) 中看到的那样,我还为 border-radius 属性做了一个简单的 prop 重命名并指定了我想要更改的 css 属性 (property) ,因此无需添加transform,因为该值将保持不变。

    export const ExtendedBox2 = styled(Box)<ExtendedBoxProps>`
      background-position: center;
    
      ${system({
        myCustomProp: {
          property: "border-radius"
        }
      })}
    `;
    

    看看这是不是你要找的东西! :)

    【讨论】:

      【解决方案2】:

      我知道您已经将其标记为已解决,而 Eduardo 的方法绝对有效。然而,另一种“开箱即用”的方法是使用别名,以便您可以使用对象而不是数组(来源:https://styled-system.com/responsive-styles/):

      // theme.js
      const breakpoints = ['40em', '52em', '64em', '80em']
      
      // aliases
      breakpoints.sm = breakpoints[0]
      breakpoints.md = breakpoints[1]
      breakpoints.lg = breakpoints[2]
      breakpoints.xl = breakpoints[3]
      
      export default {
        breakpoints,
      }
      
      // ResponsiveImageBox.js
      <ResponsiveImageBox
        color="white"
        backgroundImage={{
          md: "https://placekitten.com/300/80",
          sm: "https://placekitten.com/500/80"
        }}
      >
        Box 8
      </ResponsiveImageBox>
      

      【讨论】:

        猜你喜欢
        • 2019-05-11
        • 2020-01-21
        • 2020-02-23
        • 2018-12-18
        • 2018-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多