Material-UI主题覆盖:如何在全球覆盖儿童样式?

时间:2018-12-20 21:56:13

标签: reactjs material-ui mui

我正在使用Material-UI library为ReactJS构建一个应用程序。我试图使用Theme Overrides API来弄清楚如何对组件进行全局样式设置,但前提是该组件是另一个特定组件的子组件。

例如,我试图在MenuItem菜单中设置<Select>的背景/文本颜色,其中每个<MenuItem>包含一个<listItemText>。这是我的组件:

import { MenuItem, Select, ListItemText } from '@material-ui/core';
import { MuiThemeProvider } from '@material-ui/core/styles';
import * as React from 'react';
import theme from './theme';

const MySelect = props => {
    return (
        <MuiThemeProvider theme={theme}>
            <Select variant="standard" value="2" open>
                <MenuItem value="1">
                    <ListItemText>One</ListItemText>
                </MenuItem>
                <MenuItem value="2">
                    <ListItemText>Two</ListItemText>
                </MenuItem>
                <MenuItem value="3">
                    <ListItemText>Three</ListItemText>
                </MenuItem>
                <MenuItem value="4">
                    <ListItemText>Four</ListItemText>
                </MenuItem>
            </Select>
        </MuiThemeProvider>
    );
};

export default MySelect;

不幸的是,直接将颜色应用于<MenuItem>是行不通的,因为<ListItemText>会被具有自己颜色的<Typography>覆盖。对于非悬停,未选择的状态,这很好,但是如果我将“已选择” MenuItem的样式设置为具有较深的背景,则需要使其具有较浅的文本。

MUI select dropdown with darkened selected item and dark text

这是我的主题文件:

import { createMuiTheme, createStyles } from '@material-ui/core';

const myTheme = createMuiTheme({
    overrides: {
        MuiMenuItem: createStyles({
            root: {
                '&&:hover': {
                    backgroundColor: 'pink',
                    color: 'white'
                }
            },
            selected: {
                '&&': {
                    backgroundColor: 'blue',
                    color: 'white'
                },
                '&&:hover': {
                    backgroundColor: 'darkblue',
                    color: 'white'
                }
            }
        }),

        // How do I enforce this ONLY inside of MuiMenuItem and only for
        // the selected variant of that?
        MuiTypography: {
            subheading: {
                color: 'white'
            }
        }
    }
});

export default myTheme;

所以,我的问题是:是否有一种方法可以仅使用主题覆盖?还是我需要使用prop有条件地将此样式传递到<ListItemText>组件中?由于此处的大多数样式都非常适合主题覆盖,因此这似乎是一种更好的方法,但是也许我滥用了API。

有关上述代码的有效演示,请参见:https://codesandbox.io/s/3r9mkxq231

欢迎有识之士!谢谢!

3 个答案:

答案 0 :(得分:1)

一种实现方法是,以祖先样式(在这种情况下为MenuItem)定位后代html元素(例如ListItemText的跨度)。

下面是如何指定MenuItem.selected样式的示例:

  selected: {
    "&&": {
      backgroundColor: "blue",
      color: "white",
      "&& span": {
        color: "white"
      }
    },
    "&&:hover": {
      backgroundColor: "darkblue",
      color: "white"
    }
  }

完整代码(从您的CodeSandbox分叉)在这里:

Edit MUI How to: Override Tab Theme

答案 1 :(得分:0)

首先,我认为我们无法在主题替代中做到这一点。主题替代是一种替代现有material-ui组件的默认样式配置的方法。

第二,我不认为您需要通过条件语句来使其变得过于复杂。没有这个也可以解决。我不明白为什么<ListItemText>本身具有显示文本的功能时为什么需要使用<MenuItem>
只需从代码中删除<ListItemText>,然后您就可以根据需要使用主题覆盖来修改<MenuItem>

在此处找到修改后的代码:https://codesandbox.io/s/30p3o4jjz5

让我知道是否可以澄清您的疑问。

答案 2 :(得分:0)

是的,您可以使用jss嵌套语法在主题覆盖中执行此操作:

const myTheme = createMuiTheme({
  overrides: {
    MuiMenuItem: createStyles({
      root: {
        "&&:hover": {
          backgroundColor: "pink",
          "& *": {
            color: "white"
          }
        }
      },
      selected: {
        "&&": {
          backgroundColor: "blue",
          "& *": {
            color: "white"
          }
        },
        "&&:hover": {
          backgroundColor: "darkblue",
          "& *": {
            color: "white"
          }
        }
      }
    })
  }
});

export default myTheme;

在此处查看有效的代码笔:https://codesandbox.io/embed/308mk7k5x6?fontsize=14