How to apply fontSize to CardHeader title in MUI? - reactjs

I want to change the title in CardHeader to 16px. I tried changing theme in App.js but it does not seem to work
const theme = createMuiTheme({
typography: {
useNextVariants: true,
overrides: {
MuiCardHeader: {
titleTypographyProps: {
variant:'h2'
}
}
}
}
);
In the component:
<CardHeader
action={
<IconButton color="inherit">
<MoreHorizIcon />
</IconButton>
}
title="Titletext"
/>
The title font still does not change. What do I need to do to fix this?

you cant target the header class or id and change fontSize or
pass as props
titleTypographyProps={{variant:'h1' }}
that object acepts:'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'subtitle1', 'subtitle2', 'body1', 'body2', 'caption', 'button', 'overline', 'srOnly', 'inherit', "display4", 'display3', 'display2', 'display1', 'headline', 'title', 'subheading'
in your code it would be
<CardHeader
action={
<IconButton color="inherit">
<MoreHorizIcon />
</IconButton>
}
titleTypographyProps={{variant:'h1' }}
title="Titletext"
/>

I know this is quite old post now, but for future references anyone who stumbles upon this question might take a look at: https://github.com/mui-org/material-ui/issues/7521
Basically, we can use the classes property, which takes key/value pairs, and can add style to parts of the <ContentHeader /> component based on that.
Example:
const useStyles = makeStyles({
root: {
minWidth: 300,
maxWidth: 500,
margin: "10px 15px 10px 0",
},
headerTitle: {
maxWidth: 300
}
});
const CustomizedCard = () => {
const materializeUIClasses = useStyles();
return (
<Card className={materialUIClasses.root}>
<CardHeader
title={title}
// Here we can target whatever part we need: title, subtitle, action
classes={{
title: materialUIClasses.headerTitle
}}
/>
</Card>
}

this piece of code worked for me:
<CardHeader
title={
<Typography gutterBottom variant="h5" component="h2">
/* Content goes here */
</Typography>
} />
notes: package: "#material-ui/core": "^4.5.2"
I use this solution because I make use of makeStyles module.

In MUI v5, you make use of system properties in Typography by adding a fontSize prop directly in titleTypographyProps or subheaderTypographyProps:
<CardHeader
titleTypographyProps={{
fontSize: 22,
}}
subheaderTypographyProps={{
fontSize: 10,
}}
title="Shrimp and Chorizo Paella"
subheader="September 14, 2016"
/>
Live Demo

Related

MaterialUI React duplicate keys error from mui components

While creating a navbar I used multiple collapse components from MUI in order to create generate the menu items.
Its not a code breaking error but an annoying to have one. I get the following error in my console.
Warning: Encountered two children with the same key, `indexCollapseListItem`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
List#http://localhost:3000/static/js/bundle.js:18632:82
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
Transition#http://localhost:3000/static/js/bundle.js:102860:30
Collapse#http://localhost:3000/static/js/bundle.js:12704:82
nav
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
List#http://localhost:3000/static/js/bundle.js:18632:82
div
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
Paper#http://localhost:3000/static/js/bundle.js:22524:82
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
Drawer#http://localhost:3000/static/js/bundle.js:13680:83
nav
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
Box#http://localhost:3000/static/js/bundle.js:29040:72
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
Box#http://localhost:3000/static/js/bundle.js:29040:72
NavBar#http://localhost:3000/static/js/bundle.js:1766:7
Dashboard
Routes#http://localhost:3000/static/js/bundle.js:101977:7
Router#http://localhost:3000/static/js/bundle.js:101914:7
BrowserRouter#http://localhost:3000/static/js/bundle.js:101391:7
App
Provider#http://localhost:3000/static/js/bundle.js:98572:15 react-dom.development.js:67
React 19
js index.js:8
factory react refresh:6
Webpack 3
Warning: Encountered two children with the same key, `indexCollapseListItem`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
List#http://localhost:3000/static/js/bundle.js:18632:82
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
Transition#http://localhost:3000/static/js/bundle.js:102860:30
Collapse#http://localhost:3000/static/js/bundle.js:12704:82
nav
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
List#http://localhost:3000/static/js/bundle.js:18632:82
div
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
Paper#http://localhost:3000/static/js/bundle.js:22524:82
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
Transition#http://localhost:3000/static/js/bundle.js:102860:30
Slide#http://localhost:3000/static/js/bundle.js:24602:7
Unstable_TrapFocus#http://localhost:3000/static/js/bundle.js:8464:7
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
Portal#http://localhost:3000/static/js/bundle.js:8032:7
ModalUnstyled#http://localhost:3000/static/js/bundle.js:7245:7
Modal#http://localhost:3000/static/js/bundle.js:21375:82
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
Drawer#http://localhost:3000/static/js/bundle.js:13680:83
nav
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
Box#http://localhost:3000/static/js/bundle.js:29040:72
div
./node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js/withEmotionCache/<#http://localhost:3000/static/js/bundle.js:5079:66
Box#http://localhost:3000/static/js/bundle.js:29040:72
NavBar#http://localhost:3000/static/js/bundle.js:1766:7
Dashboard
Routes#http://localhost:3000/static/js/bundle.js:101977:7
Router#http://localhost:3000/static/js/bundle.js:101914:7
BrowserRouter#http://localhost:3000/static/js/bundle.js:101391:7
App
Provider#http://localhost:3000/static/js/bundle.js:98572:15 react-dom.development.js:67
​I am not setting this key in my code but why is it being set by default, which component is being assigned the same key again and again and how can I fix this.
My navbar code is the following for your reference.
//ASSETS
import AuraLogo from '../../../assets/images/logo/aura.png'
//REACT
import { useState } from 'react'
import { Link } from 'react-router-dom'
//MenuItems
import menuItems from '../dashboard/menu-items/index'
//MUI
import PropTypes from 'prop-types'
import AppBar from '#mui/material/AppBar'
import Box from '#mui/material/Box'
import CssBaseline from '#mui/material/CssBaseline'
import Divider from '#mui/material/Divider'
import Drawer from '#mui/material/Drawer'
import IconButton from '#mui/material/IconButton'
import List from '#mui/material/List'
import ListItemIcon from '#mui/material/ListItemIcon'
import ListItemText from '#mui/material/ListItemText'
import MenuIcon from '#mui/icons-material/Menu'
import Toolbar from '#mui/material/Toolbar'
import Typography from '#mui/material/Typography'
import Collapse from '#mui/material/Collapse'
import ListSubheader from '#mui/material/ListSubheader'
import ListItemButton from '#mui/material/ListItemButton'
import ExpandLess from '#mui/icons-material/ExpandLess'
import ExpandMore from '#mui/icons-material/ExpandMore'
import ArrowBackIosNew from '#mui/icons-material/ArrowBackIosNew'
const drawerWidth = 240
// TODO - fix duplicate keys error in components from MUI
function NavBar(props) {
const { window } = props
const [mobileOpen, setMobileOpen] = useState(false)
// TODO - change appbar title depending on the category clicked
const [title, setTitle] = useState()
const [open, setOpen] = useState({
dashboard: true,
categories: true,
subcategories: true,
products: true,
auth: true,
other: false,
})
const handleClick = (id) => {
setOpen((prevState) => ({ ...prevState, [id]: !prevState[id] }))
}
// const handleClick = (id) => {
// setOpen({ ...state, [id]: !open[id] });
// // setOpen((prevState => ({...prevState, [id]: !prevState[id]}))
// };
// const handleClick = (item) => {
// setOpen({
// item : !open
// })
// }
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen)
}
const drawer = (
<div>
<Toolbar key={'LogoToolbar'}>
<img
as={Link}
src={AuraLogo}
style={{
maxWidth: '60%',
maxHeight: '60%',
paddingTop: '10px',
paddingBottom: '10px',
margin: '0 auto',
}}
/>
</Toolbar>
<Divider />
{menuItems.items.map(({id, icon, title, children}) => (
<>
<List
key={id+'ParentList'}
sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}
component='nav'
aria-labelledby='nested-list-subheader'
// subheader={
// <ListSubheader component='div' id='nested-list-subheader'>
// {item.subheader}
// </ListSubheader>
// }
>
<ListItemButton key={id+'listitembutton'} onClick={() => handleClick(id)}>
<ListItemIcon>{icon}</ListItemIcon>
<ListItemText primary={title} />
{open[id] ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse key={id+'collapse'} in={open[id]} timeout='auto' unmountOnExit>
<List key={id+'listchildren'} component='div' disablePadding>
{children.map(({id, icon, title, url}) => (
<ListItemButton
component={Link}
to={`${url}`}
onClick={handleDrawerToggle}
key={id+'CollapseListItem'}
sx={{ pl: 3 }}>
<ListItemIcon>{icon}</ListItemIcon>
<ListItemText primary={title} />
</ListItemButton>
))}
</List>
</Collapse>
</List>
<Divider />
</>
))}
<Link style={{textDecoration: 'none', color: '#202020'}} to='/'>
<ListItemButton key={'returnlistitembutton'}>
<ListItemIcon><ArrowBackIosNew/></ListItemIcon>
<ListItemText primary='Πίσω στους καταλόγους' />
</ListItemButton>
</Link>
</div>
)
const container =
window !== undefined ? () => window().document.body : undefined
return (
<Box sx={{ display: 'flex' }}>
<CssBaseline />
<AppBar
position='fixed'
sx={{
width: { sm: `calc(100% - ${drawerWidth}px)` },
ml: { sm: `${drawerWidth}px` },
}}>
<Toolbar>
<IconButton
color='inherit'
aria-label='open drawer'
edge='start'
onClick={handleDrawerToggle}
sx={{ mr: 2, display: { sm: 'none' } }}>
<MenuIcon />
</IconButton>
<Typography variant='h6' noWrap component='div'>
Dashboard
{/* TODO - add more functionallity to appbar */}
</Typography>
</Toolbar>
</AppBar>
<Box
component='nav'
sx={{ width: { sm: drawerWidth }, flexShrink: { sm: 0 } }}
aria-label='mailbox folders'>
{/* The implementation can be swapped with js to avoid SEO duplication of links. */}
<Drawer
key={'drawer'}
container={container}
variant='temporary'
open={mobileOpen}
onClose={handleDrawerToggle}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
sx={{
display: { xs: 'block', sm: 'none' },
'& .MuiDrawer-paper': {
boxSizing: 'border-box',
width: drawerWidth,
},
}}>
{drawer}
</Drawer>
<Drawer
variant='permanent'
sx={{
display: { xs: 'none', sm: 'block' },
'& .MuiDrawer-paper': {
boxSizing: 'border-box',
width: drawerWidth,
},
}}
open>
{drawer}
</Drawer>
</Box>
<Box
component='main'
sx={{
flexGrow: 1,
p: 3,
width: { sm: `calc(100% - ${drawerWidth}px)` },
}}>
<Toolbar />
{props.children}
</Box>
</Box>
)
}
NavBar.propTypes = {
/**
* Injected by the documentation to work in an iframe.
* You won't need it on your project.
*/
window: PropTypes.func,
}
export default NavBar
The random key properties that appear almost everywhere was my quest in finding which component generates this error but with no luck.
As always thanks in advance and if by any chance you have any suggestions or solutions... I'm all ears!
You can try something like this.
<List
sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}
component='nav'
aria-labelledby='nested-list-subheader'
>
{menuItems.items.map(({id, icon, title, children}, idx) => (
<ListItemButton
onClick={() => handleClick(id)}
key={idx}
>
<ListItemIcon>
{icon}
</ListItemIcon>
<ListItemText
primary={title}
/>
{open[id] ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open[id]} timeout='auto' unmountOnExit>
<List component='div' disablePadding>
{children.map(({id, icon, title, url}, subidx) => (
<ListItemButton
component={Link}
to={`${url}`}
onClick={handleDrawerToggle}
key={subidx}
sx={{ pl: 3 }}
>
<ListItemIcon>
{icon}
</ListItemIcon>
<ListItemText
primary={title}
/>
</ListItemButton>
))}
</List>
</Collapse>
))}
</List>
Here :
{menuItems.items.map(({id, icon, title, children}) => (
<>
<List
key={id+'ParentList'}
Your key must be provide on the first child, in your case the React Fragment so :
{menuItems.items.map(({id, icon, title, children}) => (
<Fragment key={id+'ParentList'}>
<List ...
You need to put a uniq key, the index from map can provide the same issue if you use 2 times (0, 1, 2, 3 === 0, 1, 2, 3), you can use an add string or you can use a methods to generate an uniq key :
uuid nom package
nanoid from redux-toolkit (perfect if you use Redux, don't install it just for that)
create a method from Math.random like Math.floor(Math.random()*10000000).toString(16) ( => hexa key)
create a method from a prefix you give in method params and adding an element from a new Date() or timestamp
...
With this, you sure to create a new and uniq key.
With time, in order, I prefer Nanoid or Math random.

How to change font size of material ui badge content in reactjs?

I want to change the font size of the label in material ui badge.
I am using style={{ fontSize: "15" }} but that only affect its child, which is an icon.
Code:
<Badge badgeContent={props.cartCount} color="secondary" style={{ fontSize: "15" }}>
<ShoppingCart className={classes.mediumIcon} />
</Badge>
Ideal way would be use classes badge as mentioned in documentation
import { Badge } from "#material-ui/core";
import { makeStyles } from "#material-ui/core/styles";
import "./styles.css";
const useStyles = makeStyles((theme) => ({
badge: {
fontSize: 30
}
}));
export default function App() {
const classes = useStyles();
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Badge
badgeContent={"h"}
color="secondary"
classes={{ badge: classes.badge }}
/>
</div>
);
}
If you use mui system then this can change badge font size
<Badge
badgeContent={9}
color="error"
overlap="circular"
sx={{ "& .MuiBadge-badge": { fontSize: 9, height: 15, minWidth: 15 } }}
>
<IconButton sx={{ p: 0, color: "primary.main" }}>
<Notifications />
</IconButton>
</Badge>
You can modify the font-size as below.
create styles of different font-size in useStyles
const useStyles = makeStyles((theme) => ({
font1: {
fontSize: "1rem"
},
)}
And then assign it as below to the Badge component
<Badge
classes={{
badge: classes.font1
}}
badgeContent={99}
{...defaultProps}
/>
Sandbox
You can use the componentProps attribute as follows (this example changes the color of the text in the badge but the same principle will work for fontSize).
<Badge badgeContent={comments} componentsProps={{ root: {style: {color: 'white'}} }}>
<CommentIcon />
</Badge>

How to set Material UI Fab to Outline

Is there a way to use the outline variant for the fab button in material ui
<Fab variant="here i see rounded || extended" color="primary" size="small" aria-label="scroll back to top">
<KeyboardArrowUp />
</Fab>
is there a way i could use the outline version and still inherit material ui ripple effect and other styles
As far as I know you cannot have outline version for that. But you can always write CSS for that. I had a simple demo for this
Edit: here are the code
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
"& > *": {
margin: theme.spacing(1)
}
},
fabStyle: {
backgroundColor: "white",
color: theme.palette.primary.light,
borderColor: theme.palette.primary.light,
"&:hover": {
backgroundColor: theme.palette.primary.light,
color: "white"
}
}
})
);
export default function FloatingActionButtons() {
const classes = useStyles();
return (
<div className={classes.root}>
<Fab color="primary" aria-label="add" className={classes.fabStyle}>
<AddIcon />
</Fab>
</div>
);
}
You should be able to inject classes into the Fab component. You can refer to this link for more information Customizing Components
<Fab
classes={{
root: classes.root, // class name, e.g. `classes-nesting-root-x`
label: classes.label, // class name, e.g. `classes-nesting-label-x`
}}
variant="here i see rounded || extended" color="primary" size="small" aria-label="scroll back to top">
<KeyboardArrowUp />
</Fab>

Set <Avatar> backgroundColor randomly

I have defined three backgroundColor in the style theme.
avatar: {
backgroundColor: red[500],
},
orangeAvatar: {
margin: 10,
color: '#fff',
backgroundColor: deepOrange[500],
},
purpleAvatar: {
margin: 10,
color: '#fff',
backgroundColor: deepPurple[500],
},
When ever the Avatar is loaded I would like to select one of them randomly.
<Card>
<CardHeader
avatar={
<Avatar id="av" aria-label="Recipe"
className={classes.avatar}>{this.props.userName.charAt(0).toLocaleUpperCase()}
</Avatar>}
title={this.props.userName} disableTypography={true}/>
<CardActionArea disabled={this.state.images.length == 1 ? true : false}>
<CardMedia
id={this.props.ownerId}
className={classes.media}
image={this.state.images[this.state.imageIndex]}
onClick={this.handleOnClick}
/>
</CardActionArea>
</Card>
Any advice how to do this?
Thank you
Several ways to do what you want. My suggestion: put the 3 classes in an array, pick a random number between 0 and 2 every time, and assign that class name:
<Avatar className={classes[Math.floor(Math.random() * 3)]}.../>
I was presented with the same need, perhaps this solution will also serve you, there is a function to generate the color at random and then call the function from the online style.
const useStyles = makeStyles((theme: Theme) =>
createStyles({
large: {
fontSize: "2.5rem",
width: 100,
height: 100
}
})
);
function randomColor() {
let hex = Math.floor(Math.random() * 0xFFFFFF);
let color = "#" + hex.toString(16);
return color;
}
...
return (
<Avatar
variant="square"
src={imageSrc}
alt={alt}
className={classes.large}
style={{
backgroundColor: randomColor()
}}
/>
)
ref:
Javascript random color
Avatar random backgroundColor on fallback
let classNameHolder = ["avatar","orangeAvatar","purpleAvatar"];
<Card>
<CardHeader
avatar={
<Avatar id="av" aria-label="Recipe"
className={classNameHolder[Math.floor(Math.random() * 3)]}>{this.props.userName.charAt(0).toLocaleUpperCase()}
</Avatar>}
title={this.props.userName} disableTypography={true}/>
<CardActionArea disabled={this.state.images.length == 1 ? true : false}>
<CardMedia
id={this.props.ownerId}
className={classes.media}
image={this.state.images[this.state.imageIndex]}
onClick={this.handleOnClick}
/>
</CardActionArea>
</Card>

Is there a way I can overwrite the colour the Material UI Icons npm package provides in React?

I am new to React and am using the npm package Material UI icons (https://www.npmjs.com/package/#material-ui/icons) and displaying icons within a React component as such:
Importing:
import KeyboardArrowRightIcon from 'material-ui/svg-icons/hardware/keyboard-arrow-right';
and rendering:
readMoreLink={<a href={someUrl} >Read more <KeyboardArrowRightIcon /></a>}
However, since KeyboardArrowRightIcon is an SVG provided by the npm package, it comes with it's own fill colour:
Eg: <svg viewBox="0 0 24 24" style="display: inline-block; color: rgba(0, 0, 0, 0.54);...
I know I can override this colour by having a style attribute within the element, eg:
<KeyboardArrowRightIcon style={{ fill: '#0072ea' }} />
But is there anyway to make this a SCSS variable (style={{ fill: $link-color }})?
I worry if the link colour changes in the style sheet someone will have to hunt down all these hard coded instances later.
Change Icon Color
<HomeIcon />
<HomeIcon color="primary" />
<HomeIcon color="secondary" />
<HomeIcon color="action" />
<HomeIcon color="disabled" />
<HomeIcon style={{ color: green[500] }} />
<HomeIcon style={{ color: 'red' }} />
Change Icon Size
<HomeIcon fontSize="small" />
<HomeIcon />
<HomeIcon fontSize="large" />
<HomeIcon style={{ fontSize: 40 }} />
MDI using Icon component
<Icon>add_circle</Icon>
<Icon color="primary">add_circle</Icon>
<Icon color="secondary">add_circle</Icon>
<Icon style={{ color: green[500] }}>add_circle</Icon>
<Icon fontSize="small">add_circle</Icon>
<Icon style={{ fontSize: 30 }}>add_circle</Icon>
For the Font
<Icon className="fa fa-plus-circle" />
<Icon className="fa fa-plus-circle" color="primary" />
<Icon className="fa fa-plus-circle" color="secondary" />
<Icon className="fa fa-plus-circle" style={{ color: green[500] }} />
<Icon className="fa fa-plus-circle" fontSize="small" />
<Icon className="fa fa-plus-circle" style={{ fontSize: 30 }} />
Resouces to learn more abo it, Icons
Just add a style fill: "green"
Example: <Star style={{fill: "green"}}/>
The simplest way to specify/override the color of an Icon in Material-UI is to use a custom CSS class name.
Suppose that you want to show a green checkbox rather than a red triangle, depending on the outcome of some process.
You create a function somewhere inside your code, for example like this:
function iconStyles() {
return {
successIcon: {
color: 'green',
},
errorIcon: {
color: 'red',
},
}
}
You then apply makeStyles to that function, and run the result.
import { makeStyles } from '#material-ui/core/styles';
...
const classes = makeStyles(iconStyles)();
Inside your render function, you can now use the object classes:
const chosenIcon = outcome
? <CheckCircleIcon className={classes.successIcon} />
: <ReportProblemIcon className={classes.errorIcon} />;
The function I mentioned first in this answer actually accepts a theme as input and allows you to modify/enrich that theme: this ensures that your custom classes aren't seen as exceptions, but rather as integrations inside a more comprehensive visual solution (for example, icon colors in a theme are best seen as encodings).
Material-UI is very rich and I'd encourage you to explore also other existing customisation mechanisms.
Update: 2022 July MUI5
There are multiple ways to change icon color
<HomeIcon sx={{color: "#FC0"}} />
<HomeIcon htmlColor="red" />
<HomeIcon color="primary" />
<HomeIcon color="success" />
<HomeIcon color="action" />
<HomeIcon color="disabled" />
<HomeIcon color="error" />
<HomeIcon sx={{ color: pink[500] }} />
Using sx prop you can specify any hex/rgb color code or colors from your theme palette
Example :
import { red } from '#mui/material/colors';
<HomeIcon sx={{ color: red[800] }} />
This is what I do
I use MUI v4.5.1. Use the color prop API with value inherit and add a div or span wrapper around and add your color there.
From the API docs
color default value:inherit. The color of the component. It supports those theme colors that make sense for this component.
Add star icon
import React from 'react';
import Star from '#material-ui/icons/StarRounded';
import './styles.css';
export function FavStar() {
return (
<div className="star-container">
<Star size="2em" fontSize="inherit" />
</div>
);
}
In style.css
.star-container {
color: red;
font-size: 30px;
}
You can do like this: <PlusOne htmlColor="#ffaaee" />
The simplest way I found is using the following.
import { styled } from '#material-ui/styles';
import { Visibility } from '#material-ui/icons';
const MyVisibility = styled(Visibility)({
color: 'white',
});
You can set a default color for all icons by creating a custom theme with createMuiTheme():
createMuiTheme({
props: {
MuiSvgIcon: {
htmlColor: '#aa0011',
}
}
})
This will set the default value of the htmlColor prop for every icon like <KeyboardArrowRightIcon/>. Here's a list of other props you can set.
Overwriting the material UI Icon color like below
in js
const [activeStar, setActiveStar] = useState(false);
<IconButton onClick={() => setActiveStar(!activeStar)}>
{activeStar ? (
<StarOutlined className="starBorderOutlined" />
) : (
<StarBorderOutlined />
)}
</IconButton>
in Css
.starBorderOutlined {
color: #f4b400 !important;
}
Surprised that no one has suggested a site-wide solution yet.
You can override the colors that are assigned for the "colors" option here https://material-ui.com/api/icon/#props
by adding an override to your theme (you'll have to define a custom theme if you aren't already) https://material-ui.com/customization/theming/#createmuitheme-options-args-theme
After defining a theme though, it's as simple as
const theme = createMuiTheme({
"overrides": {
MuiSvgIcon: {
colorPrimary: {
color: ["#625b5b", "!important"],
},
colorSecondary: {
color: ["#d5d7d8", "!important"],
},
},
...
});
Only correct solution that covers two tone (TwoTone) icons is to pass it htmColor property:
React.createElement(Icon, {htmlColor: "#00688b"})
To change color of your MUI Icons your have three ways: (Source)
//using a hex value
<BathroomIconOutlined style={{ color: "#ffee66" }} />
//using a standard css colour
<BathroomTwoToneIcon style={{ color: "blue" }} />
//import a material ui colour, and use that
import { purple } from "#mui/material/colors";
<BathroomIcon style={{ color: purple[500] }} />
Or use directly the MUI properties: (Source)
import SearchOutlined from '#mui/icons-material/SearchOutlined';
<SearchOutlined style={{ color: 'primary', fontSize: "small" }} />
<SearchOutlined style={{ color: 'secondary', fontSize: "medium" }} />
<SearchOutlined style={{ color: 'action', fontSize: "large" }} />
<SearchOutlined style={{ color: 'error', fontSize: 16 }} />
<SearchOutlined style={{ color: 'disabled', fontSize: 16 }} />
You can use SvgIcon, from the documentation:
The SvgIcon component takes an SVG path element as its child and
converts it to a React component that displays the path, and allows
the icon to be styled and respond to mouse events. SVG elements should
be scaled for a 24x24px viewport.
You must use the devTools to extract the path of the KeyboardArrowRightIcon icon:
Then use it with your custom color like this:
<SvgIcon
component={svgProps => {
return (
<svg {...svgProps}>
{React.cloneElement(svgProps.children[0], {
fill: myColorVariable
})}
</svg>
);
}}
>
<path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"></path>
</SvgIcon>
I had the same problem, me solution was:
import React from 'react';
import pure from 'recompose/pure';
import {SvgIcon} from '#material-ui/core';
let smile = (props) => (
<SvgIcon {...props}
component={props => {
return (
<svg {...props}>
{React.cloneElement(props.children[0], {
fill: "#4caf50"
})}
</svg>
);
}}
>
<path d="M256,32C132.281,32,32,132.281,32,256s100.281,224,224,224s224-100.281,224-224S379.719,32,256,32z M256,448
c-105.875,0-192-86.125-192-192S150.125,64,256,64s192,86.125,192,192S361.875,448,256,448z M160,192c0-26.5,14.313-48,32-48
s32,21.5,32,48c0,26.531-14.313,48-32,48S160,218.531,160,192z M288,192c0-26.5,14.313-48,32-48s32,21.5,32,48
c0,26.531-14.313,48-32,48S288,218.531,288,192z M384,288c-16.594,56.875-68.75,96-128,96c-59.266,0-111.406-39.125-128-96"></path>
</SvgIcon>
);
smile = pure(smile);
smile.displayName = 'smile';
smile.muiName = 'SvgIcon';
export default smile;
Solution that works the best for myself:
const EditableIcon = ({ icon, color, sx }: PropsWithChildren<EditableIconProps>) => {
const c = useIconStyles()
return React.cloneElement(icon, {
...(color && { color }),
...(sx && { sx }),
classes: {
colorPrimary: c.colorPrimary,
colorSecondary: c.colorSecondary,
colorAction: c.colorAction
}
})
}
If color is set, your classes would override default values.

Resources