I have recently started using Material ui (v5) and I am facing some issues with theme customization. I want to change the font-family for all the components through the ThemeProvider and creating a new theme. I am able to see the theme in the react inspector with the correct values but those values don't get applied to the components (specifically fontFamily but nothing works really).
This is what my ThemeProvider looks like:
import React from "react";
import {
createTheme,
ThemeProvider as MUIThemeProvider,
} from "#mui/material/styles";
const theme = createTheme({
typography: {
fontFamily: "serif",
},
});
type ThemeProviderProps = {
children: React.ReactNode;
};
const ThemeProvider = ({ children }: ThemeProviderProps) => (
<MUIThemeProvider theme={theme}>{children}</MUIThemeProvider>
);
export default ThemeProvider;
The ThemeProvider then wraps every story (using storybook):
<div
style={{
height: "100%",
width: "100%",
}}
>
<ThemeProvider>
<Story {...context} />
</ThemeProvider>
</div>
);
export const decorators = [withThemeProvider];```
I am able to see the theme I created if I use the useTheme hook or in the ThemeProvider in the components inspector (please ignore the different fontFamily in the screenshot below):
When I look at the actual component I see that it is still getting the default styles:
I am sure I am doing something stupid somewhere?
Related
I am aware of custom theming process within react-admin.
I was wondering if in react-admin it is possible to implement a custom theme without needing to go component by component and theming them ourselves. Something like for example Material Ui premium themes (see here)
Yes, definitely. You can pass a custom theme to the <Admin> component:
const App = () => (
<Admin theme={myTheme} dataProvider={simpleRestProvider('http://path.to.my.api')}>
// ...
</Admin>
);
Here is an example custom theme:
import { defaultTheme } from 'react-admin';
import merge from 'lodash/merge';
import indigo from '#material-ui/core/colors/indigo';
import pink from '#material-ui/core/colors/pink';
import red from '#material-ui/core/colors/red';
const myTheme = merge({}, defaultTheme, {
palette: {
primary: indigo,
secondary: pink,
error: red,
contrastThreshold: 3,
tonalOffset: 0.2,
},
typography: {
// Use the system font instead of the default Roboto font.
fontFamily: ['-apple-system', 'BlinkMacSystemFont', '"Segoe UI"', 'Arial', 'sans-serif'].join(','),
},
overrides: {
MuiButton: { // override the styles of all instances of this component
root: { // Name of the rule
color: 'white', // Some CSS
},
},
},
});
You can find more information at https://marmelab.com/react-admin/Theming.html#writing-a-custom-theme, and a complete example of custom admin theme in the e-commerce demo (https://github.com/marmelab/react-admin/blob/master/examples/demo/src/layout/themes.ts).
I have made customTheme using createMuiTheme() and I used it in the <ThemeProvider>.
Now, I want to make some custom styles using that customTheme inside the makeStyles() function. But makeStyles() is not getting my customTheme. It gets the default theme.
Code:
import React from 'react';
import { createMuiTheme, makeStyles, ThemeProvider } from '#material-ui/core';
const customTheme = createMuiTheme({
palette: {
primary: {
main: '#f0f'
},
}
});
const useStyles = makeStyles((theme) => ({
box: {
height: '100px',
width: '100px',
backgroundColor: theme.palette.primary.main
}
}));
export default function App() {
const classes = useStyles();
return (
<ThemeProvider theme={customTheme}>
<div className={classes.box}>
makeStyles
</div>
<div style={{
height: '100px',
width: '100px',
backgroundColor: customTheme.palette.primary.main
}}>
inline style
</div>
</ThemeProvider>
);
}
Screenshot:
Screenshot Image
As can see in the Screenshot, the first <div> has default deep blue color of Material-UI that is using makeStyles.
The second <div> has the custom color, that is using inline style.
So, how can I use the customTheme in makeStyles()?
Try ThemeProvider to wrap over App component, as per my understanding theme provided will be applied to react components wrapped under it. since "makeStyles div" is just an element styles didn't apply to it.
Codesandbox Link - https://codesandbox.io/s/mui-custom-theme-f354x
I want to override the color of some icons based on theme.type to a native PaletteColor. I can check the type and conditionally set the color like this:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
someIcon: {
color:
theme.palette.type === "dark"
? theme.palette.warning.dark
: theme.palette.warning.light,
},
})
);
This is pretty verbose every time I want to override something though, so it can be refactored to themeColor below:
const themeColor = (theme: Theme, color: PaletteColor) =>
theme.palette.type === "dark"
? color.dark
: color.light;
const useStyles = makeStyles((theme: Theme) =>
createStyles({
someIcon: {
color: themeColor(theme, theme.palette.warning)
},
})
);
Which now makes me think, does Material-UI have some native helper that already does this?
I digged in the Material-UI source code for a while and here is what I found:
You can see any potential helper methods related to Material-UI style here.
There is this commit that changed palette.type to palette.mode, if you Ctrl+F to search for 'light' ? or 'dark' ?, you'll see that they also use ternary operator to assign the colors based on the dark | light mode so I doubt they have any helper method like what you described in the second snippet.
I'm trying to integrate material-ui to my project and I have some issues with custom theme settings
I created a custom theme this way
App.js
const theme = createMuiTheme({
palette: {
primary: green,
secondary: red,
},
});
class App extends Component {
render() {
return (
<MuiThemeProvider theme={theme}>
<BrowserRouter>
<Switch>
...}}
Then in a component in the substructure I create some specific css.
Now my issue is that I'm obliged to define style appBar with a backgroud color and apply it explicitely on the AppBar component. If I don't do one of these two operations, the bg of the appBar remains light gray
What is weired is that I get the correct green from theme.palette.primary["500"], which means the theme is correctly configured
Header.js
const styles = theme => ({
root: {
flexGrow: 1,
},
grow: {
flexGrow: 1,
},
appBar: {
backgroundColor: theme.palette.primary["500"]
},//...)}
class Header extends Component {
constructor(props) {
super(props)
this.classes = props.classes
}
render() {
return (<I18n>
{(tsl, {i18n, t, ready}) => {
return (
<div className={this.classes.root}>
<AppBar position="static" color="default" className={this.classes.appBar}>
<Toolbar>...(irrelevant code)
I followed the examples in https://material-ui.com/demos/app-bar/ where the first example has the light gray color, then all the other examples have a blue bg, but there's nothing in the source code that was added to apply the blue color (in my opinion)
Any help please? thanks folks
Use <AppBar position="static" color="primary">.
By default AppBar is using the colors from the grey palette.
We are considering defaulting to primary for the color prop since it's not following the spec and having grey as a default for something as prominent as the app bar is a bad idea anyway.
I looked through the doc and couldn't find an attribute z-index which defines the Drawer display style : over / beneath the AppBar ? Any quick ways to do that ?
Thx,
Here you go:
<Drawer
containerStyle={{zIndex: 1000}}
>
for some z-index != AppBar's
You can style the drawer and the app bar at the top-level of your app, using the ThemeProvider. There is a zIndex property which describes these values for different components.
import { ThemeProvider } from "#material-ui/styles";
import { createMuiTheme } from "#material-ui/core/styles";
const customTheme = createMuiTheme({
zIndex: {
appBar: 1100,
drawer: 1200
}
});
// Then, wrap your app with a ThemeProvider
<ThemeProvider theme={customTheme}>
<App />
</ThemeProvider>