Material-UI自定义Snackbar的TransitionComponent如何改成Slide
Material-UI How to change TransitionComponent of Customized Snackbar to Slide
我想将 snackbar 的过渡更改为 Slide Up 而不是 Grow(默认行为),但我发现在 Customized snackbar 上很难这样做:
import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import Button from '@material-ui/core/Button';
import CheckCircleIcon from '@material-ui/icons/CheckCircle';
import ErrorIcon from '@material-ui/icons/Error';
import InfoIcon from '@material-ui/icons/Info';
import CloseIcon from '@material-ui/icons/Close';
import green from '@material-ui/core/colors/green';
import amber from '@material-ui/core/colors/amber';
import IconButton from '@material-ui/core/IconButton';
import Snackbar from '@material-ui/core/Snackbar';
import SnackbarContent from '@material-ui/core/SnackbarContent';
import WarningIcon from '@material-ui/icons/Warning';
import { makeStyles } from '@material-ui/core/styles';
const variantIcon = {
success: CheckCircleIcon,
warning: WarningIcon,
error: ErrorIcon,
info: InfoIcon,
};
const useStyles1 = makeStyles(theme => ({
success: {
backgroundColor: green[600],
},
error: {
backgroundColor: theme.palette.error.dark,
},
info: {
backgroundColor: theme.palette.primary.dark,
},
warning: {
backgroundColor: amber[700],
},
icon: {
fontSize: 20,
},
iconVariant: {
opacity: 0.9,
marginRight: theme.spacing(1),
},
message: {
display: 'flex',
alignItems: 'center',
},
}));
function MySnackbarContentWrapper(props) {
const classes = useStyles1();
const { className, message, onClose, variant, ...other } = props;
const Icon = variantIcon[variant];
return (
<SnackbarContent
className={clsx(classes[variant], className)}
aria-describedby="client-snackbar"
message={
<span id="client-snackbar" className={classes.message}>
<Icon className={clsx(classes.icon, classes.iconVariant)} />
{message}
</span>
}
action={[
<IconButton key="close" aria-label="Close" color="inherit" onClick={onClose}>
<CloseIcon className={classes.icon} />
</IconButton>,
]}
{...other}
/>
);
}
MySnackbarContentWrapper.propTypes = {
className: PropTypes.string,
message: PropTypes.node,
onClose: PropTypes.func,
variant: PropTypes.oneOf(['success', 'warning', 'error', 'info']).isRequired,
};
const useStyles2 = makeStyles(theme => ({
margin: {
margin: theme.spacing(1),
},
}));
function CustomizedSnackbars() {
const classes = useStyles2();
const [open, setOpen] = React.useState(false);
function handleClick() {
setOpen(true);
}
function handleClose(event, reason) {
if (reason === 'clickaway') {
return;
}
setOpen(false);
}
return (
<div>
<Button variant="outlined" className={classes.margin} onClick={handleClick}>
Open success snackbar
</Button>
<Snackbar
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
open={open}
autoHideDuration={6000}
onClose={handleClose}
>
<MySnackbarContentWrapper
onClose={handleClose}
variant="success"
message="This is a success message!"
/>
</Snackbar>
<MySnackbarContentWrapper
variant="error"
className={classes.margin}
message="This is an error message!"
/>
<MySnackbarContentWrapper
variant="warning"
className={classes.margin}
message="This is a warning message!"
/>
<MySnackbarContentWrapper
variant="info"
className={classes.margin}
message="This is an information message!"
/>
<MySnackbarContentWrapper
variant="success"
className={classes.margin}
message="This is a success message!"
/>
</div>
);
}
export default CustomizedSnackbars;
这是我到目前为止所做的:
https://codesandbox.io/s/material-demo-2dvos
错误信息是我目前得到的信息。
请帮忙,我将不胜感激。
问题在于您使用 Slide
组件的方式。
https://material-ui.com/api/slide/
children element A single child content element.
⚠️ Needs to be able to hold a ref.
Slide 元素的子元素是您的 MySnackbarContentWrapper
组件,它不接受或持有引用。更新它以保存一个 ref 并且它按预期工作:
const MySnackbarContentWrapper = React.forwardRef((props, ref) => {
const classes = useStyles1();
const { className, message, onClose, variant, ...other } = props;
const Icon = variantIcon[variant];
return (
<SnackbarContent
ref={ref}
className={clsx(classes[variant], className)}
aria-describedby="client-snackbar"
message={
<span id="client-snackbar" className={classes.message}>
<Icon className={clsx(classes.icon, classes.iconVariant)} />
{message}
</span>
}
action={[
<IconButton
key="close"
aria-label="Close"
color="inherit"
onClick={onClose}
>
<CloseIcon className={classes.icon} />
</IconButton>
]}
{...other}
/>
);
})
我想将 snackbar 的过渡更改为 Slide Up 而不是 Grow(默认行为),但我发现在 Customized snackbar 上很难这样做:
import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import Button from '@material-ui/core/Button';
import CheckCircleIcon from '@material-ui/icons/CheckCircle';
import ErrorIcon from '@material-ui/icons/Error';
import InfoIcon from '@material-ui/icons/Info';
import CloseIcon from '@material-ui/icons/Close';
import green from '@material-ui/core/colors/green';
import amber from '@material-ui/core/colors/amber';
import IconButton from '@material-ui/core/IconButton';
import Snackbar from '@material-ui/core/Snackbar';
import SnackbarContent from '@material-ui/core/SnackbarContent';
import WarningIcon from '@material-ui/icons/Warning';
import { makeStyles } from '@material-ui/core/styles';
const variantIcon = {
success: CheckCircleIcon,
warning: WarningIcon,
error: ErrorIcon,
info: InfoIcon,
};
const useStyles1 = makeStyles(theme => ({
success: {
backgroundColor: green[600],
},
error: {
backgroundColor: theme.palette.error.dark,
},
info: {
backgroundColor: theme.palette.primary.dark,
},
warning: {
backgroundColor: amber[700],
},
icon: {
fontSize: 20,
},
iconVariant: {
opacity: 0.9,
marginRight: theme.spacing(1),
},
message: {
display: 'flex',
alignItems: 'center',
},
}));
function MySnackbarContentWrapper(props) {
const classes = useStyles1();
const { className, message, onClose, variant, ...other } = props;
const Icon = variantIcon[variant];
return (
<SnackbarContent
className={clsx(classes[variant], className)}
aria-describedby="client-snackbar"
message={
<span id="client-snackbar" className={classes.message}>
<Icon className={clsx(classes.icon, classes.iconVariant)} />
{message}
</span>
}
action={[
<IconButton key="close" aria-label="Close" color="inherit" onClick={onClose}>
<CloseIcon className={classes.icon} />
</IconButton>,
]}
{...other}
/>
);
}
MySnackbarContentWrapper.propTypes = {
className: PropTypes.string,
message: PropTypes.node,
onClose: PropTypes.func,
variant: PropTypes.oneOf(['success', 'warning', 'error', 'info']).isRequired,
};
const useStyles2 = makeStyles(theme => ({
margin: {
margin: theme.spacing(1),
},
}));
function CustomizedSnackbars() {
const classes = useStyles2();
const [open, setOpen] = React.useState(false);
function handleClick() {
setOpen(true);
}
function handleClose(event, reason) {
if (reason === 'clickaway') {
return;
}
setOpen(false);
}
return (
<div>
<Button variant="outlined" className={classes.margin} onClick={handleClick}>
Open success snackbar
</Button>
<Snackbar
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
open={open}
autoHideDuration={6000}
onClose={handleClose}
>
<MySnackbarContentWrapper
onClose={handleClose}
variant="success"
message="This is a success message!"
/>
</Snackbar>
<MySnackbarContentWrapper
variant="error"
className={classes.margin}
message="This is an error message!"
/>
<MySnackbarContentWrapper
variant="warning"
className={classes.margin}
message="This is a warning message!"
/>
<MySnackbarContentWrapper
variant="info"
className={classes.margin}
message="This is an information message!"
/>
<MySnackbarContentWrapper
variant="success"
className={classes.margin}
message="This is a success message!"
/>
</div>
);
}
export default CustomizedSnackbars;
这是我到目前为止所做的:
https://codesandbox.io/s/material-demo-2dvos
错误信息是我目前得到的信息。
请帮忙,我将不胜感激。
问题在于您使用 Slide
组件的方式。
https://material-ui.com/api/slide/
children element A single child content element.
⚠️ Needs to be able to hold a ref.
Slide 元素的子元素是您的 MySnackbarContentWrapper
组件,它不接受或持有引用。更新它以保存一个 ref 并且它按预期工作:
const MySnackbarContentWrapper = React.forwardRef((props, ref) => {
const classes = useStyles1();
const { className, message, onClose, variant, ...other } = props;
const Icon = variantIcon[variant];
return (
<SnackbarContent
ref={ref}
className={clsx(classes[variant], className)}
aria-describedby="client-snackbar"
message={
<span id="client-snackbar" className={classes.message}>
<Icon className={clsx(classes.icon, classes.iconVariant)} />
{message}
</span>
}
action={[
<IconButton
key="close"
aria-label="Close"
color="inherit"
onClick={onClose}
>
<CloseIcon className={classes.icon} />
</IconButton>
]}
{...other}
/>
);
})