I'm using React (v5) and Material UI with TypeScript.
I'd like to be able to support TextField
s in large
as well as small
and medium
. There are specific heights to be associated with those sizes.
I augmented the TextField
module to register the new value for the size attribute:
declare module '@mui/material/TextField' {
interface TextFieldPropsSizeOverrides {
large: true;
}
}
I'd like the default to be medium
.
I want the heights to apply to <TextField select>
as well as "regular" <TextField>
elements, so I believe I want to override the height on the MuiInputBase
child element.
Here's what I'm passing to createTheme()
:
components: {
MuiTextField: {
styleOverrides: {
root: {
'& .MuiInputBase-root': {
height: '48px',
},
'&[size="medium"] .MuiInputBase-root': {
height: '48px',
},
'&[size="small"] .MuiInputBase-root': {
height: '32px',
},
'&[size="large"] .MuiInputBase-root': {
height: '56px',
},
...
The base style does get applied -- text fields are 48px high.
And I can specify size="large"
on my TextField
s without getting build / syntax check errors.
But doing so has no effect: the fields remain at the base height (48px).
I also tried using a marker CSS class, i.e.
'&.myapp-lg .MuiInputBase-root': {
height: '56px',
},
... and adding className="myapp-lg"
to the TextField
. But, again, the style rule is ignored.
I understand I could use a styled component, but that seems like a lot of overhead just to control the sizing.
I also understand I could potentially define a custom variant for the TextField
. But that's not really what variants are for (at least as I understand it); and what I really want to do is "inherit" the styling -- except the size -- of existing variants.
Am I getting the incantation(s) wrong? (I feel like I must be missing something obvious.)
...or is this perhaps a limitation of the theming subsystem?
I managed to get the marker class approach working.
The "flattened" style rule doesn't work for whatever reason. But if you nest the rule for the inner div
, it does work:
components: {
MuiTextField: {
styleOverrides: {
root: {
...
'&.myapp-lg': {
height: '56px',
'& .MuiInputBase-root': {
height: '56px',
},
},
...
... this answer to a related question is what put me on the right track.
I have seen similar behavior in the past when using LESS, I probably should have tried something like this sooner.
But again, the marker class approach is more of a workaround then a solution IMHO.
Checking for an attribute e.g. [size="large"]
doesn't work because that's not how React generates the final markup. (Duh.)
Instead, when React generates the nested <div>
with CSS class MuiInputBase
, an additional marker class is applied to that nested div
, in this case, MuiInputBase-sizeLarge
.
So the object passed to createTheme
needs to be:
components: {
MuiTextField: {
styleOverrides: {
root: {
...
//&[size="large"]
'& .MuiInputBase-sizeLarge': {
height: '56px',
},
...