How to position MUI badge in IconButton border in ReactJS? - reactjs

I have made a Bluetooth connection status indicator using a tooltip and a badge. However I'm struggling with the badge's positioning.
Here's my code:
<Tooltip className={classes.help} title={getBluetoothStatus()}>
<IconButton onClick={props.onClick} size="large">
<Badge badgeContent="✔" color="success" overlap="circular">
<BluetoothIcon />
</Badge>
</IconButton>
</Tooltip>
Which looks like this:
However, I want the badge to be positioned on the edge of the circular IconButton.
I've tried placing the Badge around the IconButton like so:
<Tooltip className={classes.help} title={getBluetoothStatus()}>
<Badge badgeContent="✔" color="primary" overlap="circular">
<IconButton onClick={props.onClick} size="large">
<BluetoothIcon />
</IconButton>
</Badge>
</Tooltip>
This does place the Badge more outwards and fixes the issue. Unfortunately it add an unwanted square:
I've tried adding css properties such as padding, margin and transform:translate to no avail :(
Any thoughts or suggestions are highly appreciated, thanks!

Managed to get it looking like intended:
Had to separate Badge component from the Icon component and then I just styled the badge with transform: 'translate(30px, -20px)'
Here's the code I used in case anyone needs it:
<Tooltip className={classes.help} title={getBluetoothStatus()}>
<IconButton onClick={props.onClick} size="large" >
<Badge badgeContent="✔" color="success" overlap="circular" style={{ transform: 'translate(30px, -20px)'}}>
</Badge>
<BluetoothIcon />
</IconButton>
</Tooltip>
Let me know if you find a better way.

Related

How to remove MUI 5 Card Action Area Default Hover State

This question has probably been answered but i cant seem to find a solution.
I want to remove the default hover state on the CardActionArea component from mui 5. When i hover over the action area, there is a light grey background that i want to remove. Any help is much appreciated.
<Grid container spacing={2}>
{todos.map((todo) => (
<Grid key={todo.db_id} item xs={12} md={4}>
<Card variant='outlined' sx={{ minWidth: 200 }}>
<CardActionArea onClick={() => handleRedirect(todo.db_id)}>
<CardContent>
<Typography variant='h4' color='text.secondary' gutterBottom>
{todo.title}
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Button
onClick={() => deleteHandler(todo.db_id)}
variant='contained'
size='small'
>
Delete
</Button>
</CardActions>
</Card>
</Grid>
))}
</Grid>
I'm using the styled-components engine for MUI 5, so my answer will be based on that, but I was able to remove the grey hover by accessing the .MuiCardActionArea-focusHighlight, as described on this page:
https://mui.com/material-ui/api/card-action-area/
I was able to remove it with the following code:
const StyledCardActionArea = styled(CardActionArea)(({theme}) => `
.MuiCardActionArea-focusHighlight {
background: transparent;
}
`);
Then just put that component in place of CardActionArea within your code.

Unable to show icon when i hover using reactjs

I'm new to the framework. My objective is to show the icon when i hover on the tab, But i couldn't able to perform hover.
I've tried by giving css as display: none and hover too, but didn't worked.
Can anyone help me in solving this issue?
Here is the code:
showIcon: {
// display: "none",
"&.hover": {
display: "visible"
}
}
<Card>
<CardHeader
className={classes.header}
avatar={<Avatar aria-label="recipe">R</Avatar>}
action={
<div>
<IconButton
className={classes.showIcon}
aria-label="settings"
aria-controls="simple-menu"
onClick={this.handleClick}
>
<MoreVertIcon />
</IconButton>
<Menu id="simple-menu" keepMounted anchorEl={this.state.menu}>
<MenuItem>Profile</MenuItem>
<MenuItem>change password</MenuItem>
<MenuItem>Logout</MenuItem>
</Menu>
</div>
}
title="Shrimp and Chorizo Paella"
subheader="September 14, 2016"
/>
</Card>
Here is the sample code
I forked your code and fixed it for you;
What was wrong? All css pseudo classes need to have a : delimiter, not a .. Additionally, the hover was on the wrong element

Both right and left aligned icons in AppBar with material-ui next

If I have an AppBar, how can I make it so one group of icons plus the logo is on the left, and another group of icons are on the right of it?
Ex:
Left: (from left to right) 1 menu icon, logo
Right: (from right to left) 1 menu icon, 1 save icon, 1 edit icon
AppBar component:
<AppBar
className={classNames(classes.appBar, {
[classes.appBarShift]: open,
[classes[`appBarShift-left`]]: open,
[classes[`appBarShift-right`]]: !tools,
})}
position='static'
>
<Toolbar className={classNames(classes.topBar)}>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={this.handleDrawerToggle}
className={classNames(classes.menuButton)}
>
<MenuIcon />
</IconButton>
<Typography variant="title" color="inherit" noWrap>React App</Typography>
<IconButton
color="inherit"
aria-label="open tool drawer"
onClick={this.handleToolDrawerToggle}
className={classNames(classes.menuButton)}
>
<MenuIcon />
</IconButton>
</Toolbar>
</AppBar>
You can use flexbox to control the alignment of elements in the toolbar...
One option is to add flex: 1 to the logo element. It will expand to fill the available space in container. All the elements after logo will be aligned to the right.
OR
Use margin-left: auto to align the second group of buttons to the right side of the flex container.
Here is a live example
const styles = {
// this group of buttons will be aligned to the right side
toolbarButtons: {
marginLeft: 'auto',
},
};
const Demo = ({ classes }) => (
<AppBar position="static">
<Toolbar>
<IconButton color="inherit">
<MenuIcon />
</IconButton>
<Typography variant="title" color="inherit">Title</Typography>
<div className={classes.toolbarButtons}>
<IconButton color="inherit"><EditIcon /></IconButton>
<IconButton color="inherit"><SaveIcon /></IconButton>
<IconButton color="inherit"><MoreVertIcon /></IconButton>
</div>
</Toolbar>
</AppBar>
);
I know it's been a while since you asked the question, I would like to provide an alternative solution. Add Box tag (similar to flexbox in CSS) around the components on the left and adjust the flexGrow attribute and it works for me:
import Box from '#material-ui/core/Box';
{/* BEFORE APPBAR*/}
<AppBar>
<Toolbar>
<Box display='flex' flexGrow={1}>
{/* whatever is on the left side */}
</Box>
{/* whatever is on the right side */}
</Toolbar>
</AppBar>
{/* AFTER APPBAR*/}
I tried using inline css inside Toolbar component itself, it worked for me;
<Toolbar style={{display:'flex', justifyContent:"space-between", width:'100%'}}>

Why 1st menu item selected by default at MenuAppBar

In this menuAppBar the first item in the menu is selected by default. Where in this menu the first item is not selected by default, and that what I want is the same to be in the manuAppBar menu.
The first example is implemented with the material-ui Menu component and the second example is implemented using components from the react-popper library.
In the first example, the first item is highlighted because it has focus. This is because Menu sets focus if it is open when mounted or updated. Take a look at the source:
class Menu extends React.Component {
componentDidMount() {
if (this.props.open) {
this.focus();
}
}
componentDidUpdate(prevProps) {
if (!prevProps.open && this.props.open) {
// Needs to refocus as when a menu is rendered into another Modal,
// the first modal might change the focus to prevent any leak.
this.focus();
}
}
If you prefer react-popper and would like to use it in an AppBar, you can:
<AppBar position="static">
<Toolbar>
<IconButton className={classes.menuButton} color="contrast" aria-label="Menu">
<MenuIcon />
</IconButton>
<Typography type="title" color="inherit" className={classes.flex}>
Title
</Typography>
{auth && (
<Manager>
<Target>
<IconButton
aria-owns={open ? 'menu-list' : null}
aria-haspopup="true"
onClick={this.handleMenu}
color="contrast"
>
<AccountCircle />
</IconButton>
</Target>
<Popper
placement="top-right"
eventsEnabled={open}
className={classNames({ [classes.popperClose]: !open })}
>
<ClickAwayListener onClickAway={this.handleClose}>
<Grow in={open} id="menu-list" style={{ transformOrigin: '0 0 0' }}>
<Paper>
<MenuList role="menu">
<MenuItem onClick={this.handleClose}>Profile</MenuItem>
<MenuItem onClick={this.handleClose}>My account</MenuItem>
<MenuItem onClick={this.handleClose}>Logout</MenuItem>
</MenuList>
</Paper>
</Grow>
</ClickAwayListener>
</Popper>
</Manager>
)}
</Toolbar>
</AppBar>
Here is a mashup of your two cited examples on codesandbox. It needs work and was only added here to illustrate react-popper as a possibility.

Material-UI/React: How to correctly add notification button with Badge to AppBar?

Using material-ui and react/jsx, I have an AppBar. I wanted to add a notifications menu icon with badge (number) on it, that is, to show the number of new notifications.
The problem is that the badge will be displayed incorrectly. That is, with weird styles and look.
Here is what I have already tried
<AppBar>
<IconMenu anchorOrigin={{ horizontal: 'right', vertical: 'top' }}
targetOrigin={{ horizontal: 'right', vertical: 'bottom' }}
iconButtonElement={
<FlatButton label={<Badge badgeContent={5} />} icon={<NotificationsIcon />} />
}
/>
</AppBar>
That way, the badge will not be aligned correctly with the bell (notifications) icon.
I have also tried making the IconMenu part of the AppBar's iconElementRight property to no avail.
Any help?
You're right - it does seem to take some experimenting with the proper nesting order, and even then you have to tweak the style a bit. But, here's a sample webpackbin that I think looks decent without being hacky: http://www.webpackbin.com/EJqz0NVzM
<AppBar>
<IconMenu
iconButtonElement={
<IconButton style={{ padding: 0 }}>
<Badge
badgeStyle={{ top: 12, right: 12, backgroundColor: colors.yellow800 }}
badgeContent={5}
secondary={true}
>
<NotificationIcon color={muiTheme.appBar.textColor} />
</Badge>
</IconButton>
}
>
<MenuItem primaryText="View Notifications" />
<MenuItem primaryText="Dismiss All" />
</IconMenu>
</AppBar>
Once you nest the components correctly, the final bit is setting the padding on the IconButton to zero. Once you do this, it will look as expected according to the material-ui docs.
In this configuration, in my humble opinion, the badge is floating a little too far away from the notification icon. So, I also added a custom "badgeStyle" to nudge the badge inward to overlay on top of the notification icon slightly. I also put a custom yellow color on the badge too, just to illustrate that you can further customize the look of that badge (could change borderRadius, boxShadow, fontSize, etc)

Resources