javascript - 制作响应式组件烘干机

标签 javascript reactjs styled-components react-props react-component

我有以下代码来帮助我在样式组件中进行响应式设计:

const breakpoints = {
  tablet: "769px",
  desktop: "1024px",
  widescreen: "1216px",
  fullhd: "1408px"
};

const gridCSS = ({ bg, color }) => css`
  background-color: ${bg};
  color: ${color};
`;

const responsiveGrid = (key, prop) =>
  prop &&
  css`
    @media screen and (min-width: ${breakpoints[key]}) {
      color: ${prop.color};
      background-color: ${prop.bg};
    }
  `;

const Grid = styled.div(
  ({ color, bg, desktop, tablet }) => css`
  display: grid;
  justify-content: center;
  align-content: center;
  min-height: 100vh;
  ${responsiveGrid("tablet", tablet)}
  ${responsiveGrid("desktop", desktop)}
  ${gridCSS}
`
);

function App() {
  return (
    <Grid
      color="orange"
      bg="lightgreen"
      tablet={{
        color: "green",
        bg: "orange"
      }}
      desktop={{
        color: "yellow",
        bg: "purple"
      }}
    >
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
      </div>
    </Grid>
  );
}

现在这可以按照我想要的方式工作了。文本和背景颜色根据屏幕尺寸而变化。

但是,我想指出代码中的一定重复性:

例如,gridCSS 函数包含与 responsiveGrid 函数完全相同的 css 属性和 prop 名称。它们都有 colorbackground-color 属性,并且都引用 colorbg 属性。

但是,如果我尝试将gridCSS注入(inject)`responsiveGrid,它就不起作用。 换句话说,这是有效的:

const responsiveGrid = (key, {bg, color}) =>
  (color || bg) &&
  css`
    @media screen and (min-width: ${breakpoints[key]}) {
      color: ${color};
      background-color: ${bg};
    }
  `;

但这不起作用:

const responsiveGrid = (key, {bg, color}) =>
  (color || bg) &&
  css`
    @media screen and (min-width: ${breakpoints[key]}) {
      ${gridCSS}
    }
  `;

所以,我想知道是否有一种方法可以为 css 属性名称及其相应的 props 提供一个中心位置,而不必编写两次(一次在 gridCSS 中)函数并在 responsiveGrid 函数中第二次。

请注意,我正在寻找的最终结果如下:

function App() {
  return (
    <Grid
      color="orange"
      bg="lightgreen"
      tablet={{
        color: "green",
        bg: "orange"
      }}
      desktop={{
        color: "yellow",
        bg: "purple"
      }}
    >
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
      </div>
    </Grid>
  );
}

这样我就可以在没有任何媒体查询的情况下设置 colorbg 属性,并在媒体查询属性中设置相同属性,例如平板电脑桌面

有什么想法吗?

谢谢。

附注如果有帮助,这里是上述代码的代码和框:https://codesandbox.io/s/vigorous-brook-ughkv?fontsize=14

最佳答案

这是我想出的解决方案:

const breakpoints = {
  tablet: {
    value: 769,
    unit: "px"
  },
  desktop: {
    value: 1024,
    unit: "px"
  },
  widescreen: {
    value: 1216,
    unit: "px"
  },
  fullhd: {
    value: 1408,
    unit: "px"
  }
};

const breakpointKeys = Object.keys(breakpoints);

const gridCSS = ({ bg, textColor, ...props }) => {
  let mediaQueryCSS = breakpointKeys.map(key => {
    let mediaQuery = breakpoints[key].value + breakpoints[key].unit;
    let newMQ = mediaQuery - 1
    console.log(newMQ)

    return css`
      @media screen and (min-width: ${mediaQuery}) {
        color: ${props[key] && props[key].textColor};
        background-color: ${props[key] && props[key].bg};
      }
    `;
  });

  return css`
    background-color: ${bg};
    color: ${textColor};
    ${mediaQueryCSS};
  `;
};

const Grid = styled.div(
  ({ color, bg, desktop, tablet }) => css`
    display: grid;
    justify-content: center;
    align-content: center;
    min-height: 100vh;
    ${gridCSS}
  `
);

function App() {
  return (
    <Grid
      textColor="orange"
      bg="lightgreen"
      tablet={{
        textColor: "green",
        bg: "orange"
      }}
      desktop={{
        textColor: "yellow",
        bg: "purple"
      }}
    >
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
      </div>
    </Grid>
  );
}

关于javascript - 制作响应式组件烘干机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58078177/

相关文章:

javascript - 如何(使用 React JS Web)和 Firestore,您能否找出聊天室(在 Firestore 数据库上)何时收到新消息?

css - 可重用样式组件的小调整

javascript - 如何使用 styled-components 更改其他组件中单个组件的样式?

javascript - 将 js 变量定义为全局会导致任何安全问题吗?

javascript - 时区转换层

javascript - 是否可以仅在它们共享的键/属性之间比较两个对象?

javascript - 当所有子复选框都被选中时,标题中的复选框将被选中,当其中一个复选框未被选中时,将被取消选中

javascript - 如何避免在 React 的嵌套列表中重新呈现

html - 缩放元素时,部分边框在 Firefox 上不可见

javascript - 在 React Native 中使用样式化组件捕获 Pressable press