Sunday, November 12, 2023
Mastering default styles and props customization in MUI
 views
MUI's theming system is amazing. USE IT
A common phenomenon that I personally observed from beginners is they tend to create wrapper components and apply branding styles and behaviors to it and nothing else, e.g.
Will this work? Absolutely, but this method has a drawback. Every member of the team needs to be clear about which wrapper components are created and should be used instead of the original ones from MUI. This can get out of hand when the project and the team size grow. Fortunately, there is actually a more maintainable way to achieve this, which is to make use of MUI's theming system.
Customize the default props
To override the default props of an MUI component, specify those in components.Mui[ComponentName].defaultProps
. e.g.
This will change the default value of disableUnderline
for all FilledInput
to true
, effectively hide its underline by default (and in turn, <TextField variant="filled" />
's underline as well).
One exception here is sx
. Though it might be tempting to specify sx
here to override the default styling of a component, there is a better place for it, and is much more powerful as well, which we will explore in the next section.
Customize the default styles
Similar to defaultProps
, the default styles of an MUI component can be overridden in styleOverrides
. e.g.
This will change the default background color of FilledInput
to white (similarly, <TextField variant="filled" />
's background color will also be affected).
One thing to note is that the system prop shorthands, e.g. bgcolor
for this case specifically, can NOT be used in styleOverrides
. Though Emotion syntax can still be used, e.g.
Gaining access to the design tokens
One thing you may have noticed from the previous example is that we are hard coding color codes here, which is not the brightest idea since typically, these should be managed by design tokens. These can be addressed by specifying styleOverrides.[slot]
as a function instead of an object.
With this, we have access to the theme
object we are currently defining in styleOverrides
. Thus, can do all sorts of operations that we have gotten used to, like theme.spacing()
and theme.breakpoints.up()
here.
Conditional rendering
Another use case is to define the default styles depending on the state/props of the component. The function syntax of styleOverrides.[slot]
provides ownerState
for that purpose. e.g.
Consider the ownerState
as a combination of props and internal state. For this example, <FilledInput error />
's background will be red, while <FilledInput />
's will be white.
State classes don't need special handling anymore
If you have been searching online, you may have come across some resources suggesting certain states like error
and disabled
need special handling, e.g.
This was indeed the case before ownerState
was introduced. But nowadays, ownerState
can handle them alright, so we don't need to do this anymore.