By default the MUI theme is a combination of several pre-defined objects such as typography: {...}
, palette: {...}
etc.
Is is possible to add a custom object into this setup and still use createTheme
?
So for example the theme object would become:
const theme = {
palette: {
primary: '#000'
},
typography: {
body1: {
fontFamily: 'Comic Sans'
}
},
custom: {
myOwnComponent: {
margin: '10px 10px'
}
}
}
Yes, this works just fine. Material-UI does a deep merge of its defaults with the object you provide with some special handling for keys that get merged in a more sophisticated fashion (such as palette
, typography
and a few others). Any unrecognized keys will come through unchanged.
Below is a working example:
import React from "react";
import ReactDOM from "react-dom";
import {
useTheme,
createMuiTheme,
MuiThemeProvider
} from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";
const theme = createMuiTheme({
palette: {
primary: {
main: "#00F"
}
},
typography: {
body1: {
fontFamily: "Comic Sans"
}
},
custom: {
myOwnComponent: {
margin: "10px 10px",
backgroundColor: "lightgreen"
}
}
});
const MyOwnComponent = () => {
const theme = useTheme();
return (
<div style={theme.custom.myOwnComponent}>
Here is my own component using a custom portion of the theme.
</div>
);
};
function App() {
return (
<MuiThemeProvider theme={theme}>
<div className="App">
<Button variant="contained" color="primary">
<Typography variant="body1">
Button using main theme color and font-family
</Typography>
</Button>
<MyOwnComponent />
</div>
</MuiThemeProvider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
You can add custom variables in your MUI theme as easy as:
const theme = createTheme({
myField: {
myNestedField: 'myValue',
},
});
But if you're using Typescript, you also need to update the definition of ThemeOptions
and Theme
using module augmentation:
declare module '@mui/material/styles' {
// fix the type error when referencing the Theme object in your styled component
interface Theme {
myField?: {
myNestedField?: string;
};
}
// fix the type error when calling `createTheme()` with a custom theme option
interface ThemeOptions {
myField?: {
myNestedField?: string;
};
}
}
If you want to reuse the type between Theme
and ThemeOptions
, you can define a common interface and inherit it in both places:
declare module '@mui/material/styles' {
interface CustomTheme {
myField?: {
myNestedField?: string;
};
}
interface Theme extends CustomTheme {}
interface ThemeOptions extends CustomTheme {}
}
Also note that you don't have to create custom variables in MUI theme if you want to override a custom component using createTheme()
. See this answer for more detail.
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