How do I get the Backdrop to cover the button?
No matter what I do, the buttons appear as if they were above the backdrop, I can't them move them behind it.
See code:
import React from "react";
import { Backdrop, Button } from "#material-ui/core";
import CircularProgress from "#material-ui/core/CircularProgress";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles({});
export default function App() {
const classes = useStyles();
const [test, setTest] = React.useState(true);
return (
<div className={classes.parent}>
<Backdrop className={classes.backdrop} open={test}>
<CircularProgress color="inherit" />
</Backdrop>
<Button
variant="contained"
color="secondary"
onClick={() => {
setTest(test ? false : true);
}}
>
I should be behind the backdrop (click me)
</Button>
</div>
);
}
You need to give the backdrop a higher z-index
const useStyles = makeStyles((theme) => ({ backdrop: { zIndex: theme.zIndex.drawer + 1, color: '#fff', }, }));
This should fix it, just check the docs.
Related
I am attempting to create a floating "emergency exit" button for my React typescript application which will immediately take the user to weather.com. I'm having no trouble creating the button, but the requirements call for a tooltip when hovering over the button. Since we use chakra-ui throughout the product, using the Tooltip component they provide seems natural to me.
My first attempt looks like this:
Button.tsx
import React from "react";
import { Button as ChakraButton, ButtonProps } from "#chakra-ui/react";
interface Props extends ButtonProps {
buttonColor: string;
}
const Button: React.FC<Props> = ({
buttonColor,
children,
...restProps
}: Props) => (
<ChakraButton
backgroundColor={buttonColor}
color="white"
_hover={{
background: buttonColor
}}
_active={{
background: buttonColor
}}
padding="15px 30px"
height="auto"
fontSize="sm"
minWidth="200px"
borderRadius="100px"
fontFamily="AvenirBold"
{...restProps}
>
{children}
</ChakraButton>
);
export default Button;
EmergencyExitButton.tsx
import styled from "#emotion/styled";
import React from "react";
import Button from "./Button";
import { Tooltip } from "#chakra-ui/react";
const StyledButton = styled(Button)`
z-index: 99999;
position: fixed;
margin-left: calc(50% - 100px);
margin-top: 5px;
`;
export const EmergencyExitButton: React.FC = ({ children }) => {
const handleClick = () => {
window.open("https://weather.com", "_self");
};
return (
<>
<Tooltip
width="100%"
label="Immediately exit to the Weather Channel. Unsaved changes will be lost."
placement="bottom"
bg="black"
color="white"
>
<StyledButton buttonColor="#CC0000" onClick={handleClick}>
Emergency Exit
</StyledButton>
</Tooltip>
{children}
</>
);
};
When I insert this button into the application and hover over it, the tooltip appears in the top left corner of the screen and doesn't go away when you move the pointer away from the button. (codesandbox: https://codesandbox.io/s/objective-rain-z5szs7)
After consulting the chakra-ui documentation on Tooltip, I realized that I should be using a forwardRef for the wrapped component, so I modified EmergencyExitButton to look like this:
import * as React from "react";
import Button from "./Button";
import { Tooltip } from "#chakra-ui/react";
const EmergencyButton = React.forwardRef<HTMLDivElement>((props, ref) => {
const handleClick = () => {
window.open("https://weather.com", "_self");
};
return (
<div
ref={ref}
style={{
zIndex: 99999,
position: "fixed",
marginLeft: "calc(75% - 100px)",
marginTop: "5px"
}}
>
<Button buttonColor="#CC0000" onClick={handleClick}>
EmergencyExit
</Button>
</div>
);
});
EmergencyButton.displayName = "EmergencyButton";
export const EmergencyExitButton: React.FC = ({ children }) => (
<>
<Tooltip
width="100%"
label="Immediately exit to the Weather Channel. Unsaved changes will be lost."
placement="bottom"
bg="black"
color="white"
hasArrow
style={{ zIndex: 99999 }}
>
<EmergencyButton />
</Tooltip>
{children}
</>
);
In this iteration, the tooltip doesn't appear at all. (codesandbox: https://codesandbox.io/s/kind-voice-i230ku)
I would really appreciate any advice or ideas on how to make this work.
Edited to fix the code a little.
I figured it out. It turns out that instead of creating a forwardRef, I just needed to wrap the button in a span tag.
import React from 'react';
import Button from './Button';
import { Tooltip } from '#chakra-ui/react';
export const EmergencyExitButton: React.FC = ({ children }) => {
const handleClick = () => {
window.open('https://weather.com', '_self');
};
return (
<>
<Tooltip
width='100%'
label='Immediately exit to the Weather Channel. Unsaved changes will be lost.'
placement='bottom'
bg='black'
color='white'
>
<span style={{ zIndex: 99999, position: 'fixed', marginLeft: 'calc(50% - 100px)', marginTop: '5px'}}>
<Button buttonColor='#CC0000' onClick={handleClick}>Emergency Exit</Button>
</span>
</Tooltip>
{children}
</>
);
};
I think the prop shouldWrapChildren could be used in this case.
See https://chakra-ui.com/docs/components/tooltip/props
I'm learning how to use Material-ui for ReactJS, I don't understand what is the "TransitionProps" in this example code below:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Popper from '#material-ui/core/Popper';
import Fade from '#material-ui/core/Fade';
const useStyles = makeStyles((theme) => ({
paper: {
border: '1px solid',
padding: theme.spacing(1),
backgroundColor: theme.palette.background.paper,
},
}));
export default function TransitionsPopper() {
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = (event) => {
setAnchorEl(anchorEl ? null : event.currentTarget);
};
const open = Boolean(anchorEl);
const id = open ? 'transitions-popper' : undefined;
return (
<div>
<button aria-describedby={id} type="button" onClick={handleClick}>
Toggle Popper
</button>
<Popper id={id} open={open} anchorEl={anchorEl} transition>
{({ TransitionProps }) => (
<Fade {...TransitionProps} timeout={350}>
<div className={classes.paper}>The content of the Popper.</div>
</Fade>
)}
</Popper>
</div>
);
}
What will be passed into "TransitionProps"?
Here is the source code on Codesandbox
Hoping someone will explain some more on this syntax.
Thanks.
I've edited my original post, so far I'm able to refactor away from hooks with this implementation, now, the behavior for moving the mouse cursor away does not close the popover. This is what I have so far:
import React, { Fragment, useState } from 'react';
import propTypes from '../../propTypes';
import { Grid, Typography, Box, Popover } from '#material-ui/core';
import { makeStyles, styled } from '#material-ui/core/styles';
import InfoIcon from '#material-ui/icons/InfoOutlined';
import { fade } from '#material-ui/core/styles/colorManipulator';
export const InfoIconWrapper = styled(InfoIcon)(({ theme }) => ({
color: fade(theme.palette.black, 0.3),
}));
export const GridWrapper = styled(Grid)(({theme}) => ({
pointerEvents: 'none',
padding: theme.spacing(1),
}));
const DistributionLinePopover = ({ distributionLine }) => {
const [anchorEl, setAnchorEl] = useState(null);
const handlePopoverOpen = event => {
setAnchorEl(event.currentTarget);
console.log("open")
};
const handlePopoverClose = () => {
setAnchorEl(null);
console.log("close")
};
const open = Boolean(anchorEl);
return (
<Fragment>
<Typography
aria-owns={open ? 'mouse-over-popover' : undefined}
aria-haspopup="true"
onMouseEnter={handlePopoverOpen}
>
<InfoIconWrapper fontSize="small" />
</Typography>
<Popover
id="mouse-over-popover"
open={open}
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
onClose={handlePopoverClose}
// onMouseLeave={handlePopoverClose}
disableRestoreFocus
>
<GridWrapper container>
What can I do to have the popover close when the user moves their mouse away from it? onExit, onExited, onExiting does not produce the desired behavior.
You need to use import { withStyles } from '#material-ui/core/styles'
Then, your styles are defined as such:
const styles = theme => ({
...
});
Your className attributes will be className={classes.popover} (or whichever you're using). Note, classes is passed into your component, so you would obtain it from the signature, i.e. function Component({classes}) { ... }
Finally, you export your class as such:
export default withStyles(styles)(Component)
Ok, the solution to the updated post is to replace onClose with onMouseOut.
I'm struggling to effect an on-hover dotted underline on a Material-UI <Link> component. The following code doesn't seem to have any effect:
const useStyles = makeStyles(theme => ({
link: {
'&hover': {
textDecoration: 'dotted'
},
},
}));
export default function Links() {
const classes = useStyles();
return (
<Typography>
<Link
underline={'hover'}
href="/"
className={classes.link}
>
Some anchor text
</Link>
</Typography>
);
}
Any alternative?
This works for me..
There were two things I had to change:
You have to change &hover to &:hover
You have to use textDecorationStyle: 'dotted', instead of textDecoration: 'dotted'
Live Demo
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import { Typography, Link } from '#material-ui/core';
const useStyles = makeStyles(theme => ({
link: {
'&:hover': {
textDecorationStyle: 'dotted'
}
},
}));
export default function Links() {
const classes = useStyles();
return (
<Typography>
<Link
underline="hover"
href="/"
className={classes.link}
>
Some anchor text
</Link>
</Typography>
);
}
I'm trying to invoke the function ButtonAppBar inside my stateless component but the TS compiler gives me this error: '{' expected. I'm not sure whether I should be passing it to my New Header component or whether I should give it a type.
Here's my component
import * as React from "react";
import { withStyles, createStyles } from "#material-ui/core/styles";
import AppBar from "#material-ui/core/AppBar";
import Toolbar from "#material-ui/core/Toolbar";
import Typography from "#material-ui/core/Typography";
import Button from "#material-ui/core/Button";
import IconButton from "#material-ui/core/IconButton";
import MenuIcon from "#material-ui/icons/Menu";
const styles: any = createStyles({
root: {
flexGrow: 1
},
header: {
backgroundColor: "#007"
},
grow: {
flexGrow: 1
},
menuButton: {
marginLeft: -12,
marginRight: 20
}
});
const ButtonAppBar = (styles) => {
const classes = styles;
return (
<div className={classes.root}>
<AppBar position="static" className={classes.header}>
<Toolbar>
<IconButton
className={classes.menuButton}
color="inherit"
aria-label="Menu"
>
<MenuIcon />
</IconButton>
<Button color="inherit">Home</Button>
<Button color="inherit">Help</Button>
</Toolbar>
</AppBar>
</div>
);
}
const NewHeader: React.StatelessComponent<props> = ({}) => {
return (
{ButtonAppBar()}
);
}
export default withStyles(styles, NewHeader);
Your code is not parsed properly.
const NewHeader: React.StatelessComponent<props> = ({}) => ButtonAppBar();
either:
const NewHeader: React.StatelessComponent<props> = ({}) => {
return ButtonAppBar();
}