AshKeys

Confessions and Confusions of Ashok M A. Personal and Professional Blog.

Ashok Mannolu Arunachalam, How toSnackbarToastUIReactJS
Back

How to create a toast or snackbar in React

After reading this web.dev article, I wanted to create toast component in ReactJS and this post showcases the same.

Goal

What we want to achieve is a toast or snackbar that appears when we click the below button.

Let's take a look at the code block and understand what is going on.

Output tag - few words

There is a HTML tag named <output>. It is there to be used semantically to show an output of a particular calculation performed by the browser or of an user interactions.

In our case, the latter is the happening.

Toast Component - Final

If you are in a rush, go ahead and copy the code block below for the component.

jsx
<output
className="snackbar fixed bottom-0 left-0
right-0 m-auto bg-[#121212] text-white
flex items-center h-12 rounded-t-lg z-10
opacity-0 text-2xl"
>
<span className="content p-4">{toastText}</span>
<button
className="action ml-auto cursor-pointer
p-4 focus:outline focus:outline-1
focus:outline-white focus:bg-[#ffffff11]"
onClick={undo}
style={{
display: actionable ? 'unset' : 'none'
}}
>
Undo
</button>
</output>
<style jsx>{`
.snackbar {
width: min(100%, 400px);
animation: slide-in 500ms ease, slide-out 500ms 3s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
.snackbar .action {
backgroud: none;
border: none;
outline: none;
color: #8effff;
border-radius: 2px;
}
@keyframes slide-in {
from {
transform: translateY(100%);
opacity: 0;
}
to {
transform: translateY(0%);
opacity: 1;
}
}
@keyframes slide-out {
to {
transform: translateY(100%);
opacity: 0;
}
}
`}</style>

Mind that the above toast component expects some properties to function. It is customizable as you noticed.

Understanding the component

Let's dive into the component segments to understand what is happening.

The HTML

jsx
<output
className="snackbar fixed bottom-0 left-0
right-0 opacity-0"
>
<span>{toastText}</span>
<button
onClick={undo}
style={{
display: actionable ? 'unset' : 'none'
}}
>
Undo
</button>
</output>

<output> tag is a presentational tag and holds nothing specific. It is named semantically.

We place here the toast message and the possible action. A toast can be either actionable or simply an informational notification.

I have simplified the code by eliminating the cosmetic changes. The same will be done on the following.

The CSS

css
.snackbar {
width: min(100%, 400px);
animation: slide-in 500ms ease, slide-out 500ms 3s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
@keyframes slide-in {
from {
transform: translateY(100%);
opacity: 0;
}
to {
transform: translateY(0%);
opacity: 1;
}
}
@keyframes slide-out {
to {
transform: translateY(100%);
opacity: 0;
}
}

Above we are trying to animate the output tag during the first render. There are two animations happening.

AnimationPurpose
slide-inUpon first render slide in the toast with ease on 500ms delay.
slide-outAfter 3s delay, slide out the toast.

width: min(100%, 400px) is handy to make the toast responsive. Try it out with mobile view in Dev Tools.

animation-fill-mode: forwards is important here to keep the opacity: 1 once the slide-in animation is done. Otherwise it will go back to the declaration (opacity:0).

css
output {
position: fixed;
bottom: 0;
left: 0;
right: 0;
}

The above css makes the toast appear on the bottom.

Try to make the toast show up at the top of the page. Do not forget to update the animations. \O/