I'm trying out material-ui, so I have create two themes:
const darkTheme = createMuiTheme({
palette: {
type: "dark"
}
});
const lightTheme = createMuiTheme({
palette: {
type: "light"
}
});
But when I use Typography component its color property does not change. Even more - color is inherited from html so Typography is unaware of current theme.
Is there way to configure Typography color while creating theme or use default?
I have tried to put color prop in pallete object like so:
const darkTheme = createMuiTheme({
palette: {
type: "dark",
typography: {
body1: {
color: '#fff'
}
}
}
});
But had no luck. I've create codepen. And there I have discovered that if I downgrade material-ui to 3.1 it works fine - .MuiTypography-body1 class sets color property corresponding to theme.
The default behavior for Typography is to do nothing with color. The reason for this is that generally the color is controlled by the same component that is controlling the background color. For instance, if you put the Typography element within a Paper element, the Paper will control both background-color and color. In order to have the html and body elements honor your theme, you need to use CssBaseline.
Typography provides the color prop for explicitly controlling the color. Using color="textPrimary" will set the color of the Typography in the same way as CssBaseline sets the color for the body element.
Below is a working example demonstrating the behavior:
import React from "react";
import { createMuiTheme, MuiThemeProvider } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";
import CssBaseline from "@material-ui/core/CssBaseline";
import Paper from "@material-ui/core/Paper";
import Button from "@material-ui/core/Button";
const darkTheme = createMuiTheme({
palette: {
type: "dark"
}
});
const lightTheme = createMuiTheme({
palette: {
type: "light"
}
});
export default function App() {
const [topLevelDark, setTopLevelDark] = React.useState(false);
return (
<MuiThemeProvider theme={topLevelDark ? darkTheme : lightTheme}>
<CssBaseline />
<Button
variant="contained"
color="primary"
onClick={() => {
setTopLevelDark(!topLevelDark);
}}
>
Toggle Themes
</Button>
<div>
<Typography variant="body1">I'm within the top-level theme</Typography>
<MuiThemeProvider theme={topLevelDark ? lightTheme : darkTheme}>
<Paper>
<Typography variant="body1">
I'm in a Paper within the nested theme
</Typography>
</Paper>
<Typography variant="body1" color="textPrimary">
I'm in the nested theme with textPrimary color, but outside of a
Paper. This makes me hard to read since nothing is setting the
background-color to something contrasting.
</Typography>
<Typography variant="body1">
I'm in the nested theme outside of a Paper with no explicit color.
</Typography>
</MuiThemeProvider>
</div>
</MuiThemeProvider>
);
}
A note about using multiple themes
In your code sandbox example, you had two sibling ThemeProvider elements, but when using your own custom theme it is important for your custom theme to be at the top-level. If you use a different theme for part of the page, it should be nested within your top-level theme. If you have two top-level ThemeProvider elements (i.e. neither one nested within the other), they will both be trying to impact the global Material-UI CSS class names. This means that only one of them will win, and the other won't seem to work at all. When Material-UI detects that you are within a nested ThemeProvider, it will use different (suffixed) class names within the nested theme, and the nested theme will work as expected.
Related answers:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With