Snackbar
Snackbars provide brief messages about processes through a message — typically at the bottom of the screen.
Simple Snackbar
class SimpleSnackbar extends React.Component {constructor(props) {super(props);this.handleClose = this.handleClose.bind(this);this.handleClick = this.handleClick.bind(this);this.state = {open: false,};}handleClose() {this.setState({ open: false });}handleClick() {this.setState({ open: true });}render() {return (<div><Button onClick={this.handleClick}>Open simple snackbar</Button><SnackbaranchorOrigin={{vertical: 'bottom',horizontal: 'right',}}open={this.state.open}autoHideDuration={6000}onClose={this.handleClose}ContentProps={{'aria-describedby': 'message-id',}}message={<span id="message-id">Note archived</span>}action={[<Buttonkey="undo"variant="text"color="inherit"size="small"onClick={this.handleClose}>UNDO</Button>,<IconButton key="close" aria-label="Close" color="inherit" onClick={this.handleClose}><Close /></IconButton>,]}/></div>);}}
Positioned Snackbar
There may be circumstances when the placement of the snackbar needs to be more flexible.
class PositionedSnackbar extends React.Component {constructor(props) {super(props);this.handleClose = this.handleClose.bind(this);this.state = {open: false,vertical: 'top',horizontal: 'center',};}handleClose() {this.setState({ open: false });}handleClick(state) {this.setState({ open: true, ...state });}render() {const { vertical, horizontal, open } = this.state;return (<div><Buttonvariant="text"onClick={() => this.handleClick({ vertical: 'top', horizontal: 'center' })}>Top-Center</Button><Buttonvariant="text"onClick={() => this.handleClick({ vertical: 'top', horizontal: 'right' })}>Top-Right</Button><Buttonvariant="text"onClick={() =>this.handleClick({vertical: 'bottom',horizontal: 'right',})}>Bottom-Right</Button><Buttonvariant="text"onClick={() =>this.handleClick({vertical: 'bottom',horizontal: 'center',})}>Bottom-Center</Button><Buttonvariant="text"onClick={() => this.handleClick({ vertical: 'bottom', horizontal: 'left' })}>Bottom-Left</Button><Buttonvariant="text"onClick={() => this.handleClick({ vertical: 'top', horizontal: 'left' })}>Top-Left</Button><SnackbaranchorOrigin={{ vertical, horizontal }}open={open}onClose={this.handleClose}ContentProps={{'aria-describedby': 'positioned-message-id',role: 'alert',}}message={<span id="positioned-message-id">I love snacks</span>}/></div>);}}
Message Length
Some snackbars with varying message length.
<div><SnackbarContentmessage="I love snacks."style={{ marginBottom: '16px' }}action={<Button color="neutral" size="small" variant="contained">Agree</Button>}/><SnackbarContentmessage={'I love candy. I love cookies. I love cupcakes. \I love cheesecake. I love chocolate.'}style={{ marginBottom: '16px' }}role="alert"/><SnackbarContentmessage="I love candy. I love cookies. I love cupcakes."style={{ marginBottom: '16px' }}action={<Button variant="text" color="inherit" size="small">lorem ipsum dolorem</Button>}/><SnackbarContentmessage={'I love candy. I love cookies. I love cupcakes. \I love cheesecake. I love chocolate.'}style={{ marginBottom: '16px' }}action={<Button variant="text" color="inherit" size="small">lorem ipsum dolorem</Button>}/></div>
Transitions
Consecutive Snackbars
When a second snackbar is triggered while the first is displayed, the first should start the contraction motion downwards before the second one animates upwards.
class ConsecutiveSnackbars extends React.Component {constructor(props) {super(props);this.processQueue = this.processQueue.bind(this);this.handleExited = this.handleExited.bind(this);this.handleClose = this.handleClose.bind(this);this.state = {open: false,messageInfo: {},};this.queue = [];}handleClick(message) {this.queue.push({message,key: new Date().getTime(),});if (this.state.open) {// immediately begin dismissing current message// to start showing new onethis.setState({ open: false });} else {this.processQueue();}}processQueue() {if (this.queue.length > 0) {this.setState({messageInfo: this.queue.shift(),open: true,});}}handleClose(event, reason) {if (reason === 'clickaway') {return;}this.setState({ open: false });}handleExited() {this.processQueue();}render() {const { messageInfo } = this.state;return (<div><Button variant="text" onClick={() => this.handleClick('message a')}>Show message A</Button><Button variant="text" onClick={() => this.handleClick('message b')}>Show message B</Button><Snackbarkey={messageInfo.key}anchorOrigin={{vertical: 'bottom',horizontal: 'right',}}open={this.state.open}autoHideDuration={6000}onClose={this.handleClose}onExited={this.handleExited}ContentProps={{'aria-describedby': 'fade-message-id',role: 'alert',}}message={<span id="fade-message-id">{messageInfo.message}</span>}action={[<Buttonkey="undo"variant="text"color="inherit"size="small"onClick={this.handleClose}>UNDO</Button>,<IconButton key="close" aria-label="Close" color="inherit" onClick={this.handleClose}><Close /></IconButton>,]}/></div>);}}
Using With Fab
Move the floating action button vertically to accommodate the snackbar height.
class FabIntegrationSnackbar extends React.Component {constructor(props) {super(props);this.handleClose = this.handleClose.bind(this);this.handleClick = this.handleClick.bind(this);this.state = {open: false,};}handleClick() {this.setState({ open: true });}handleClose() {this.setState({ open: false });}render() {const { open } = this.state;const fabTranslate = open ? 'translate3d(0, -46px, 0)' : 'translate3d(0, 0, 0)';return (<div style={{ position: 'relative', overflow: 'hidden', margin: 'auto', maxWidth: '360px' }}><Button variant="outlined" margin={{ bottom: 1 }} onClick={this.handleClick}>Open snackbar</Button><divstyle={{position: 'relative',maxWidth: '360px',minHeight: '330px',backgroundColor: '#fff',}}><AppBar position="static" color="primary"><Toolbar><IconButton color="inherit" aria-label="Menu"><MenuIcon /></IconButton><Typography variant="h6" color="inherit" margin={{ left: 2 }}>Out of my way!</Typography></Toolbar></AppBar><Fabaria-label="Add"color="secondary"style={{position: 'absolute',bottom: 8 * 2,right: 8 * 2,transform: fabTranslate,}}><Add /></Fab><Snackbaropen={open}autoHideDuration={4000}onClose={this.handleClose}ContentProps={{'aria-describedby': 'snackbar-fab-message-id',}}message={<span id="snackbar-fab-message-id">Archived</span>}action={<Button variant="text" color="inherit" size="small" onClick={this.handleClose}>Undo</Button>}style={{ position: 'absolute' }}/></div></div>);}}
Change Transition
Use a different transition all together.
class FadeSnackbar extends React.Component {constructor(props) {super(props);this.handleClose = this.handleClose.bind(this);this.handleClick = this.handleClick.bind(this);this.state = {open: false,};}handleClick() {this.setState({ open: true });}handleClose() {this.setState({ open: false });}render() {const { open } = this.state;const fabTranslate = open ? 'translate3d(0, -46px, 0)' : 'translate3d(0, 0, 0)';return (<div><Button onClick={this.handleClick}>Open with Fade Transition</Button><Snackbaropen={this.state.open}onClose={this.handleClose}TransitionComponent={Fade}ContentProps={{'aria-describedby': 'message-id',}}message={<span id="message-id">I love snacks</span>}/></div>);}}