Customize multiple mui components - reactjs

From MUI's docs you have the ability to customize a component. But is there a way to customize multiple components?
Say I want to customize MuiPaper and MuiList with the same styles.
E.g of customizable components:
const theme = createTheme({
components: {
// Name of the component
MuiPaper: {
defaultProps: {
// The props to change the default for.
backgroundColor: '#101010',
},
},
},
});

there are multiple ways to customize the default props. please check below I have added three ways to customize the components. also you can add more components to it.
theme.js
const mytheme = {
components: {
MuiPaper: {
styleOverrides: {
root: ({ theme }) => ({ // using with theme
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
}),
},
},
MuiList : {
styleOverrides: {
root: { // adding direct CSS properties with screensize condition.
'#media (min-width:600px)': {
minHeight: '4.5rem',
backgroundColor: '#101010',
},
},
},
},
MuiButton: {
styleOverrides: {
root: ({ ownerState, theme }) => ({ // changing only 'contained' variant or adding new variant.
textTransform: 'capitalize',
...(ownerState.variant === 'contained' && {
color: theme.palette.primary.contrastText,
backgroundColor: theme.palette.primary.light,
}),
}),
},
},
},
};
export default mytheme;
app.js
const App = () => {
<ThemeProvider theme={createTheme(mytheme)}>
...
</ThemeProvider>
}
export default App;

Related

How to change default typography for Textfields and such via theme in MUI v5?

Is there a way to map default typography for TextField and all my inputs via theme? I know I can do this
components: {
MuiInput: {
styleOverrides: {
root: {
fontSize: '16px',
lineHeight: '25px'
}
}
},
but I wish to find a way to map it to 'body2'
MuiInput: {
defaultProps: {
typographyProps???: {
variant: 'body2'
}
}
For using body2 font size value in another component, You need to access the theme object's typography property.
Then You will set the MUI TextFiled's font-size equal to that value from the theme object.
import { createTheme } from "#mui/material";
const theme = createTheme({});
theme!.components!.MuiTextField = {
styleOverrides: {
root: {
"& .MuiInputBase-input": {
fontSize: theme.typography.body2.fontSize, // this is the default mui body2 font-size
lineHeight: "25px", // and any other styles you want...
},
},
},
};
And You can change the body2 fontSize when defining the theme object:
const theme = createTheme({
typography: {
body2: {
fontSize: 80,
},
});
theme!.components!.MuiTextField = {
styleOverrides: {
root: {
"& .MuiInputBase-input": {
fontSize: theme.typography.body2.fontSize, // this will be 80px
lineHeight: "25px", // and any other styles you want...
},
},
},
};
EDIT:
If You are not ok with overriding the theme after defining it, You can use this approach:
import { createTheme } from "#mui/material";
const myBody2FontSize = 20px;
const theme = createTheme({
typography: {
body2: {
fontSize: myBody2FontSize,
},
},
components: {
MuiTextField: {
styleOverrides: {
root: {
"& .MuiInputBase-input": {
fontSize: myBody2FontSize , // this is the default mui body2 font-size
lineHeight: "25px", // and any other styles you want...
},
},
},
},
},
});
You could try setting it via classname. Its a bit awkward because an input doesnt actually use Typography internally.
MuiInput: {
defaultProps: {
className: 'MuiTypography-body2'
}
}
Or possibly
MuiTextField: {
defaultProps: {
InputProps: {className: 'MuiTypography-body2' }
}
}

Material UI React v5.8.0 "disableRipple: true" does not disable button ripple. What am I doing wrong?

I am trying to disable the ripple on buttons in Material UI v5 because my product does not need it. According to the Material UI docs, all I have to do is this:
import { createTheme } from '#mui/material';
const theme = createTheme({
components: {
// Name of the component ⚛️
MuiButtonBase: {
defaultProps: {
// The props to apply
disableRipple: true, // No more ripple, on the whole application 💣!
},
},
},
});
So I do that to my own theme, which is here:
import { createTheme } from '#mui/material/styles';
const theme = createTheme({
components: {
MuiButtonBase: {
defaultProps: {
disableRipple: true,
},
},
MuiButton: {
styleOverrides: {
root: {
textTransform: 'none',
borderRadius: "40px",
fontSize: "1.1875rem"
},
},
},
},
});
export default theme;
The style overrides work fine. But the disableRipple does not work. It still ripples. I tried applying to the default props of MuiButton as well. No luck.
I am using typescript, but this is not returning any errors.
Can anyone help me out here?

Theme override support for custom components

After the migration to mui v5 for react-admin, we realized that supporting theme overrides for our custom components seems to require more code than we expected. As it looks that this could be handled by the styled API, I would like to know if this is really required.
Here's an example of our Navigation link:
const PREFIX = 'RaMenuItemLink';
export const MenuItemLinkClasses = {
root: `${PREFIX}-root`,
active: `${PREFIX}-active`,
icon: `${PREFIX}-icon`,
};
const StyledMenuItem = styled(MenuItem, {
name: PREFIX,
// Why do I have to do this?
overridesResolver: (props, styles) => [
{ [`&.${MenuItemLinkClasses.active}`]: styles.active },
{ [`& .${MenuItemLinkClasses.icon}`]: styles.icon },
styles.root,
],
})(({ theme }) => ({
[`&.${MenuItemLinkClasses.root}`]: {
color: theme.palette.text.secondary,
},
[`&.${MenuItemLinkClasses.active}`]: {
color: theme.palette.text.primary,
},
[`& .${MenuItemLinkClasses.icon}`]: { minWidth: theme.spacing(5) },
}));
In your case, I think that I would start to simplify the code to:
const PREFIX = 'RaMenuItemLink';
export const MenuItemLinkClasses = {
root: `${PREFIX}-root`,
active: `Mui-active`,
icon: `${PREFIX}-icon`,
};
const StyledMenuItem = styled(MenuItem, {
name: PREFIX,
overridesResolver: (props, styles) => [
styles.root,
{ [`&.${MenuItemLinkClasses.active}`]: styles.active },
{ [`& .${MenuItemLinkClasses.icon}`]: styles.icon },
],
})(({ theme }) => ({
color: theme.palette.text.secondary,
[`&.${MenuItemLinkClasses.active}`]: {
color: theme.palette.text.primary,
},
[`& .${MenuItemLinkClasses.icon}`]: { minWidth: theme.spacing(5) },
}));
The overridesResolver property is meant to resolve this object:
const theme = {
components: {
[PREFIX]: {
styleOverrides: /* this object, it's the 'styles' arg of overridesResolver */,
},
},
};

How can I change MUI v5 Button to lighten on hover instead of darken using theme?

I have setup my theme as outlined in the docs.
palette: {
primary: {
main: customColor
}
}
When I hover, my mui button darkens based on the main color, but I want it to lighten based on the same color (without having to hard code a value anywhere). How can I achieve this?
Update:
Based on Prashant Jangam's answer I was able to get everything exactly as I needed it. See code below:
components: {
MuiButton: {
styleOverrides: {
root: ({ theme }) => ({
'&.MuiButton-containedPrimary:hover': {
backgroundColor: theme.palette.primary.light,
},
'&.MuiButton-containedSecondary:hover': {
backgroundColor: theme.palette.secondary.light,
},
}),
},
},
}
check the global component overide section for more details https://mui.com/customization/theme-components/#global-style-overrides
following code with give you start. here I have changed opacity on button hover state.
const theme = createTheme({
// your other theme settings here
components: {
MuiButton: {
styleOverrides: {
root: ({ ownerState }) => ({
'&:hover': {
opacity:0.5,
},
}),
},
},
},
});
I customize it like so:
const theme = createTheme({
get components() {
return {
MuiButton: {
styleOverrides: {
root: ({ ownerState }) => ({
'&:hover': {
backgroundColor: this.palette[ownerState.color].light,
transition: '0.2s',
},
}),
},
},
}
},
palette: {
primary: {
main: '#3E4BA0',
dark: '#313b7d',
light: '#5664bd',
},
},
})
At least on the version 4 of MUI the palette.primary.dark is the color that is used for hovering the button. Just replace the value of the dark property with the value that you want (hex color or rgb/rgba).
Note: It can also change some hovering colors on another components
const baseTheme = createMuiTheme({
palette: {
primary: {
main: '#4B882F',
dark: '#345F20', // <-------- rgba(75, 136, 47, 0.2)
light: '#6F9F58'
}
}
})
You can't use it like this because the baseTheme was not defined yet.
const baseTheme = createMuiTheme({
palette: {
primary: {
main: '#4B882F',
dark: baseTheme.palette.primary.light,
light: '#6F9F58'
}
}
})

Change ripple effect duration in MUI React

I want to modify ripple effect duration in theme file
I've tried things like
const theme = createMuiTheme({
props: {
MuiButtonBase: {
TouchRippleProps: {
animationDuration: '5s',
transitionDuration: '5s',
},
classes: {
root: 'CustomizeTouchRipple'
}
},
}
})
Not working.. but class is added
Edit:
I found its a constant in TouchRipple component
https://github.com/mui-org/material-ui/blob/c06a88d24235685dd769c1a3df82152ded17a6ca/packages/material-ui/src/ButtonBase/TouchRipple.js#L8
From the source, the class name where the animationDuration is set is MuiTouchRipple-rippleVisible. You just need to override that value:
V5
<Button
sx={{
'&& .MuiTouchRipple-rippleVisible': {
animationDuration: '200ms',
},
}}
>
V4
const theme = createTheme({
overrides: {
MuiButton: {
root: {
'& .MuiTouchRipple-rippleVisible': {
animationDuration: '200ms',
},
},
},
// if you want to change the ripple duration of all components that have ripple
// effect (e.g. Button, CardActionArea, FAB...)
MuiTouchRipple: {
rippleVisible: {
animationDuration: '200ms',
},
},
},
});

Resources