Snackbar
Please refer to MUI's official docs for more details on component's usage guide and API documentation.
Basic Snackbar
Manage open
prop with Snackbar
component with the help of a state.
- TSX
- JS
// React Imports
import { useState } from 'react'
import type { SyntheticEvent } from 'react'
// MUI Imports
import Button from '@mui/material/Button'
import Snackbar from '@mui/material/Snackbar'
import IconButton from '@mui/material/IconButton'
const SnackbarBasic = () => {
// States
const [open, setOpen] = useState<boolean>(false)
const handleClick = () => {
setOpen(true)
}
const handleClose = (event: Event | SyntheticEvent, reason?: string) => {
if (reason === 'clickaway') {
return
}
setOpen(false)
}
return (
<>
<Button variant='outlined' onClick={handleClick}>
Open simple snackbar
</Button>
<Snackbar
open={open}
onClose={handleClose}
message='Note archived'
autoHideDuration={3000}
action={
<>
<Button size='small' onClick={handleClose}>
Undo
</Button>
<IconButton size='small' aria-label='close' color='inherit' onClick={handleClose}>
<i className='ri-close-line text-xl' />
</IconButton>
</>
}
/>
</>
)
}
export default SnackbarBasic
// React Imports
import { useState } from 'react'
// MUI Imports
import Button from '@mui/material/Button'
import Snackbar from '@mui/material/Snackbar'
import IconButton from '@mui/material/IconButton'
const SnackbarBasic = () => {
// States
const [open, setOpen] = useState(false)
const handleClick = () => {
setOpen(true)
}
const handleClose = (event, reason) => {
if (reason === 'clickaway') {
return
}
setOpen(false)
}
return (
<>
<Button variant='outlined' onClick={handleClick}>
Open simple snackbar
</Button>
<Snackbar
open={open}
onClose={handleClose}
message='Note archived'
autoHideDuration={3000}
action={
<>
<Button size='small' onClick={handleClose}>
Undo
</Button>
<IconButton size='small' aria-label='close' color='inherit' onClick={handleClose}>
<i className='ri-close-line text-xl' />
</IconButton>
</>
}
/>
</>
)
}
export default SnackbarBasic
Alert Snackbar
Add Alert
component as a children of Snackbar
component.
- TSX
- JS
// React Imports
import { SyntheticEvent, useState } from 'react'
// MUI Imports
import Alert from '@mui/material/Alert'
import Button from '@mui/material/Button'
import Snackbar from '@mui/material/Snackbar'
const SnackbarAlert = () => {
// States
const [open, setOpen] = useState<boolean>(false)
const handleClick = () => {
setOpen(true)
}
const handleClose = (event?: Event | SyntheticEvent, reason?: string) => {
if (reason === 'clickaway') {
return
}
setOpen(false)
}
return (
<>
<Button variant='outlined' onClick={handleClick}>
Open alert snackbar
</Button>
<Snackbar open={open} onClose={handleClose} autoHideDuration={3000}>
<Alert variant='filled' severity='success' onClose={handleClose} className='is-full shadow-xs'>
This is a success message!
</Alert>
</Snackbar>
</>
)
}
export default SnackbarAlert
// React Imports
import { useState } from 'react'
// MUI Imports
import Alert from '@mui/material/Alert'
import Button from '@mui/material/Button'
import Snackbar from '@mui/material/Snackbar'
const SnackbarAlert = () => {
// States
const [open, setOpen] = useState(false)
const handleClick = () => {
setOpen(true)
}
const handleClose = (event, reason) => {
if (reason === 'clickaway') {
return
}
setOpen(false)
}
return (
<>
<Button variant='outlined' onClick={handleClick}>
Open alert snackbar
</Button>
<Snackbar open={open} onClose={handleClose} autoHideDuration={3000}>
<Alert variant='filled' severity='success' onClose={handleClose} className='is-full shadow-xs'>
This is a success message!
</Alert>
</Snackbar>
</>
)
}
export default SnackbarAlert
Positioned Snackbar
Use anchorOrigin
prop to change the position of the snackbar.
- TSX
- JS
// React Imports
import { useState } from 'react'
// MUI Imports
import Button from '@mui/material/Button'
import Snackbar from '@mui/material/Snackbar'
import type { SnackbarOrigin } from '@mui/material/Snackbar'
type State = SnackbarOrigin & {
open: boolean
}
const SnackbarPositioned = () => {
// States
const [state, setState] = useState<State>({
open: false,
vertical: 'top',
horizontal: 'center'
})
const { vertical, horizontal, open } = state
const handleClick = (newState: SnackbarOrigin) => () => {
setState({ open: true, ...newState })
}
const handleClose = () => {
setState({ ...state, open: false })
}
return (
<>
<div className='flex items-center gap-4 flex-wrap'>
<Button variant='outlined' onClick={handleClick({ vertical: 'top', horizontal: 'center' })}>
Top Center
</Button>
<Button variant='outlined' onClick={handleClick({ vertical: 'top', horizontal: 'right' })}>
Top Right
</Button>
<Button variant='outlined' onClick={handleClick({ vertical: 'bottom', horizontal: 'right' })}>
Bottom Right
</Button>
<Button variant='outlined' onClick={handleClick({ vertical: 'bottom', horizontal: 'center' })}>
Bottom Center
</Button>
<Button variant='outlined' onClick={handleClick({ vertical: 'bottom', horizontal: 'left' })}>
Bottom Left
</Button>
<Button variant='outlined' onClick={handleClick({ vertical: 'top', horizontal: 'left' })}>
Top Left
</Button>
</div>
<Snackbar
open={open}
onClose={handleClose}
message='I love snacks'
autoHideDuration={3000}
key={vertical + horizontal}
anchorOrigin={{ vertical, horizontal }}
/>
</>
)
}
export default SnackbarPositioned
// React Imports
import { useState } from 'react'
// MUI Imports
import Button from '@mui/material/Button'
import Snackbar from '@mui/material/Snackbar'
const SnackbarPositioned = () => {
// States
const [state, setState] = useState({
open: false,
vertical: 'top',
horizontal: 'center'
})
const { vertical, horizontal, open } = state
const handleClick = newState => () => {
setState({ open: true, ...newState })
}
const handleClose = () => {
setState({ ...state, open: false })
}
return (
<>
<div className='flex items-center gap-4 flex-wrap'>
<Button variant='outlined' onClick={handleClick({ vertical: 'top', horizontal: 'center' })}>
Top Center
</Button>
<Button variant='outlined' onClick={handleClick({ vertical: 'top', horizontal: 'right' })}>
Top Right
</Button>
<Button variant='outlined' onClick={handleClick({ vertical: 'bottom', horizontal: 'right' })}>
Bottom Right
</Button>
<Button variant='outlined' onClick={handleClick({ vertical: 'bottom', horizontal: 'center' })}>
Bottom Center
</Button>
<Button variant='outlined' onClick={handleClick({ vertical: 'bottom', horizontal: 'left' })}>
Bottom Left
</Button>
<Button variant='outlined' onClick={handleClick({ vertical: 'top', horizontal: 'left' })}>
Top Left
</Button>
</div>
<Snackbar
open={open}
onClose={handleClose}
message='I love snacks'
autoHideDuration={3000}
key={vertical + horizontal}
anchorOrigin={{ vertical, horizontal }}
/>
</>
)
}
export default SnackbarPositioned
Consecutive Snackbars
When multiple snackbar updates are necessary, they should appear one at a time.
- TSX
- JS
// React Imports
import { useEffect, useState } from 'react'
import type { SyntheticEvent } from 'react'
// MUI Imports
import Alert from '@mui/material/Alert'
import Button from '@mui/material/Button'
import Snackbar from '@mui/material/Snackbar'
export type SnackbarMessage = {
key: number
message: string
}
const SnackbarConsecutive = () => {
// States
const [open, setOpen] = useState<boolean>(false)
const [snackPack, setSnackPack] = useState<SnackbarMessage[]>([])
const [messageInfo, setMessageInfo] = useState<SnackbarMessage | undefined>(undefined)
useEffect(() => {
if (snackPack.length && !messageInfo) {
setOpen(true)
setSnackPack(prev => prev.slice(1))
setMessageInfo({ ...snackPack[0] })
} else if (snackPack.length && messageInfo && open) {
setOpen(false)
}
}, [snackPack, messageInfo, open])
const handleClick = (message: string) => () => {
setSnackPack(prev => [...prev, { message, key: new Date().getTime() }])
}
const handleClose = (event: Event | SyntheticEvent, reason?: string) => {
if (reason === 'clickaway') {
return
}
setOpen(false)
}
const handleExited = () => {
setMessageInfo(undefined)
}
return (
<>
<div className='flex gap-4'>
<Button variant='outlined' onClick={handleClick('success')}>
Success Alert
</Button>
<Button variant='outlined' onClick={handleClick('error')}>
Error Alert
</Button>
</div>
<Snackbar
open={open}
onClose={handleClose}
autoHideDuration={3000}
TransitionProps={{ onExited: handleExited }}
key={messageInfo ? messageInfo.key : undefined}
message={messageInfo ? messageInfo.message : undefined}
>
<Alert
variant='filled'
onClose={handleClose}
className='is-full shadow-xs'
severity={messageInfo?.message === 'success' ? 'success' : 'error'}
>
This is {messageInfo?.message === 'success' ? 'a success' : 'an error'} message!
</Alert>
</Snackbar>
</>
)
}
export default SnackbarConsecutive
// React Imports
import { useEffect, useState } from 'react'
// MUI Imports
import Alert from '@mui/material/Alert'
import Button from '@mui/material/Button'
import Snackbar from '@mui/material/Snackbar'
const SnackbarConsecutive = () => {
// States
const [open, setOpen] = useState(false)
const [snackPack, setSnackPack] = useState([])
const [messageInfo, setMessageInfo] = useState(undefined)
useEffect(() => {
if (snackPack.length && !messageInfo) {
setOpen(true)
setSnackPack(prev => prev.slice(1))
setMessageInfo({ ...snackPack[0] })
} else if (snackPack.length && messageInfo && open) {
setOpen(false)
}
}, [snackPack, messageInfo, open])
const handleClick = message => () => {
setSnackPack(prev => [...prev, { message, key: new Date().getTime() }])
}
const handleClose = (event, reason) => {
if (reason === 'clickaway') {
return
}
setOpen(false)
}
const handleExited = () => {
setMessageInfo(undefined)
}
return (
<>
<div className='flex gap-4'>
<Button variant='outlined' onClick={handleClick('success')}>
Success Alert
</Button>
<Button variant='outlined' onClick={handleClick('error')}>
Error Alert
</Button>
</div>
<Snackbar
open={open}
onClose={handleClose}
autoHideDuration={3000}
TransitionProps={{ onExited: handleExited }}
key={messageInfo ? messageInfo.key : undefined}
message={messageInfo ? messageInfo.message : undefined}
>
<Alert
variant='filled'
onClose={handleClose}
className='is-full shadow-xs'
severity={
(messageInfo === null || messageInfo === void 0 ? void 0 : messageInfo.message) === 'success'
? 'success'
: 'error'
}
>
This is{' '}
{(messageInfo === null || messageInfo === void 0 ? void 0 : messageInfo.message) === 'success'
? 'a success'
: 'an error'}{' '}
message!
</Alert>
</Snackbar>
</>
)
}
export default SnackbarConsecutive
Change Transition
When multiple snackbar updates are necessary, they should appear one at a time.
- TSX
- JS
// React Imports
import { useState } from 'react'
import type { ComponentType, ReactElement } from 'react'
// MUI Imports
import Grow from '@mui/material/Grow'
import Fade from '@mui/material/Fade'
import Slide from '@mui/material/Slide'
import Button from '@mui/material/Button'
import Snackbar from '@mui/material/Snackbar'
import type { GrowProps } from '@mui/material/Grow'
import type { FadeProps } from '@mui/material/Fade'
import type { SlideProps } from '@mui/material/Slide'
const GrowTransition = (props: GrowProps) => {
return <Grow {...props} />
}
const SlideTransition = (props: SlideProps) => {
return <Slide {...props} direction='up' />
}
const SnackbarTransition = () => {
// States
const [state, setState] = useState<{
open: boolean
Transition: ComponentType<
FadeProps & {
children?: ReactElement<any>
}
>
}>({
open: false,
Transition: Fade
})
const handleClick =
(
Transition: ComponentType<
FadeProps & {
children?: ReactElement<any>
}
>
) =>
() => {
setState({
open: true,
Transition
})
}
const handleClose = () => {
setState({
...state,
open: false
})
}
return (
<>
<div className='flex items-center gap-4 flex-wrap'>
<Button variant='outlined' onClick={handleClick(GrowTransition)}>
Grow Transition
</Button>
<Button variant='outlined' onClick={handleClick(Fade)}>
Fade Transition
</Button>
<Button variant='outlined' onClick={handleClick(SlideTransition)}>
Slide Transition
</Button>
</div>
<Snackbar
open={state.open}
onClose={handleClose}
message='I love snacks'
autoHideDuration={3000}
key={state.Transition.name}
TransitionComponent={state.Transition}
/>
</>
)
}
export default SnackbarTransition
// React Imports
import { useState } from 'react'
// MUI Imports
import Grow from '@mui/material/Grow'
import Fade from '@mui/material/Fade'
import Slide from '@mui/material/Slide'
import Button from '@mui/material/Button'
import Snackbar from '@mui/material/Snackbar'
const GrowTransition = props => {
return <Grow {...props} />
}
const SlideTransition = props => {
return <Slide {...props} direction='up' />
}
const SnackbarTransition = () => {
// States
const [state, setState] = useState({
open: false,
Transition: Fade
})
const handleClick = Transition => () => {
setState({
open: true,
Transition
})
}
const handleClose = () => {
setState({
...state,
open: false
})
}
return (
<>
<div className='flex items-center gap-4 flex-wrap'>
<Button variant='outlined' onClick={handleClick(GrowTransition)}>
Grow Transition
</Button>
<Button variant='outlined' onClick={handleClick(Fade)}>
Fade Transition
</Button>
<Button variant='outlined' onClick={handleClick(SlideTransition)}>
Slide Transition
</Button>
</div>
<Snackbar
open={state.open}
onClose={handleClose}
message='I love snacks'
autoHideDuration={3000}
key={state.Transition.name}
TransitionComponent={state.Transition}
/>
</>
)
}
export default SnackbarTransition
Control Slide Direction
You can change the direction of the Slide
transition.
- TSX
- JS
// React Imports
import { useState } from 'react'
import type { ComponentType } from 'react'
// MUI Imports
import Button from '@mui/material/Button'
import Snackbar from '@mui/material/Snackbar'
import Slide from '@mui/material/Slide'
import type { SlideProps } from '@mui/material/Slide'
type TransitionProps = Omit<SlideProps, 'direction'>
const TransitionLeft = (props: TransitionProps) => {
return <Slide {...props} direction='left' />
}
const TransitionUp = (props: TransitionProps) => {
return <Slide {...props} direction='up' />
}
const TransitionRight = (props: TransitionProps) => {
return <Slide {...props} direction='right' />
}
const TransitionDown = (props: TransitionProps) => {
return <Slide {...props} direction='down' />
}
const SnackbarControlSlideDirection = () => {
// States
const [open, setOpen] = useState<boolean>(false)
const [transition, setTransition] = useState<ComponentType<TransitionProps> | undefined>(undefined)
const handleClick = (Transition: ComponentType<TransitionProps>) => () => {
setTransition(() => Transition)
setOpen(true)
}
const handleClose = () => {
setOpen(false)
}
return (
<>
<div className='flex gap-3'>
<Button variant='outlined' onClick={handleClick(TransitionLeft)}>
Right
</Button>
<Button variant='outlined' onClick={handleClick(TransitionUp)}>
Up
</Button>
<Button variant='outlined' onClick={handleClick(TransitionRight)}>
Left
</Button>
<Button variant='outlined' onClick={handleClick(TransitionDown)}>
Down
</Button>
</div>
<Snackbar
open={open}
onClose={handleClose}
message='I love snacks'
autoHideDuration={3000}
TransitionComponent={transition}
key={transition ? transition.name : ''}
/>
</>
)
}
export default SnackbarControlSlideDirection
// React Imports
import { useState } from 'react'
// MUI Imports
import Button from '@mui/material/Button'
import Snackbar from '@mui/material/Snackbar'
import Slide from '@mui/material/Slide'
const TransitionLeft = props => {
return <Slide {...props} direction='left' />
}
const TransitionUp = props => {
return <Slide {...props} direction='up' />
}
const TransitionRight = props => {
return <Slide {...props} direction='right' />
}
const TransitionDown = props => {
return <Slide {...props} direction='down' />
}
const SnackbarControlSlideDirection = () => {
// States
const [open, setOpen] = useState(false)
const [transition, setTransition] = useState(undefined)
const handleClick = Transition => () => {
setTransition(() => Transition)
setOpen(true)
}
const handleClose = () => {
setOpen(false)
}
return (
<>
<div className='flex gap-3'>
<Button variant='outlined' onClick={handleClick(TransitionLeft)}>
Right
</Button>
<Button variant='outlined' onClick={handleClick(TransitionUp)}>
Up
</Button>
<Button variant='outlined' onClick={handleClick(TransitionRight)}>
Left
</Button>
<Button variant='outlined' onClick={handleClick(TransitionDown)}>
Down
</Button>
</div>
<Snackbar
open={open}
onClose={handleClose}
message='I love snacks'
autoHideDuration={3000}
TransitionComponent={transition}
key={transition ? transition.name : ''}
/>
</>
)
}
export default SnackbarControlSlideDirection