基于元素大小的Material UI响应式设计

10
我正在使用React和MaterialUI构建一个系统,该系统将在另一个(非基于React的)网站中显示小部件。我想使这些小部件具有响应性,但是它们需要响应自己的容器宽度而不是窗口宽度,因为我不知道小部件将占用页面的多少内容。
我考虑过以下几种选项:
  • 定期轮询容器大小
  • 在窗口调整大小事件时轮询容器大小
  • 根据容器和窗口大小在启动时设置主题断点
这些方法都对我来说不太优雅。有没有更优雅的方法实现我想要的效果?
2个回答

1

不必使用断点,您可以监听组件大小的变化。您可以使用react-use钩子useMeasure来实现这一点(它依赖于ResizeObserver,所有主要浏览器都支持),如下面的示例所示:

/** @jsx jsx */
import { css, jsx } from '@emotion/core';
import { faAddressBook, faCoffee } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { useMeasure } from 'react-use';

const useMyComponentStyle = (params) => {
    const { color } = params;
    const [ref, { width }] = useMeasure();

    const borderColor = width < 150 ? 'red' : width < 400 ? 'yellow' : 'green';
    const icon = width < 250 ? faCoffee : faAddressBook;

    const style = css`
        color: ${color};
        padding: 10px;
        border: 1px solid ${borderColor};
    `;

    return {
        ref,
        style,
        icon,
        width,
    };
};

export const MyComponent = (props) => {
    const { ref, style, icon, width } = useMyComponentStyle(props);

    return (
        <div ref={ref} css={style}>
            <FontAwesomeIcon icon={icon} />
            {props.children} [[{parseInt('' + width)}px]]
        </div>
    );
};

const containerStyle = css`
    padding: 100px 200px;
    border: 1px solid blue;
`;

export const MyContainer = () => (
    <div css={containerStyle}>
        <MyComponent color='blue'></MyComponent>
    </div>
);

ReactDOM.render(<MyContainer />, document.getElementById('root'));

上面的示例使用emotion作为css样式,但样式也可以使用其他库定义,比如jssstyled components,甚至是纯react内联样式。
组件MyComponent包含在容器组件MyContainer中,该容器组件具有左右填充200px的值,并且您可以看到随着浏览器视图的调整,MyComponentborder颜色基于组件本身的大小(如果组件的宽度小于150px,则为red,小于400px则为yellow,否则为green),而不是基于窗口大小。

0
为了让各种@material-ui/core元素仅占用您放置它们的容器所需的空间,我会使用Grid组件。
我已经使用了以下内容:
<Grid container spacing={24}>
  <Grid item>
    Your content here
  </Grid>
</Grid>

如果您希望您的网格项对屏幕大小等因素具有响应性,可以执行以下操作:
const grid = {
    xs: 24,
    sm: 24,
    md: 24,
    lg: 12,
    xl: 12,
};

并且

<Grid item {...grid}>

文档:https://material-ui.com/layout/grid/


4
谢谢,但那不是我想表达的。问题在于断点(例如在你的示例中将网格项目从24列更改为12列的位置)是参考浏览器实际窗口大小,而不是我的小部件容器大小。 - Marten Jacobs
@MartenJacobs,你找到适合你的解决方案了吗?我也有同样的需求。 - Xavier
这个话题有进展了吗?谢谢大家提供的信息。 - Ivan Mjartan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接