引用主题的原色而不是 MUI 中的特定颜色

Reference to theme's primary color instead of a specific color in MUI

使用 ReactJS 和 MUI,我有一个更改了主题颜色的项目。

const newTheme = getMuiTheme({
    fontFamily: 'Roboto, sans-serif',
    palette: {
        primary1Color: cyan500,
        primary2Color: cyan700,
        primary3Color: grey400,
        accent1Color: amberA400,
        accent2Color: grey100,
        accent3Color: grey500,
        textColor: darkBlack,
        alternateTextColor: white,
        canvasColor: white,
        borderColor: grey300,
        disabledColor: fade(darkBlack, 0.3),
        pickerHeaderColor: cyan500,
        clockCircleColor: fade(darkBlack, 0.07),
        shadowColor: fullBlack,
    },
});

  // App class
  render() {
    return(
        <ThemeProvider theme={newTheme}>
            <Project />
        </ThemeProvider>
    )
  }

一切正常。某些组件,如按钮,可以根据主要道具设置颜色。但是,我有一个组件使用需要原色的图标。我可以导入颜色直接设置:

import React from 'react';
import ActionLock from 'material-ui/svg-icons/action/lock';
import {cyan500} from 'material-ui/styles/colors';

export default class LockIcon extends React.Component {
    render() {
        return(
            <ActionLock color={cyan500} />
        )
    }
}

有没有什么方法可以引用主题的主色,而不是单独设置每个组件的颜色?类似于:

import React from 'react';
import ActionLock from 'material-ui/svg-icons/action/lock';
import {primary1Color} from 'somewhere';

export default class LockIcon extends React.Component {
    render() {
        return(
            <ActionLock color={primary1Color} />
        )
    }
}

是的,你有! 使用 muiThemeable..

import muiThemeable from 'material-ui/styles/muiThemeable';
class LockIcon extends React.Component {
    render() {
        return(
            <ActionLock color={this.props.muiTheme.palette.primary1Color} />
        )
    }
}
        export default muiThemeable()(LockIcon)

from material-ui docs

使用 withTheme 组件在 material-ui v1.0.0(当前测试版)中添加如何访问主题颜色。
还要检查以下 Example.

import React, {Component} from 'react';
import { withTheme } from 'material-ui/styles';

class WithThemeExample extends Component {
    render() {
        const { theme } = props;
        const {primary, secondary} = theme.palette.text;

        return (
            <div>
                <div style={{color: primary}}>Hi in Primary color</div>
                <div style={{color: secondary}}>Bye in Secondary color</div>
            </div>
        );
    }
}

export default withTheme()(WithThemeExample);

好的,如果您使用的 material-ui 版本大于 4,那么上述解决方案可能不适合您。按照下面的代码

import { withTheme } from '@material-ui/core/styles';

function DeepChildRaw(props) {
  return <span>{`spacing ${props.theme.spacing}`}</span>;
}

const DeepChild = withTheme(DeepChildRaw);

参考:https://material-ui.com/styles/advanced/

如果您使用的是 React v16.8.0 和 Material-UI v3.5.0 或更高版本,您可以使用 useTheme() 挂钩:

import { useTheme } from '@material-ui/core/styles';

function LockIcon = () => {
  const theme = useTheme();

  return (
    <ActionLock color={theme.palette.primary1Color} />
}

有了反应钩子,现在你不需要在 withTheme 中扭曲组件,只需使用 useTheme:

import { useTheme } from '@material-ui/core/styles';

export default function MyComponent() {
    const theme = useTheme();
    
    return <span>{`spacing ${theme.spacing}`}</span>;
}

如果您将 system properties, you can define a string path of the Palette 对象用于颜色值,如下所示:

<Box sx={{ color: "primary.main" }}>primary.main</Box>
<Box sx={{ color: "secondary.main" }}>secondary.main</Box>
<Box sx={{ color: "error.main" }}>error.main</Box>
<Box sx={{ color: "warning.main" }}>warning.main</Box>
<Box sx={{ color: "info.main" }}>info.main</Box>
<Box sx={{ color: "success.main" }}>success.main</Box>
<Box sx={{ color: "text.primary" }}>text.primary</Box>
<Box sx={{ color: "text.secondary" }}>text.secondary</Box>
<Box sx={{ color: "text.disabled" }}>text.disabled</Box>

上同:

<Box sx={{ color: theme => theme.palette.primary.main }}>primary.main</Box>
<Box sx={{ color: theme => theme.palette.secondary.main }}>secondary.main</Box>
<Box sx={{ color: theme => theme.palette.error.main }}>error.main</Box>
<Box sx={{ color: theme => theme.palette.warning.main }}>warning.main</Box>
<Box sx={{ color: theme => theme.palette.info.main }}>info.main</Box>
<Box sx={{ color: theme => theme.palette.success.main }}>success.main</Box>
<Box sx={{ color: theme => theme.palette.text.primary }}>text.primary</Box>
<Box sx={{ color: theme => theme.palette.text.secondary }}>text.secondary</Box>
<Box sx={{ color: theme => theme.palette.text.disabled }}>text.disabled</Box>

使用回调的示例更冗长但类型安全,只有字符串的较短示例在原型设计时更快更好,但您可能希望将字符串存储在常量中以防止任何拼写错误和帮助IDE 更好地重构您的代码。

现场演示

MUI V5

对于MUI v5的用户,可以直接在sx css样式中指定函数,例如:

<Box sx={{ color: (theme) => theme.palette.primary1Color }} />

您可以使用 useTheme() 挂钩并访问颜色,如下例所示。 还有一些其他颜色变体。

梅 5:

import * as React from 'react';
import PropTypes from 'prop-types';
import { NavLink } from "react-router-dom";
import { useTheme } from "@mui/material/styles";

function VinNavLink(props) {
  const theme = useTheme();

  return (
    <NavLink {...props} style={({ isActive }) => isActive ? { textDecoration: "underline", color: theme.palette.primary.main} : undefined}>{props.children}</NavLink>
  );
}

export default VinNavLink;