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

Using ReactJS and MUI, I have a project in which I have changed the theme colors.

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>
    )
  }

Everything works as expected. Certain components, like buttons have the ability to set the color based on the primary prop. However, I have a component that uses an icon that needs the primary color. I can import the color and set it directly:

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} />
        )
    }
}

Is there some way to reference the theme's primary color, rather than setting the color in each component individually? Something like:

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} />
        )
    }
}


Solution 1:[1]

If you're using React v16.8.0 and Material-UI v3.5.0 or greater, you can utilize the useTheme() hook:

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

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

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

Solution 2:[2]

Adding how to access theme colors in material-ui v1.0.0 (currently beta) Using withTheme component.
Also check the following 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);

Solution 3:[3]

If you're using system properties, you can define a string path of the Palette object to the color value like below:

<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>

The above is the same as:

<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>

The example using the callback is more verbose but is type-safe, the shorter one with only string is quicker and good when prototyping, but you may want to store the string in a constant to prevent any typo errors and help the IDE refactor your code better.

Live Demo

Edit 43281020/reference-to-themes-primary-color-instead-of-a-specific-color-in-material-ui

Solution 4:[4]

Ok if you are using material-ui version greater than 4, then the above solution might not work for you. Follow the below's code

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

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

const DeepChild = withTheme(DeepChildRaw);

Reference: https://material-ui.com/styles/advanced/

Solution 5:[5]

With react hooks, now you don't need to warp component in withTheme, just use useTheme:

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

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

Solution 6:[6]

MUI V5

For the users of MUI v5, you can specify a function inside the sx css style directly, ex:

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

Solution 7:[7]

You can use the useTheme() hook and access the colors like the example below. There are also some other color variants as well.

enter image description here

Mui 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;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 chenop
Solution 3
Solution 4 shashi verma
Solution 5 elarcoiris
Solution 6 Normal
Solution 7 viniciusalvess