【问题标题】:material-ui: AppBar: strategy for restricting an image height to AppBar height?material-ui:AppBar:将图像高度限制为 AppBar 高度的策略?
【发布时间】:2018-01-05 20:46:51
【问题描述】:

任何人都可以提供有关将图像放置在 AppBar 中并将其限制为标准材质高度(例如桌面为 64 像素)的惯用方式的指导吗?

我目前正在使用material-ui@next(目前是1.0.0-beta.2)。

我发现了类似的东西:

<AppBar>
  <Toolbar>
    <IconButton color="contrast" aria-label="Menu">
      <MenuIcon />
    </IconButton>
    <img src={logo} style={{height: 64}}/>
    <Typography type="title" color="inherit">
      React Scratch
    </Typography>
  </Toolbar>
</AppBar>

效果很好。

实际的 logo 是一个高度大于 64 的 png 文件,所以如果我不把它往下拉,它会将 AppBar 的高度扩展到 Material 规范之外。

src/styles 的当前主分支版本中,有一个getMuiTheme.js,它似乎是deliver this height readily,但在我正在查看的@next 版本中,该文件甚至不存在并且tbh,我可以'不再轻易确定该高度是如何设置的。

我发现 AppBar 目前是renovated for composability,因此流失可能会使回答这个问题变得具有挑战性,但以防万一有人能很好地处理这个问题,我想我会把这个问题抛在脑后。

谢谢!

【问题讨论】:

    标签: reactjs material-design material-ui


    【解决方案1】:

    在我见过的所有情况下,AppBar 都是用 Toolbar 实现的,因为它是第一个孩子。工具栏的样式表根据主题中定义的断点来指定它的高度。

    看这里:https://github.com/callemall/material-ui/blob/v1-beta/src/Toolbar/Toolbar.js

    您可以使用类似的方法为您的 AppBar 图像定义一个样式表,该类会改变适用断点的高度。然后在渲染组件时,将类应用到您的图像。

    注意:如果您使用 withStyles HOC,就像在 Toolbar、AppBar 等中所做的那样,该样式表中定义的类将通过名为 classes 的道具提供。

    您对 AppBar 对可组合性的需求是正确的,但该问题尚未解决,无论如何这都是 beta 分支。当它被解决后,应该有一个更好的解决方案值得迁移。

    我希望这个答案会有所帮助。我会添加代码示例,但我在杂货店停车场等待时正在通过手机接听电话。如果有机会,我会更新这个答案。

    这是一种方法,将样式复制到新的可重用组件中:

    import createStyleSheet from 'material-ui/styles/createStyleSheet';
    import withStyles from 'material-ui/styles/withStyles';
    
    // define these styles once, if changes are needed because of a change
    // to the material-ui beta branch, the impact is minimal
    const styleSheet = createStyleSheet('ToolbarImage', theme => ({
        root: {
            height: 56,
            [`${theme.breakpoints.up('xs')} and (orientation: landscape)`]: {
                height: 48,
            },
            [theme.breakpoints.up('sm')]: {
                height: 64,
            },
        },
    }));
    
    // a reusable component for any image you'd need in a toolbar/appbar
    const ToolbarImage = (props) => {
        const { src, classes } = this.props;
        return (
            <img src={src} className={classes.root} />
        );
    };
    
    // this higher order component uses styleSheet to add
    // a classes prop that contains the name of the classes
    export default withStyles(styleSheet)(ToolbarImage);
    

    另一种方法是将标准工具栏高度作为business variables 添加到主题中,覆盖rootfor all Toolbars 以便它使用它们,并在需要再次引用它们时使用主题:

      // define the standard heights in one place
      const toolbarHeights = {
        mobilePortrait: 56,
        mobileLandscape: 48,
        tabletDesktop: 64,
      };
    
      // create the theme as you normally would, but add the heights
      let theme = createMuiTheme({
        palette: createPalette({
          primary: blue,
          accent: pink,
        }),
        standards: {
          toolbar: {
            heights: toolbarHeights,
          },
        },
      });
    
      // recreate the theme, overriding the toolbar's root class
      theme = createMuiTheme({
        ...theme,
        overrides: {
          MuiToolbar: {
            // Name of the styleSheet
            root: {
              position: 'relative',
              display: 'flex',
              alignItems: 'center',
              minHeight: theme.standards.toolbar.heights.mobilePortrait,
              [`${theme.breakpoints.up('xs')} and (orientation: landscape)`]: {
                minHeight: theme.standards.toolbar.heights.mobileLandscape,
              },
              [theme.breakpoints.up('sm')]: {
                minHeight: theme.standards.toolbar.heights.tabletDesktop,
              },
            },
          },
        },
      });
    

    然后您可以在您创建的任何样式表中引用这些高度,因为它们是主题的一部分。

    在 1.0.0-beta.11 发布后更新:

    现在主题上有一个工具栏混合可用,它为每个断点提供工具栏 minHeight。如果您需要相对于 AppBar 组件的标准高度设置元素的样式,可以使用此对象构建自己的样式:

    const toolbarRelativeProperties = (property, modifier = value => value) => theme =>
      Object.keys(theme.mixins.toolbar).reduce((style, key) => {
        const value = theme.mixins.toolbar[key];
        if (key === 'minHeight') {
          return { ...style, [property]: modifier(value) };
        }
        if (value.minHeight !== undefined) {
          return { ...style, [key]: { [property]: modifier(value.minHeight) } };
        }
        return style;
      }, {});
    

    在此示例中,toolbarRelativeProperties 返回一个函数,该函数将返回一个可以传播到您的样式对象中的对象。它解决了将指定属性设置为基于 AppBar 高度的值的简单情况。

    一个简单的使用示例是生成用于高度计算的动态 CSS 表达式,这取决于 AppBar 的标准高度:

    const componentStyle = theme => ({
      root: {
        height: toolbarRelativeProperties('height', value => `calc(100% - ${value}px)`)(theme)
      }
    });
    

    生成的样式定义可能如下所示:

    {
      height: 'calc(100% - 56px)',
      '@media (min-width:0px) and (orientation: landscape)': {
        height: 'calc(100% - 48px)'
      },
      '@media (min-width:600px)': {
        height: 'calc(100% - 64px)'
      }
    }
    

    【讨论】:

    • 感谢 ken,这解释了如何确定 AppBar 的高度(如果我理解正确,ToolBar 的高度)。我想如果我的目标是将图像添加到AppBar,那么该图像也将是ToolBar 的子图像。是否可以获得对父 ToolBars classes 对象的引用,所以我可能会从那里引用这些样式,而不是在我的“AppBarImage”组件中指定类似的样式?
    • 您当然可以将 classes 属性或其中包含的任何类传递给 Toolbar 的任何子项。问题是根类做的比你需要的多。您可能需要定义一个具有自己的类集的新组件,例如 ToolBarImage,当您需要在工具栏中放置图像时使用它们。
    • 感谢 ken,是的,我可能不想将 classesToolBar 传递到 ToolBarImage,但可能会使用其中的一部分。我确定我是个笨蛋,但我在获取对ToolBarclasses 道具的引用以传递给它的一个孩子时遇到问题。我尝试在ToolBar 上使用ref 函数,但是当我查看它时,ref 没有classes 道具。
    • 感谢@ken-gregory,这更像是我最初想要的。感谢更新!
    • @KenGregory 感谢您提供这个非常有用的 sn-p!在 1.0.0b11 示例中,我认为您的意思是 spread 而不是 deconstructed。我也不确定你为什么将它实现为一个生成依赖于主题的函数的函数,因为我看不出能够在调用之间改变主题的用处。
    猜你喜欢
    • 2018-12-05
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 2014-08-24
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    相关资源
    最近更新 更多