Material UI Alerts using custom colors - material-ui

Can I set a custom color for a MUI Alert component? The docs suggest that the only color options are the four that match the four severity props.

For MUI V5 in case someone is looking to change the background color in the theme this worked for me.
export const theme = createTheme({
components: {
MuiAlert: {
styleOverrides: {
standardSuccess: {
backgroundColor: 'green',
color: 'white'
},
standardError: {
backgroundColor: 'red',
color: 'white'
},
standardWarning: {
backgroundColor: 'orange',
color: 'white'
},
standardInfo: {
backgroundColor: 'grey',
color: 'black'
}
}
},
},
});
And is working by setting the variant:
<Alert severity="success">Success</Alert>
<Alert severity="error">Error</Alert>
<Alert severity="warning">Warning</Alert>
<Alert severity="info">Info</Alert>

It's possible. Quoting the API docs:
You can override the style of the component thanks to one of these
customization points:
With a rule name of the classes object prop.
With a global class name.
With a theme and an overrides property.
A crude example in this codesandbox

A simple approach would be:
const useStyles = makeStyles((theme) => ({
myAlert: {
color: "#ffffff",
backgroundColor: "#000000"
}
});
function MyCustomAlert() {
const classes = useStyles();
return (
<Alert severity="error" className={classes.myAlert}>
<AlertTitle>Error</AlertTitle>
{"I am an error message !"}
</Alert>
);
}

I guess another option, if you don't wanna deal with css classes, could be:
(using mui v5 and typescript)
first u define your styled component:
interface IAlert extends AlertProps {
background?: string
}
export const Alert = styled(MUIAlert)<IAlert>(({ background }) => ({
background,
}))
then, on your component that uses the Alert:
const Component = ({type}) => {
...
const CUSTOM_COLORS_MAPPING = {
success: palette.success[500],
info: palette.secondary[500],
error: palette.error[500],
warning: palette.warning[500],
}
return (
...
<Alert severity={type} background={CUSTOM_COLORS_MAPPING[type]}>
{message}
</Alert>
)

Related

MUI Dialog Background Color

I have a mui dialog and would like to set its background to black. (no color), but I don't succeed.
And I don't understand why it doesn't work.
My Dialog:
export const MyDialog = (props: any) => {
return (
<ThemeProvider theme={TestTheme}>
<CssBaseline />
<Dialog open={true}>
<DialogTitle>Title</DialogTitle>
<DialogContentText>Text</DialogContentText>
</Dialog>
</ThemeProvider>
);
};
My TestTheme looks like this:
export const TestTheme = createTheme(
{palette: {
mode: 'dark',
background: {
paper: '#000000',
// paper: 'red',
default: '#000000',
},
}
}
)
and it looks like this:
As we can see the dialog color has not the same black as the background even I have set the colors for both correctly.
If I set the colors :
paper: 'red',
// paper: '#000000',
// default: '#000000',
default: 'blue',
How can I set the background color of the dialog to black (no color)? (Regardless if it make sence or not, I would like to understand)
You are doing everything right with the way you set the background color.
The reason you see two different black colours is because when the Dialog is open is getting a class of MuiBackdrop-root which has a background-colour of background-color: rgba(0, 0, 0, 0.5); so this additional semi transparent layer is causing this colour difference.
Here is a codesandbox with a solution to your issue.
Code:
<Dialog open={true}
sx={{ //You can copy the code below in your theme
background: '#000',
'& .MuiPaper-root': {
background: '#000'
},
'& .MuiBackdrop-root': {
backgroundColor: 'transparent' // Try to remove this to see the result
}
}}>
<DialogTitle sx={{ color: "white" }}>Title</DialogTitle>
<DialogContentText sx={{ color: "white" }}>Text</DialogContentText>
</Dialog>
Hope it helps.

What is the correct way to extend MUI v5 component with additional components and styled utility?

What is the correct way to extend build-in components of MaterialUI v5? What I'd like to do:
Style the build-in component
Make a wrapper on top of my styled component with additional components
The current code:
import {Box, Link, LinkProps} from '#mui/material';
import {styled} from '#mui/material/styles';
const StyledLink = styled(Link)<LinkProps>({
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: '#6b7688',
fontWeight: 500,
fontSize: '12.8px',
textTransform: 'uppercase',
textDecoration: 'none',
'&:hover, &.Mui-focusVisible': {
color: '#313bac',
transition: 'all 0.3s ease-in-out',
// LinkHoverElement
'& .MuiBox-root': {
backgroundColor: '#313bac',
},
},
});
const LinkHoverElement = styled(Box)({
width: '5px',
height: '5px',
marginBottom: '5px',
borderRadius: '50%',
backgroundColor: 'transparent',
});
const MenuLink = ({children, ...restProps}: LinkProps) => {
return (
<StyledLink {...restProps}>
<LinkHoverElement />
{children}
</StyledLink>
);
};
export default MenuLink;
It works, I also may use all props ('sx' prop as well)
<MenuLink
sx={{mx: '1rem'}}
key={page}
href={`#${page}`}>
{page}
</MenuLink>
seems like a 'god object', I've read documentation and uses this articles:
Reusable component
styled()
but haven't found an complicated example and feel like the code above isn't a best practice
The codesandbox example

Passing classes inside component props

I am migrating my project from MUI v4 to v5. I want to use the recommended emotion and styled component patterns. So I'm avoiding makeStyles() and withStyles(). I have a pattern like this:
import withStyles from '#mui/styles/withStyles';
const styles = (theme) => ({
active: {
color: `${theme.palette.secondary.main}`,
},
completed: {
color: `${theme.palette.secondary.main}`,
},
});
function MyComponent() {
return (
<Step>
<StepLabel
StepIconProps={{
classes: {
active: classes.active,
completed: classes.completed,
},
}}
>
Some label
</StepLabel>
</Step>
);
}
export default withStyles(styles)(MyComponent);
How can I dynamically control the active and completed classes using StepIconProps and emotion?
The styled() function expects a Component as the first argument, so I can't use that directly. I was thinking about using createStyles().
I ended up using the sx prop like this:
function MyComponent() {
return (
<Step>
<StepLabel
StepIconProps={{
sx: {
"&.Mui-active": {
color: "secondary.main"
},
"&.Mui-completed": {
color: "secondary.main"
},
},
}}
>
{label}
</StepLabel>
</Step>
);
}

Unable to pass props to makeStyles when using material UI with next.js

I am using Next.js with material UI.
I have created a Icon and when clicked it calls the setOpenFn() and sets the open variable to be true. This variable is then passed as props to the useStyles(). Now I display the search bar if open is true. But I get the below error
webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:67 Warning: Prop `className` did not match. Server: "makeStyles-search-3 makeStyles-search-8" Client: "makeStyles-search-3 makeStyles-search-9"
When the search Icon is clicked display: flex property is also not working.
I tried to create .babelrc file and added this
{
"presets": ["next/babel"],
"plugins": [["styled-components", { "ssr": true }]]
}
but still nothing works.
const useStyles = makeStyles((theme) => ({
search: {
[theme.breakpoints.down('sm')]: {
display: (props) => (props.open ? 'flex' : 'none'),
width: '70%',
},
}
}))
const Navbar = () => {
const [open, setOpen] = useState(false);
const setOpenFn = () => {
setOpen(true);
};
const classes = useStyles({ open });
return(
<Search
className={classes.searchButton}
onClick={() => {
setOpenFn();
}}
/>
)
}
I am assuming you are using mui version 5+
According to this migration guide! you need to wrap your JSX with the following component.
<StyledEngineProvider injectFirst>
</StyledEngineProvider>

Material-UI Style Override?

I'm updating my app from Material-UI v1 to v2. I'm trying to use a style override to set the color of a selected <BottomNavigationAction> element.
const styles = {
bottomNavStyle: {
position: 'fixed',
left: '0px',
bottom: '0px',
height: '50px',
width: '100%',
zIndex: '100'
},
'&$selected': {
color: "#00bcd4" //<==trying to add this color to selected items
},
};
class bottom_nav extends Component {
state = {
selectedIndex: -1,
};
handleChange = (event, value) => {
this.setState({value});
};
render() {
const { classes } = this.props;
return (
<Paper className={classes.bottomNavStyle}>
<BottomNavigation
value={this.props.selectedBottomNavIndex}
onChange={this.handleChange}
showLabels
>
<BottomNavigationAction
label="Appointments"
icon={theApptsIcon}
/>
<BottomNavigationAction
label="Contacts"
icon={theEmailIcon}
/>
<BottomNavigationAction
label="Video Call"
icon={theVideoCall}
/>
</BottomNavigation>
</Paper>
);
}
}
export default withStyles(styles)(bottom_nav);
But, this does not do anything to the color of selected items.
I've read the Material-UI docs on CSS in JS and JSS, but haven't quite gotten it yet. What is the correct syntax for this?
UPDATE
Based on a response to this thread I've tried this:
const styles = {
bottomNavStyle: {
position: 'fixed',
left: '0px',
bottom: '0px',
height: '50px',
width: '100%',
zIndex: '100'
},
actionItemStyle: {
'&$selected': {
color: "#00bcd4 !important"
},
},
}
[.....]
return (
<Paper className={classes.bottomNavStyle}>
<BottomNavigation
value={this.props.selectedBottomNavIndex}
onChange={this.handleChange}
showLabels
>
<BottomNavigationAction
label="Appointments"
icon={theApptsIcon}
className={classes.actionItemStyle}
/>
<BottomNavigationAction
label="Contacts"
icon={theEmailIcon}
className={classes.actionItemStyle}
/>
<BottomNavigationAction
label="Video Call"
icon={theVideoCall}
className={classes.actionItemStyle}
/>
</BottomNavigation>
</Paper>
);
}
...but have not yet gotten the new color to appear on the web page.
Your updated solution looks good, there are just a few small changes...
You need to include an empty .selected class in your styles rules.
const styles = {
// Root styles for `BottomNavigationAction` component
actionItemStyles: {
"&$selected": {
color: "red"
}
},
// This is required for the '&$selected' selector to work
selected: {}
};
You need to pass classes={{selected: classes.selected}} to BottomNavigationAction. This is required for the '&$selected' selector to work.
<BottomNavigation
value={value}
onChange={this.handleChange}
className={classes.root}
>
<BottomNavigationAction
classes={{
root: classes.actionItemStyles,
selected: classes.selected
}}
label="Recents"
value="recents"
icon={<RestoreIcon />}
/>
</BottomNavigation>
Live Example:
There are couple of things I would like to suggest.
1) Write the name of the component with first letter capitalized since it is not treated the same way if it is named with small first letter and with capitalized.
2) If there is no other way for your cs rule to be applied, if it is overridden always because of some css specificity, use !iportant at the end of the rule.
3) Try this type of nesting of css in jss:
const styles = {
bottomNavStyle: {
position: 'fixed',
left: '0px',
bottom: '0px',
height: '50px',
width: '100%',
zIndex: '100',
'&:selected': {
color: "#00bcd4"
},
},
};