material-ui
material-ui copied to clipboard
[IconButton] Custom color causes TypeError
Duplicates
- [X] I have searched the existing issues
Latest version
- [X] I have tested the latest version
Current behavior 😯
When I augment IconButton
with new colors:
declare module "@mui/material/IconButton" {
interface IconButtonPropsColorOverrides {
textPrimary: true;
textSecondary: true;
}
}
and then try to use these colors:
<IconButton color="textPrimary">
<CloseIcon />
</IconButton>
My app crashes with:
TypeError: Cannot read properties of undefined (reading 'main')
at the following location:
https://github.com/mui/material-ui/blob/dec32b361714bed9c73ee1360c4b6390769bf9f5/packages/mui-material/src/IconButton/IconButton.js#L78
Expected behavior 🤔
IconButton
doesn't throw TypeError when using custom color. Instead it handles it safely, like SvgIcon
:
https://github.com/mui/material-ui/blob/dec32b361714bed9c73ee1360c4b6390769bf9f5/packages/mui-material/src/SvgIcon/SvgIcon.js#L54
Steps to reproduce 🕹
No response
Context 🔦
No response
Your environment 🌎
No response
The customization capability is not complete. I marked this as an enhancement.
The fix can use optional chaining like in SvgIcon
. However, please note that when you customize the color prop, you are opting out of the theme palette so you have to style by:
createTheme({
components: {
MuiIconButton: {
root: ({ ownerState, theme }) => ({
...ownerState.color === 'textPrimary' && {
// your style
}
})
}
}
})
The customization capability is not complete.
Ah that explains it.
I worked around it by passing the color to the icon component instead, and augmenting SvgIconPropsColorOverrides
:
<IconButton>
<CloseIcon color="textPrimary" />
</IconButton>
Is this issue open to working on? I'd like to take it. @emlai
@Shubhamchinda I don't think it's being worked on, so feel free to take it. Thank you!
@Shubhamchinda I don't think it's being worked on, so feel free to take it. Thank you!
Great, thanks. I'll take this.
@Shubhamchinda @emlai
Any progress? Would love to implement this PR
@Shubhamchinda @emlai
Any progress? Would love to implement this PR
@geraldaddey Give me a day, and I'll submit a PR.
Is this issue still open to work on? Would like to work on it
@shachargiladi 4 weeks since the last response, so I think it was abandoned. I'd say go ahead!
Hi is anyone working one this .I'd like to take it. @emlai
Hi is anyone working one this? I'd like to take it. @emlai
Hi anyone still working on this? I'd like to take it. @emlai @cyberGHostJs @hilalsidhic
Hey, doesn't seems to be an issue for me :thinking: . I was thinking to pick this up, but it didn't reproduce for me. @emlai
My bad, reproducible. @rizamoyi have you started work on it or are you working on it? If not, I can pick this up.
@kushagra010 I started working on it.
is this issue still on or can take it over and work on it?
@harsh5902 you can take it over
I have solved the this problem and created a pull request, please do review it.
@harsh5902 Why was the PR closed?
The PR to fix this issue should:
- custom color works with TypeScript
- make sure that the custom color does not crash
- add a demo to show that the color prop can be augmented
@ZeeshanTamboli if you are available, this could be one to pick up.
@ZeeshanTamboli if you are available, this could be one to pick up.
I am on a bit of a break currently and won't be working next 3-4 weeks much effectively. If somebody else wants to take a look till then, please go ahead.
this is working fine i guess, i just tested it. at first you need to provide the props in Palette and PaletteOptions interface that lies in the @mui/material/styles/, the color names that you want to add into the project
declare module '@mui/material/styles' {
interface Palette {
primaryVariant500: Palette['primary'];
secondaryVariant500: Palette['primary'];
}
interface PaletteOptions {
primaryVariant500?: PaletteOptions['primary'];
secondaryVariant500?: PaletteOptions['primary'];
}
}
and add these lines for IconButton
declare module "@mui/material/IconButton" {
interface IconButtonPropsColorOverrides {
primaryVariant500: true;
secondaryVariant500: true;
}
}
these enabling the createTheme to be aware of these colors, then you need to provide the implementation in the theme that would be passed in the themeProvider, like so
export const theme = createTheme({
palette: {
primaryVariant500: {
main: '#ff0000'
},
secondaryVariant500: {
main: '#0000ff'
},
}
});
because we do want to let the mui know the values of the color. hope it helps. thanks.
@emlai the problem for you might be that you're not writing up the color prop in createTheme for palette
@the-mgi Yes, if your palette has the exact same key as the specified color
, then this will work fine.
But we're intending to use color="textPrimary"
or color="text.primary"
to access the usual text.primary.main
that we have in our palette. Currently neither of those work.
@the-mgi Yes, if your palette has the exact same key as the specified
color
, then this will work fine.But we're intending to use
color="textPrimary"
orcolor="text.primary"
to access the usualtext.primary.main
that we have in our palette. Currently neither of those work.
got it. thanks.
Hello there, is there any work around ? I'm still having the same problem.
mui.d.ts
LightTheme.tsx
Any component that I try to change the color
Actually it works with Typography, but I think it's the only one
@siriwatknp @the-mgi @kushagra010
@TCsTheMechanic Workaround for IconButton is to pass the color
prop to the icon component instead: https://github.com/mui/material-ui/issues/33054#issuecomment-1148613095
@emlai also doesn't work
@TCsTheMechanic Did you augment the typings:
declare module "@mui/material/SvgIcon" {
interface SvgIconPropsColorOverrides {
"textColor.light": true;
}
}
@emlai still nothing, I'm using @mui/icons-material
, I don't know if it follows the same module
I am not sure what is the issue here. Custom color does work with typescript with module augmentation and can be augmented. If the custom color is not defined in the palette it will crash. CodeSandbox: https://codesandbox.io/s/vigorous-bardeen-7pnhv6?file=/src/App.tsx