javascript - Material Ui button colors not changed after theme change - Stack Overflow

admin2025-04-09  0

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 ponent="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.

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 ponent="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.

Share Improve this question edited May 7, 2020 at 14:45 Olivier Tassinari 8,6916 gold badges25 silver badges28 bronze badges asked Jan 8, 2019 at 11:17 Hayk SafaryanHayk Safaryan 2,0564 gold badges33 silver badges55 bronze badges 2
  • 1 Are you following material-ui./css-in-js/basics/… you do not need to use both Theme Providers – Josh Wooding Commented Jan 8, 2019 at 17:22
  • @JoshWooding I've fixed my answer accordingly. – Ryan Cogswell Commented Jan 8, 2019 at 18:27
Add a ment  | 

2 Answers 2

Reset to default 5

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 remended 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 ment and then reading the details in the docs and looking through some of the code, below is a solution in line with Josh's remendation. 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:

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;
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1744128140a232556.html

最新回复(0)