4

I am using https://material-ui.com/

My objective is to get a success Button, and Chip. Does anyone know how to do this without these hacky solutions: Material-ui @next customize button colors?

The goal isn't to create a styled component, the goal is to be able to use <Button color="success" /> or <Chip color="success" />.

I have tried <Box bgcolor="success.main">{ props => <Chip {...props} />}</Box> to no avail. I would be OK with using Box but not even that works.

It seems a bit ridiculous that these basic UI things are so cumbersome with this library. Success and Error colors should be a default, and they seem to be missing from every single component in this library. Am I missing something?

damusix
  • 111
  • 1
  • 9
  • 2
    Why doesn't ` – isherwood Feb 27 '20 at 18:46
  • You can always use `makeStyles` to create `classes`. The valid props for their color are `default`, `inherit`, `primary`, and `secondary`. I've spent a lot of time to add custom color as a prop in the past. :-/ – Ioannis Potouridis Feb 27 '20 at 18:47
  • If I were you, I would use the `makeStyles`/`useStyles` hook. The first example on this page is a button example: https://material-ui.com/styles/basics/ – WGriffing Feb 27 '20 at 18:49
  • @WGriffing That defeats the purpose of having a theme. If all my forms have a success button, I would need to make a success button component. Isn't there a way to create another "color" such as `success` ?? how come I can't use `color="success"` if I define it in my theme palette? Are there really only ever 3 colors? – damusix Feb 27 '20 at 18:55
  • @damusix You can define colors in a theme and access them from the hook within the components. I'll try to wrangle some snippets from my codebase and post them as an answer for you so you can see a more complete example. – WGriffing Feb 27 '20 at 18:58
  • @WGriffing Would highly appreciate that – damusix Feb 27 '20 at 19:01
  • If you haven't already, I recommend upvoting [this issue](https://github.com/mui-org/material-ui/issues/13875). This is something that Material-UI considers important, but I'm not sure if good support for this will come prior to v5. – Ryan Cogswell Feb 27 '20 at 23:19

1 Answers1

-2

This is not a full/working example, but hopefully it provides some context. The Main component is included (eventually) via an AuthenticatedRoute within the Router shown in App.js. It doesn't really add anything to show all that complexity, but I wanted to give you some context.

Steps:

  1. Create theme using createMuiTheme.
  2. Add a ThemeProvider component with a theme prop that accepts your theme. This should be a parent to any Component that will make use of the theme, ours is in App.js.
  3. Use the optional argument that makeStyles has to pass your theme into your Component (Main in my example). You can see examples where we access theme properties such as theme.palette.brand.primary.
  4. Use the useStyles hook to create a variable in your component.
  5. Apply those styles to your Component's elements via the className prop. For example, <div className={classes.root}>...</div>
  6. Repeat 3-5 on any Component that needs styling.

I'm still learning my way around Material UI; we just recently migrated from react bootstrap to MUI. We still have some *.scss files laying around, but everything can co-exist. Our eventual plan is to move everything into the makeStyles hooks, but we haven't had time to refactor everything yet.

As a non-CSS guru, I much prefer to write the styling as code (even if I have to write some boilerplate) than to deal with .scss files and specificity/inheritance.

Theme.js:

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

export default createMuiTheme({
  palette: {
    brand: {
      primary: '#1b3c6b',
      primaryLight: '#adceff',
      secondary: '#2a5da6',
      tertiary: '#bf1e2e',
      tertiaryLight: '#c35f69',
    },
  },
  typography: {
    color: '#333',
  },
  sidebar: {
    header: {
      background: '#2a5da6',
    },
    content: { background: '#fff' },
  },
  status: {
    danger: 'orange',
  },
});

Main.js (partial):

const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1,
  },
  appBar: {
    background: theme.palette.brand.primary,
    boxShadow: 'none',
    '& .MuiTabs-indicator': {
      backgroundColor: theme.palette.brand.primaryLight,
      height: 3,
    },
    position: 'fixed',
    zIndex: 1000,
  },
}));

const Main = React.memo(props => {
  const classes = useStyles();

  ...

  return (
    <div className={classes.root}>
      <AppBar className={classes.appBar} position="static">
      ....
      </AppBar>
    </div>
  );
}

App.js (partial):

import { CssBaseline, ThemeProvider } from '@material-ui/core';
import theme from 'Theme/Theme'; // Theme.js from above

...

class App extends Component {
  ...

  render() {
    ...
    return (
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <Router>
          ...
        </Router>
      </ThemeProvider>
    );
  }
  ...
}
WGriffing
  • 604
  • 6
  • 12