MUI two tooltips on one component - reactjs

I want to display two tooltips on a button. However, I can't find any way to do it without errors in the console.
My goal:
Minimal reproducible example
import * as React from 'react';
import { Tooltip, Button, Box } from '#mui/material';
export default function BasicTooltip() {
return (
<Box sx={{ margin: 10 }}>
<Tooltip title="Tooltip on top" placement="top">
<Tooltip title="Tooltip on button" placement="bottom">
<Button>Hello</Button>
</Tooltip>
</Tooltip>
</Box>
);
}
Error I'm getting in the console with this code:
MUI: You have provided a title prop to the child of Tooltip.
Remove this title prop Tooltip on button or the Tooltip component.
Link to stackblitz: https://stackblitz.com/edit/react-qgtibd?file=demo.js
I already tried to isolate the inner tooltip with button in another component like this, but it did not work:
import * as React from 'react';
import { Tooltip, Button, Box } from '#mui/material';
const MyButton = React.forwardRef(({ tooltipText }, ref) => (
<Tooltip title={tooltipText} placement="bottom">
<Button ref={ref}>Hello</Button>
</Tooltip>
));
export default function BasicTooltip() {
return (
<Box sx={{ margin: 10 }}>
<Tooltip title="Tooltip on top" placement="top">
<MyButton tooltipText="Tooltip on bottom" />
</Tooltip>
</Box>
);
}
edit: I also can't put a div nor React.fragment between those tooltips, because it completely screws up the layout in my real case scenario.

Looks like you need to isolate the tooltips from one another
<Box sx={{ margin: 10 }}>
<Tooltip title="Tooltip on top" placement="top">
<Box>
<Tooltip title="Tooltip on button" placement="bottom">
<Button>Hello</Button>
</Tooltip>
</Box>
</Tooltip>
</Box>
modified stackblitz with the aligment

Related

Material Ui CardMedia Component is not loading my picture

I am trying to load a picture using Material UI card component. Everything seems to load except for the actual picture. I have tried all possible ways and other suggestions from the net but no luck.
Here is my code.
I've tried the imageURL, path i even copied the path exactly from the folder structure to see if i wrote it wrong.
import Card from '#mui/material/Card';
import CardMedia from '#mui/material/CardMedia';
import { Button, CardActionArea, CardActions } from '#mui/material';
function DisplayProjectCard(props) {
return (
<Card elevation={0}
sx={{ maxWidth: 645,
backgroundColor: "transparent", p:4 }}>
<CardActionArea>
<CardMedia
component="img"
title="My Next Promo App landing page"
height="240"
width="440"
image="src/static/images/MyNextPromoApp.png"
alt="Home page of My Next Promo App"
/>
</CardActionArea>
<CardActions sx={{
justifyContent:'center'
}}>
<Button size="small" color="primary">
View
</Button> |
<Button size="small" color="primary">
Github
</Button>
</CardActions>
</Card>
);
}
export default DisplayProjectCard```

IconButton Hovering Effect on Material UI

below i have different icons from material UI , which currently displays a grey circle whenever i hover on any of them , i want to remove this grey circle and i want each icon to change to a specific color whenever i hover over it i looked at the documentation in material ui but couldn't find anything that explains it , appreciate your feedback.
<Box className={classes.socialmedia}>
<IconButton aria-label="twitter">
<TwitterIcon />
</IconButton>
<IconButton aria-label="facebook">
<FacebookIcon />
</IconButton>
<IconButton aria-label="instagram">
<InstagramIcon />
</IconButton>
<IconButton aria-label="Youtube">
<YouTubeIcon />
</IconButton>
<IconButton aria-label="Apple">
<AppleIcon />
</IconButton>
</Box>
In order to remove the grey circle displaying in background on hover then you can use disableFocusRipple & disableRipple property in IconButton component and set style={{ backgroundColor: 'transparent' }}.
Ex:
<IconButton
disableFocusRipple
disableRipple
style={{ backgroundColor: "transparent" }}
aria-label="twitter"
>
<TwitterIcon className={classes.twitter} />
</IconButton>
To change the color of icon on hover then use hover selector.
Ex:
const useStyles = makeStyles({
twitter: {
"&:hover": {
color: "#00acee"
}
}
});
I've created a quick example to illustrate the solution in codesandbox:
https://codesandbox.io/s/elegant-ramanujan-wnj9fw?file=/index.js:948-961
Define a hook. Import makeStyle from '#material-ui/core/styles'.
const useStyles = makeStyle(() => ({
styleRed: {
'&:hover': {
backgroundColor: '#f00'
}
},
styleBlue: {
'&:hover': {
backgroundColor: '#00f'
}
}
}));
Then in your component:
// using our hook
const {styleRed, styleBlue} = useStyles();
// some more code
return (
<>
<IconButton aria-label="twitter" classes={styleRed}>
<TwitterIcon />
</IconButton>
<IconButton aria-label="facebook" classes={styleBlue}>
<FacebookIcon />
</IconButton>
</>
)

Material-UI Divider doesn't show and prevents other elements from showing?

I'm trying to use the MUI divider in React. However, it doesn't seem to work; I currently have:
import * as React from "react";
import IconButton from "#mui/material/IconButton";
import ShareIcon from "#mui/icons-material/Share";
import ReportGmailerrorredIcon from "#mui/icons-material/ReportGmailerrorred";
import Divider from "#mui/material/Divider";
import "./settings.css";
function Settings() {
return (
<div className="body">
<div className="media_interact">
<div className="media_buttons">
<IconButton size="medium" sx={{ ml: 2 }}>
<ShareIcon fontSize="large" />
</IconButton>
<IconButton size="medium" sx={{ ml: 2 }}>
<ReportGmailerrorredIcon fontSize="large" />
</IconButton>
</div>
<Divider
orientation="vertical"
variant="middle"
flexItem
sx={{ color: "black" }}
/>
Hello
</div>
</div>
);
}
export default Settings;
which, as you can see from the Sandbox, doesn't produce the Divider at all and the Hello text element after:
I'm hoping for some guidance in terms of how to use it?

Material-UI center button text ignoring icons

I would like to center text in a Material-UI button so that the text is centered irrespective of the icon next to it. At the moment the icon is included in the centering.
The top two buttons in the demo show how it currently looks, I am looking for the text to appear as it does in the bottom two buttons. With the icons before and after these buttons respectively, without influencing the text of the buttons.
Bottom two are desired output
https://codesandbox.io/s/material-demo-forked-tj8ko?file=/demo.js
import React from "react";
import Button from "#material-ui/core/Button";
import { makeStyles } from "#material-ui/core/styles";
import KeyboardArrowRightIcon from "#material-ui/icons/KeyboardArrowRight";
import KeyboardArrowLeftIcon from "#material-ui/icons/KeyboardArrowLeft";
const useStyles = makeStyles((theme) => ({
button: {
width: "100%",
marginBottom: theme.spacing(1),
marginTop: theme.spacing(1)
}
}));
export default function IconLabelButtons() {
const classes = useStyles();
return (
<div>
<Button
variant="contained"
color="secondary"
className={classes.button}
startIcon={<KeyboardArrowLeftIcon />}
>
Back
</Button>
{/* This Button uses a Font Icon, see the installation instructions in the Icon component docs. */}
<Button
variant="contained"
color="primary"
className={classes.button}
endIcon={<KeyboardArrowRightIcon />}
>
Forward
</Button>
<Button variant="contained" color="secondary" className={classes.button}>
Back
</Button>
{/* This Button uses a Font Icon, see the installation instructions in the Icon component docs. */}
<Button variant="contained" color="primary" className={classes.button}>
Forward
</Button>
</div>
);
}
It's possible to move the icons into the inner html of the button and tweak the margins respectively. It's kind of hacky but solves your problem. I forked your demo with the updates: https://codesandbox.io/s/material-demo-forked-xmltd?file=/demo.js
<Button variant="contained" color="secondary" className={classes.button}>
<KeyboardArrowLeftIcon style={{ marginLeft: -28 }} />
Back
</Button>
<Button variant="contained" color="primary" className={classes.button}>
Forward
<KeyboardArrowRightIcon style={{ marginRight: -28 }} />
</Button>
You can get the same effect while still using startIcon and endIcon by customizing the styles for the start/end icons using withStyles and then using the resulting customized component:
const CenteredTextButton = withStyles({
startIcon: {
marginLeft: -28
},
endIcon: {
marginRight: -28
}
})(Button);

Show Dialog on MenuItem click

Is there a way to have a Dialog component pop up when you click on a MenuItem in a Material-UI Menu? I have a header component that returns the below JSX:
return (
<AppBar
iconElementLeft={<a href='/'><Avatar src="/static/images/favicon.ico" style={{ marginTop:4 }} /></a>}
title= {
<div>
{"Application"}
{displaySearch?<div style={{display:'inline-block', marginLeft:20, width:500}}><Search location={location}/></div>:null}
<div style={{float:'right'}}>
{logoUri ? <img src={logoUri} style={{ height:40, verticalAlign:'middle',borderRadius:3,overflow:'hidden'}} /> : null}
</div>
</div>
}
iconElementRight={
<IconMenu
iconButtonElement={
<IconButton><MoreVertIcon /></IconButton>
}
targetOrigin={{ horizontal: 'right', vertical: 'top' }}
anchorOrigin={{ horizontal: 'right', vertical: 'top' }}
>
{
menuItems.map(
menuItem => <MenuItem containerElement={<Link to={menuItem.uri} />} primaryText={menuItem.primaryText} key={menuItem.key} />)
}
<MenuItem href='#' primaryText={'about'} onTouchTap={()=>{}} />
<MenuItem href='/auth/logout' primaryText={'logout'} />
</IconMenu>
}
<Dialog ref="dialog" title="version 1.0" open={true}>
Version: {version}
</Dialog>
/>
)
I'm just trying to wire up the 'about' menu item to the dialog that pops up and displays the version information that I pass along to the page, but once I include the Dialog in the IconMenu, if you click on the IconMenu, nothing shows and I get an error:
"Menu.js:222 Uncaught TypeError: Cannot set property 'opacity' of undefined".
If I remove the Dialog component, my MenuItem works as intended. I'm not sure how exactly I can wire up a MenuItem to a Dialog. Is it possible to have a MenuItem trigger a Dialog component in Material-UI?
You could create the dialog as a menu item:
import MenuDialog from './MenuDialog';
Then
<IconMenu
...
<MenuDialog />
...
</IconMenu>
And now in a seperate MenuDialog.js file, as a component which is imported above
render(){
const actions = [<FlatButton
label="Close"
primary={true}
onClick={this.handleClose} />
]
return(
<div>
<MenuItem onClick={this.handleOpen}>Press for dialog </MenuItem>
<Dialog
title={Dialog name}
actions={actions}
modal={false}
open={this.state.open}
onRequestClose={this.handleClose}> Dialog writing
</Dialog>
</div>
)
}

Resources