mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.72k stars 32.23k forks source link

How to specify a custom pallete name? #10615

Closed Vishal1419 closed 5 years ago

Vishal1419 commented 6 years ago

I want to declare a custom pallete named excel, which I will use on for example a button to show it green. So, I tried that on code sandbox and I was unsuccessful. Here is the link to sandbox: https://codesandbox.io/s/13rzn53xx7

I don't know that if this is a feature or not? If its a feature then that should be a bug. Else can you please suggest me a workaround.

Expected Behavior

As per my sandbox code, color of secondary button should look green.

Current Behavior

Color of secondary button looks gray

Tech Version
Material-UI next
React > 16
browser chrome
oliviertassinari commented 6 years ago

@Vishal1419 You can't. The color property has static supported values. You need to write a wrapping component that implements this behavior.

I want to work on this story in the future. I was thinking of introducing a Color component for this use case.

gustavopch commented 6 years ago

@Vishal1419 Any success?

Vishal1419 commented 6 years ago

@oliviertassinari Thanks for giving me the idea, I have created the wrapping component and it works.

@gustavopch Yes, I implemented it. Take a look at the code below:

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

class Color extends Component {
    constructor(props) {
        super(props);
        this.state = {
            hover: false,
        }
        this.toggleHover = this.toggleHover.bind(this);
    }

    toggleHover() {
        this.setState({
            hover: !this.state.hover,
        });
    }

    render() {
        const { theme, color, children } = this.props;
        return (
            React.cloneElement(children, {
                style: {
                    ...children.props.style,
                    color: !children.props.disabled && 
                           theme.palette[color].contrastText,
                    background: !children.props.disabled &&
                                (this.state.hover 
                                ? theme.palette[color].dark
                                : theme.palette[color].main),
                },
                onMouseEnter: this.toggleHover,
                onMouseLeave: this.toggleHover,
            })
        );
    }
}

Color.propTypes = {
    color: PropTypes.string.isRequired,
    children: PropTypes.element.isRequired,
    theme: PropTypes.object.isRequired,
}

export default withTheme()(Color);

You can use it as follows:

<Color color="excel">
    <Button 
        color="primary" 
        variant="raised" 
        style={{ margin: 10, marginTop: 6 }}
        disabled={props.selectedContacts.length <= 0}
        onClick={props.deleteSelectedContacts}
    >
        <DeleteIcon style={{ marginRight: 10 }} />
        Export To Excel
    </Button>
</Color>

In theme I am doing this:

import { createMuiTheme } from 'material-ui/styles';

const theme = createMuiTheme({
  palette: {
    primary: {
      light: '#e3f2fd',
      main: '#2196f3',
      dark: '#1976d2',
      contrastText: '#fff',
    },
    secondary: {
      light: '#fbbcd0',
      main: '#f50057',
      dark: '#c51162',
      contrastText: '#fff',
    },
    excel: {
      light: '#E8F5E9',
      main: '#4CAF50',
      dark: '#2E7D32',
      contrastText: '#fff',      
    }
  },
});

export default theme;

And in App.js, I wrap parent div inside MuiThemeProvider as follows:

      <div className="App">
        <Provider store={store}>
          <MuiThemeProvider theme={LightTheme}>
            <Contacts />
          </MuiThemeProvider>
        </Provider>
      </div>
Vishal1419 commented 5 years ago

@oliviertassinari Any in-built support for this in newer versions?

oliviertassinari commented 5 years ago

I'm closing as a duplicate of #14185. #13875 covers the same problem.