Reputation: 5591
Using ReactJS and Material UI, I have a project in which I have changed the theme colors.
const newTheme = getMuiTheme({
fontFamily: 'Roboto, sans-serif',
palette: {
primary1Color: cyan500,
primary2Color: cyan700,
primary3Color: grey400,
accent1Color: amberA400,
accent2Color: grey100,
accent3Color: grey500,
textColor: darkBlack,
alternateTextColor: white,
canvasColor: white,
borderColor: grey300,
disabledColor: fade(darkBlack, 0.3),
pickerHeaderColor: cyan500,
clockCircleColor: fade(darkBlack, 0.07),
shadowColor: fullBlack,
},
});
// App class
render() {
return(
<ThemeProvider theme={newTheme}>
<Project />
</ThemeProvider>
)
}
Everything works as expected. Certain components, like buttons have the ability to set the color based on the primary prop. However, I have a component that uses an icon that needs the primary color. I can import the color and set it directly:
import React from 'react';
import ActionLock from 'material-ui/svg-icons/action/lock';
import {cyan500} from 'material-ui/styles/colors';
export default class LockIcon extends React.Component {
render() {
return(
<ActionLock color={cyan500} />
)
}
}
Is there some way to reference the theme's primary color, rather than setting the color in each component individually? Something like:
import React from 'react';
import ActionLock from 'material-ui/svg-icons/action/lock';
import {primary1Color} from 'somewhere';
export default class LockIcon extends React.Component {
render() {
return(
<ActionLock color={primary1Color} />
)
}
}
Upvotes: 38
Views: 64933
Reputation: 363
With MUI 5 and the createTheme()
function, you can reference the palette inside your ThemeOptions
by passing a function as the typography
value. This function accepts the palette as it's first argument.
This lets you easily map the various hX and bodyX typography variants.
const theme = createTheme({
palette: {
primary: {
main: "#2D3178",
},
},
typography: (palette) => ({
h1: {
fontSize: "2rem",
fontWeight: 700,
color: palette.primary.main,
},
}),
});
You can also reference the theme in the sx
prop by passing a function
<Box sx={(theme) => ({
backgroundColor: theme.palette.secondary.main,
})}/>
Upvotes: 1
Reputation: 814
You can use the useTheme() hook and access the colors like the example below. There are also some other color variants as well.
Mui 5:
import * as React from 'react';
import PropTypes from 'prop-types';
import { NavLink } from "react-router-dom";
import { useTheme } from "@mui/material/styles";
function VinNavLink(props) {
const theme = useTheme();
return (
<NavLink {...props} style={({ isActive }) => isActive ? { textDecoration: "underline", color: theme.palette.primary.main} : undefined}>{props.children}</NavLink>
);
}
export default VinNavLink;
Upvotes: 6
Reputation: 3596
For the users of MUI v5, you can specify a function inside the sx
css style directly, ex:
<Box sx={{ color: (theme) => theme.palette.primary1Color }} />
Upvotes: 4
Reputation: 81280
If you're using system properties, you can define a string path of the Palette
object to the color value like below:
<Box sx={{ color: "primary.main" }}>primary.main</Box>
<Box sx={{ color: "secondary.main" }}>secondary.main</Box>
<Box sx={{ color: "error.main" }}>error.main</Box>
<Box sx={{ color: "warning.main" }}>warning.main</Box>
<Box sx={{ color: "info.main" }}>info.main</Box>
<Box sx={{ color: "success.main" }}>success.main</Box>
<Box sx={{ color: "text.primary" }}>text.primary</Box>
<Box sx={{ color: "text.secondary" }}>text.secondary</Box>
<Box sx={{ color: "text.disabled" }}>text.disabled</Box>
The above is the same as:
<Box sx={{ color: theme => theme.palette.primary.main }}>primary.main</Box>
<Box sx={{ color: theme => theme.palette.secondary.main }}>secondary.main</Box>
<Box sx={{ color: theme => theme.palette.error.main }}>error.main</Box>
<Box sx={{ color: theme => theme.palette.warning.main }}>warning.main</Box>
<Box sx={{ color: theme => theme.palette.info.main }}>info.main</Box>
<Box sx={{ color: theme => theme.palette.success.main }}>success.main</Box>
<Box sx={{ color: theme => theme.palette.text.primary }}>text.primary</Box>
<Box sx={{ color: theme => theme.palette.text.secondary }}>text.secondary</Box>
<Box sx={{ color: theme => theme.palette.text.disabled }}>text.disabled</Box>
The example using the callback is more verbose but is type-safe, the shorter one with only string is quicker and good when prototyping, but you may want to store the string in a constant to prevent any typo errors and help the IDE refactor your code better.
Upvotes: 18
Reputation: 618
Yes you have! using muiThemeable..
import muiThemeable from 'material-ui/styles/muiThemeable';
class LockIcon extends React.Component {
render() {
return(
<ActionLock color={this.props.muiTheme.palette.primary1Color} />
)
}
}
export default muiThemeable()(LockIcon)
Upvotes: 18
Reputation: 2909
With react hooks, now you don't need to warp component in withTheme, just use useTheme:
import { useTheme } from '@material-ui/core/styles';
export default function MyComponent() {
const theme = useTheme();
return <span>{`spacing ${theme.spacing}`}</span>;
}
Upvotes: 5
Reputation: 954
If you're using React v16.8.0 and Material-UI v3.5.0 or greater, you can utilize the useTheme()
hook:
import { useTheme } from '@material-ui/core/styles';
function LockIcon = () => {
const theme = useTheme();
return (
<ActionLock color={theme.palette.primary1Color} />
}
Upvotes: 49
Reputation: 973
Ok if you are using material-ui version greater than 4, then the above solution might not work for you. Follow the below's code
import { withTheme } from '@material-ui/core/styles';
function DeepChildRaw(props) {
return <span>{`spacing ${props.theme.spacing}`}</span>;
}
const DeepChild = withTheme(DeepChildRaw);
Reference: https://material-ui.com/styles/advanced/
Upvotes: 4
Reputation: 5143
Adding how to access theme colors in material-ui v1.0.0 (currently beta) Using withTheme component.
Also check the following Example.
import React, {Component} from 'react';
import { withTheme } from 'material-ui/styles';
class WithThemeExample extends Component {
render() {
const { theme } = props;
const {primary, secondary} = theme.palette.text;
return (
<div>
<div style={{color: primary}}>Hi in Primary color</div>
<div style={{color: secondary}}>Bye in Secondary color</div>
</div>
);
}
}
export default withTheme()(WithThemeExample);
Upvotes: 15