Hayk Safaryan
Hayk Safaryan

Reputation: 2046

Material Ui button colors not changed after theme change

In the project with react Material Ui is used. The theme is being overriden, but the colors of buttons and inputs do not change.

Here is the theme.js where Material Ui theme is created

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

import type
{
  Theme,
} from '@material-ui/core';

const theme: Theme = createMuiTheme({
  palette: {
    primary: {
      main: '#ffa300',
      light: '#ffd449',
      dark: '#c67400',
      contrastText: '#000000',
    },
    secondary: {
      main: '#ff8500',
      light: '#ffb644',
      dark: '#c55600',
      contrastText: '#000000',
    },
    error: {
      main: '#A21C2B',
    },
  },
});


export default theme;

Here is App.js

import React from 'react';
import { ThemeProvider } from '@material-ui/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import {
  Switch,
} from 'react-router-dom';
import theme from './theme';
import Auth from './Auth';

const App = () => (
  <ThemeProvider theme={theme}>
    <CssBaseline />
    <Switch>
      <Auth />
    </Switch>
  </ThemeProvider>
);

export default App;

Note there the use of the new ThemeProvider because hooks are used later.

And here is a sample login page

// @flow
import * as React from 'react';
import Avatar from '@material-ui/core/Avatar';
import Button from '@material-ui/core/Button';
import FormControl from '@material-ui/core/FormControl';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Checkbox from '@material-ui/core/Checkbox';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import LockIcon from '@material-ui/icons/LockOutlined';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/styles';

const useStyles = makeStyles(theme => ({
  main: {
    width: 'auto',
    display: 'block', // Fix IE 11 issue.
    marginLeft: theme.spacing.unit * 3,
    marginRight: theme.spacing.unit * 3,
    [theme.breakpoints.up(400 + theme.spacing.unit * 3 * 2)]: {
      width: 400,
      marginLeft: 'auto',
      marginRight: 'auto',
    },
  },
  paper: {
    marginTop: theme.spacing.unit * 8,
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    padding: `${theme.spacing.unit * 2}px\
    ${theme.spacing.unit * 3}px\
    ${theme.spacing.unit * 3}px`,
  },
  avatar: {
    margin: theme.spacing.unit,
    backgroundColor: theme.palette.secondary.main,
  },
  form: {
    width: '100%', // Fix IE 11 issue.
    marginTop: theme.spacing.unit,
  },
  submit: {
    marginTop: theme.spacing.unit * 3,
  },
}));

const Login = (props) => {
  const classes = useStyles();

  return (
    <main className={classes.main}>
      <Paper className={classes.paper}>
        <Avatar className={classes.avatar}>
          <LockIcon />
        </Avatar>
        <Typography component="h1" variant="h5">
          Sign in
        </Typography>
        <form className={classes.form}>
          <FormControl margin="normal" required fullWidth>
            <InputLabel htmlFor="email">Email Address</InputLabel>
            <Input id="email" name="email" autoComplete="email" autoFocus />
          </FormControl>
          <FormControl margin="normal" required fullWidth>
            <InputLabel htmlFor="password">Password</InputLabel>
            <Input
              name="password"
              type="password"
              id="password"
              autoComplete="current-password"
            />
          </FormControl>
          <FormControlLabel
            control={<Checkbox value="remember" color="primary" />}
            label="Remember me"
          />
          <Button
            type="submit"
            fullWidth
            variant="contained"
            color="primary"
            className={classes.submit}
          >
            Sign in
          </Button>
        </form>
      </Paper>
    </main>
  );
};

export default Login;

And here is the problem. The colors of the button and input are not changed. But the color of the LockIcon is changed to the color provided by theme.

Upvotes: 0

Views: 7114

Answers (2)

Anji Bandaiah
Anji Bandaiah

Reputation: 29

In version 4, This Theme Provider is not working.

<ThemeProvider theme={theme}>

theme called is

import { createMuiTheme } from "@material-ui/core/styles";
import { red } from "@material-ui/core/colors";

// Create a theme instance.
const theme = createMuiTheme({
  palette: {
    primary: {
      main: "#06a3b8"
    },
    secondary: {
      main: "#ff7c04"
    },
    error: {
      main: red.A400
    },
    background: {
      default: "#ffffff"
    }
  },
  typography: {
    useNextVariants: true
  }
});

export default theme;

Upvotes: 2

Ryan Cogswell
Ryan Cogswell

Reputation: 81006

Update

The answer below is specific to using @material-ui/styles with the 3.x versions of Material-UI. These install steps (bootstrapMuiStyles.js) are no longer necessary for v4 of Material-UI.


Initially I recommended also wrapping with the MuiThemeProvider. That works, but is the wrong solution and likely would lead to further issues when trying to use the new @material-ui/styles package. Based on Josh Wooding's comment and then reading the details in the docs and looking through some of the code, below is a solution in line with Josh's recommendation. The excerpts are from my CodeSandbox so there are some differences due to simplifications/changes (e.g. not using types) I did to your code to get a working example. The important parts are just index.js and bootstrapMuiStyles.js -- particularly the ordering of the imports. It will not work to import the install method directly from index.js, because that will force you to call install() after you have already imported App.js.

index.js

import React from "react";
import ReactDOM from "react-dom";
// It is important for this import to be before the import of App
// so that no other Material-UI imports happen before the install
import "./bootstrapMuiStyles";
import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

bootstrapMuiStyles.js

import { install } from "@material-ui/styles";
install();

App.js

import React from "react";
import { ThemeProvider } from "@material-ui/styles";
import CssBaseline from "@material-ui/core/CssBaseline";
import theme from "./theme";
import Login from "./Login";

const App = () => (
  <ThemeProvider theme={theme}>
    <CssBaseline />
    <Login />
  </ThemeProvider>
);
export default App;

And then Login.js is a nearly exact copy of the code from your question.

You can see this working here:

Edit mz4q046v0j

Upvotes: 5

Related Questions