1

我在React中做了一个应用程序,并使用了Grommet库来设计我的组件。我定义了一个主题文件来为不同的移动设备设置断点:

const customBreakpoints = deepMerge(grommet, {
  global: {
    breakpoints: {
      small: {
        value: 768,
        borderSize: {
          xsmall: "1px",
          small: "2px",
          medium: "4px",
          large: "6px",
          xlarge: "12px"
        },
        edgeSize: {
          none: "0px",
          hair: "1px",
          xxsmall: "2px",
          xsmall: "3px",
          small: "6px",
          medium: "12px",
          large: "24px",
          xlarge: "48px"
        },
        size: {
          xxsmall: "24px",
          xsmall: "48px",
          small: "96px",
          medium: "192px",
          large: "384px",
          xlarge: "768px",
          full: "100%"
        }
      },
      medium: { value: 1536 },
      large: {}
    }
  }
});

要布局按钮,我使用了扣眼框组件

const App = () => (
  <Grommet theme={customBreakpoints}>
    <ResponsiveContext.Consumer>
      {size => (
        <div>
          <Box
            direction="column"
            align="center"
            gap="medium"
            pad="small"
            overflow={{
              horizontal: "auto"
            }}
          >
            <Button
              primary
              hoverIndicator="true"
              style={{
                width: "100%"
              }}
              label="Next"
            />
            <Box width="medium" direction="row-responsive">
              <Button
                primary
                icon={<DocumentPdf color="white" />}
                style={{
                  boxSizing: "border-box",
                  background: "red",
                  height: "38px",
                  lineHeight: "24px",
                  fontSize: "18px",
                  fontWeight: 600,
                  paddingLeft: "20px",
                  paddingRight: "20px"
                }}
                label="Export PDF"
              />

              <Button
                primary
                icon={<DocumentPdf color="white" />}
                style={{
                  boxSizing: "border-box",
                  background: "red",
                  height: "38px",
                  lineHeight: "24px",
                  fontSize: "18px",
                  fontWeight: 600,
                  paddingLeft: "20px",
                  paddingRight: "20px"
                }}
                label="Export all"
              />
            </Box>
          </Box>
        </div>
      )}
    </ResponsiveContext.Consumer>
  </Grommet>
);

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

当我运行应用程序并在不同设备上检查当前窗口时,我得到以下输出:

在此处输入图像描述

在此处输入图像描述

即使使用ResponsiveContext.Consumer并设置 width=size} 它也不起作用。

有什么建议么?

我做了一个沙盒示例。

4

1 回答 1

1

按钮不是布局的驱动程序,它们的布局由包装布局组件控制,在您的情况下,它是 codesanbox 上 Grommet 组件下方的 Box 组件。

Box 组件会自动响应您定义的自定义断点,并且似乎可以按预期工作,也就是说,grommet 确实提供了经过精心计算的开箱即用断点定义,您的应用程序无论如何都会将其用作默认断点,因此除非您有自定义断点的特殊要求,使用默认值通常可以解决问题并消除复杂性。

您的代码正在导入 ResponsiveContext,但 ResponsiveContext 没有包装布局组件,也没有使用 size 道具,所以一旦添加了这些,我认为它可以按预期工作。我只div用 ResponsiveContext 替换了(使用 Box 时不需要 div),并将sizewidthprop 添加到 Box 中,如下所示:

    <ResponsiveContext.Consumer>
      {size => (
        <Box
          direction="column"
          align="center"
          gap="medium"
          pad="small"
          overflow={{
            horizontal: "auto"
          }}
          width={size==="small" ? "200px" : "400px"}
        >
   ...

在沙箱中使用上述代码部分将使您更好地了解如何以响应方式控制按钮。您可以根据需要使用width道具上的值,目前,它在“小”屏幕尺寸上将 Button 的宽度设置为 200px,否则使用 400px(我选择了随机值),您可以使用你认为合适的逻辑和价值观。正如您所建议的,您也可以使用width={size}并将宽度的大小默认为断点值('small'、'medium'、'large'...)

这是完整的代码示例:

import React from "react";
import ReactDOM from "react-dom";
import { Box, Button, Grommet, ResponsiveContext } from "grommet";
import { DocumentPdf } from "grommet-icons";

import { deepMerge } from "grommet/utils";
import { grommet } from "grommet/themes";

import "./styles.css";

const customBreakpoints = deepMerge(grommet, {
  global: {
    breakpoints: {
      small: {
        value: 368,
        borderSize: {
          xsmall: "1px",
          small: "2px",
          medium: "4px",
          large: "6px",
          xlarge: "12px"
        },
        edgeSize: {
          none: "0px",
          hair: "1px",
          xxsmall: "2px",
          xsmall: "3px",
          small: "6px",
          medium: "12px",
          large: "24px",
          xlarge: "48px"
        },
        size: {
          xxsmall: "24px",
          xsmall: "48px",
          small: "96px",
          medium: "192px",
          large: "384px",
          xlarge: "768px",
          full: "100%"
        }
      },
      medium: {
        value: 768,
        borderSize: {
          xsmall: "2px",
          small: "4px",
          medium: "8px",
          large: "12px",
          xlarge: "16px"
        },
        edgeSize: {
          none: "0px",
          hair: "1px",
          xxsmall: "2px",
          xsmall: "3px",
          small: "6px",
          medium: "12px",
          large: "24px",
          xlarge: "48px"
        },
        size: {
          xxsmall: "48px",
          xsmall: "96px",
          small: "192px",
          medium: "384px",
          large: "768px",
          xlarge: "1200px",
          full: "100%"
        }
      },
      large: {}
    }
  }
});

const App = () => (
  <Grommet theme={customBreakpoints}>
    <ResponsiveContext.Consumer>
      {size => (
        <Box
          direction="column"
          align="center"
          gap="medium"
          pad="small"
          overflow={{
            horizontal: "auto"
          }}
          width={size==="small" ? "200px" : "400px"}
        >
          <Button
            primary
            hoverIndicator="true"
            style={{
              width: "100%"
            }}
            label="Next"
          />

          <Button
            primary
            icon={<DocumentPdf color="white" />}
            style={{
              width: "100%"
            }}
            label="Export PDF"
          />

          <Button
            primary
            icon={<DocumentPdf color="white" />}
            style={{
              width: "100%"
            }}
            label="Export all"
          />
        </Box>
      )}
    </ResponsiveContext.Consumer>
  </Grommet>
);

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

希望这可以帮助。

于 2020-07-15T22:22:55.060 回答