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

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

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

Method 2

Yes you have!
using 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

Method 3

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

Method 4

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

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

Method 5

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/

Method 6

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

Method 7

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

Method 8

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

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

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;


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x