How to add custom MUI palette colors

32,026

Solution 1

Other than needing to change purple in your MyTheme to be something like purple[500], I'm not sure why this wouldn't work for you. You may not be able override anything other than the primary and secondary in this way.

Regardless, here's a workaround:

In MyTheme.js:

accent: { backgroundColor: purple[500], color: '#000' }

Then in App.js:

<Button
  variant="raised"
  style={MyTheme.palette.accent}
  className={classes.primary}>
    Accent
</Button>

A working example is here.

Solution 2

The MUI palette is extendable, but you need to do a couple of things to create a new color and apply to your Button component.

First, let’s define a theme with a custom color variable. You can use augmentColor() to generate the PaletteColor so it can be consumed in your Button:

import { purple } from "@mui/material/colors";

const { palette } = createTheme();
const theme = createTheme({
  palette: {
    myAwesomeColor: palette.augmentColor({ color: purple }),
    // Use this code if you want to use an arbitrary color
    // myAwesomeColor: palette.augmentColor({
    //   color: {
    //     main: "#00ff00"
    //   }
    // })
  }
});

Then update your TypeScript definition, so it can recognize the property myAwesomeColor when referencing the Palette and PaletteOption objects (skip this step if you're using JavaScript). You also need to extend the Button's color props definition, because by default it only accepts the following values:

'inherit' | 'primary' | 'secondary' | 'success' | 'error' | 'info' | 'warning'
declare module "@mui/material/styles" {
  interface Palette {
    myAwesomeColor: string;
  }
  interface PaletteOptions {
    myAwesomeColor: string;
  }
}

declare module "@mui/material/Button" {
  interface ButtonPropsColorOverrides {
    myAwesomeColor: true;
  }
}

The final step is to inject the custom theme and set the custom color for your Button:

<ThemeProvider theme={theme}>
  <Button color="myAwesomeColor" variant="contained">
    AWESOME
  </Button>
</ThemeProvider>

Live Demo

Codesandbox Demo

Related answer

Share:
32,026

Related videos on Youtube

Bethany
Author by

Bethany

By Day: Coding in React and C#.

Updated on February 17, 2022

Comments

  • Bethany
    Bethany about 2 years

    I'm trying to establish my own palette colors to match my branding in MUI. So far I can only get the primary and secondary colors to work when applied as the background color to buttons. When I add my own variable names, like use "accent" as shown as an example from MUI's website, the button defaults to grey.

    Here is my MyTheme.js code:

    import { createMuiTheme } from 'material-ui/styles';
    import purple from 'material-ui/colors/purple';
    
    export default createMuiTheme({
        palette: {
            primary: { // works
              main: '#165788',
              contrastText: '#fff',
            },
            secondary: { // works
              main: '#69BE28',
              contrastText: '#fff',
            },
            companyBlue: { // doesn’t work - defaults to a grey button
                main: '#65CFE9',
                contrastText: '#fff',
            },
            companyRed: { // doesn’t work - grey button
                main: '#E44D69',
                contrastText: '#000',
            },
            accent: { // doesnt work - grey button
                main: purple, // import purple doesn’t work
                contrastText: '#000',
            },
        },
    });
    

    Here is my App.js code:

    import React, { Component } from 'react';
    import Button from 'material-ui/Button';
    import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
    import MyTheme from './MyTheme';
    import './App.css';
    import { withStyles } from 'material-ui/styles';
    import PropTypes from 'prop-types';
    
    
    const styles = theme => ({
      button: {
        margin: theme.spacing.unit,
      },
      input: {
        display: 'none',
      },
    });
    
    
    class App extends Component {
      constructor(props)
      {
        super(props);
      }
    
      render() {
        const { classes } = this.props;
        return (
          <MuiThemeProvider theme={MyTheme}>
              <Button variant="raised" >
              Default
              </Button>
              <Button variant="raised" color="primary" className={classes.button}>
              Primary
              </Button>
              <Button variant="raised" color="secondary" className={classes.button}>
              Secondary
              </Button>
              <Button variant="raised" color="companyRed" className={classes.button}>
              Company Red
              </Button>
              <Button variant="raised" color="accent" className={classes.button}>
              Accent
              </Button>
          </MuiThemeProvider>
          );
      }
    }
    
    App.propTypes = {
      classes: PropTypes.object.isRequired,
    };
    
    export default withStyles(styles)(App);
    
    • Colin Ricardo
      Colin Ricardo about 6 years
      This is a strange one. Not sure what you mean by "purple" doesn't work, but you should have e.g. purple[500] or something in your MyTheme anyway.
  • Bethany
    Bethany about 6 years
    Hey Colin, I need my own variables to work with hex colors. The purple was just a test.
  • Colin Ricardo
    Colin Ricardo about 6 years
    Sure, but purple wasn't valid since it was an object.
  • Bethany
    Bethany about 6 years
    Thanks! I checked out your example and my custom colored variable works. For anyone looking at this post, here is the answer: <Button style={MyTheme.palette.companyRed} >
  • Bethany
    Bethany about 6 years
    and in your theme file change main to backgroundColor and contrastText to color.
  • Jota.Toledo
    Jota.Toledo over 2 years
    This worked for me when accessing the custom property inside of the callback of the styled function from @mui/material/styles. On the contrary, I get a "property doesnt exist" when accessing it through the returned value of the "useTheme" hook from @mui/material/styles. Any hints? :/
  • NearHuscarl
    NearHuscarl over 2 years
    @Jota.Toledo Similar to this answer, put the component that uses useTheme inside ThemeProvider. See my updated codesandbox for reference.