Components • 16th October, 2021 • 4 mins read
How to create a beautiful toast message component using React and Styled Components
Toast Notifications are yet another way to provide feedback to the user. They usually contain brief messages and sometimes get accompanied by CTAs as well.
This article aims to explain how we could use react-hot-toast and styled-components to create some beautiful-looking toast messages 😉
Project Initialisation
npx create-react-app toast-notification
Install Dependencies
- react-hot-toast for getting the toast notification functionality
- styled-components for styling needs
yarn add react-hot-toast styled-components
Constants
Default Title, Default Description & variants enum is stored in this file.
export const variants = {SUCCESS: "Success",WARNING: "Warning",QUESTION: "Question",FAIL: "Fail",};export const DEFAULT_TITLE = {Success: "Well done!",Warning: "Warning!",Question: "Hi there!",Fail: "Oh snap!",};export const DEFAULT_DESCRIPTION = {Success: "You successfully read this important message.",Warning: "Sorry! There was a problem with your request.",Question: "Do you have a problem? Just use this contact form.",Fail: "Change a few things up and try submitting again.",};
App Component
Form
& Toaster
component is called inside App component.
// Externalimport { Toaster } from "react-hot-toast";// Componentsimport Form from "./components/form";// Stylesimport { AppStyles } from "./styles";const App = () => {return (<AppStyles><Form /><Toaster position="bottom-left" gutter={56} /></AppStyles>);};export default App;
Toast Notification Component
Toast Notification Component contains the styles for Toast Notification.
import React from "react";// Externalimport toast from "react-hot-toast";// Componentsimport CustomIcon from "../CustomIcon";// Stylesimport {NotificationCard,NotificationImage,NotificationImageWrapper,NotificationContent,NotificationTitle,NotificationDescription,NotificationIconButton,BubblesImage,} from "../../styles";const ToastNotification = ({t,bgColor,icon,bubbleImage,title,message,}) => {// handlersconst handleDismiss = () => {toast.dismiss(t.id);};return (<><NotificationImageWrapper><NotificationImage src={icon} alt="" role="presentation" /></NotificationImageWrapper><NotificationCard bgColor={bgColor}><BubblesImage src={bubbleImage} alt="" role="presentation" /><NotificationContent><NotificationTitle>{title}</NotificationTitle><NotificationDescription>{message}</NotificationDescription></NotificationContent><NotificationIconButton onClick={handleDismiss}><CustomIcon icon="times" /></NotificationIconButton></NotificationCard></>);};export default ToastNotification;
Form Component
This component contains the inputs used for testing out the component.
import React, { useState, useEffect } from "react";// Externalimport toast from "react-hot-toast";// Componentsimport ToastNotification from "../toast-notification";// Stylesimport {Button,RadioButtonContainer,RadioButtonInput,OptionsContainer,Container,} from "../../styles";// Imageimport questionImage from "../../images/question.png";import successImage from "../../images/success.png";import warningImage from "../../images/warning.png";import failImage from "../../images/fail.png";import greenBubbles from "../../images/green-bubbles.png";import redBubbles from "../../images/red-bubbles.png";import blueBubbles from "../../images/blue-bubbles.png";import yellowBubbles from "../../images/yellow-bubbles.png";// Constantsimport {variants,DEFAULT_TITLE,DEFAULT_DESCRIPTION,} from "../ToastNotification/data";const Form = () => {const [currentVariant, setCurrentVariant] = useState(variants.SUCCESS);const [title, setTitle] = useState(DEFAULT_TITLE.SUCCESS);const [message, setMessage] = useState(DEFAULT_DESCRIPTION.SUCCESS);// change title and message when notification variant changesuseEffect(() => {setTitle(DEFAULT_TITLE[currentVariant]);setMessage(DEFAULT_DESCRIPTION[currentVariant]);}, [currentVariant]);// show appropriate toast notification as per the variantconst showToastNotification = () => {if (currentVariant === variants.SUCCESS) {toast.custom(t => (<ToastNotificationt={t}icon={successImage}bubbleImage={greenBubbles}bgColor="#76bf4c"title={title}message={message}/>));}if (currentVariant === variants.QUESTION) {toast.custom(t => (<ToastNotificationt={t}icon={questionImage}bubbleImage={blueBubbles}bgColor="#B8B5FF"title={title}message={message}/>));}if (currentVariant === variants.WARNING) {toast.custom(t => (<ToastNotificationt={t}icon={warningImage}bubbleImage={yellowBubbles}bgColor="#FCA652"title={title}message={message}/>));}if (currentVariant === variants.FAIL) {toast.custom(t => (<ToastNotificationt={t}icon={failImage}bubbleImage={redBubbles}bgColor="#F05454"title={title}message={message}/>));}};// handlersconst handleVariantChange = e => {setCurrentVariant(e.target.name);};const handleTitleChange = e => {setTitle(e.target.value);};const handleMessageChange = e => {setMessage(e.target.value);};return (<><OptionsContainer>{Object.values(variants).map(variant => (<RadioButtonContainer key={variant}><RadioButtonInputtype="radio"id={variant}name={variant}checked={currentVariant === variant}onChange={handleVariantChange}/><label htmlFor={variant}>{variant}</label></RadioButtonContainer>))}</OptionsContainer><br /><Container><label htmlFor="title-field">Title</label><inputid="title-field"type="text"value={title}onChange={handleTitleChange}/><label htmlFor="message-field">Message</label><textareaid="message-field"rows="6"value={message}onChange={handleMessageChange}></textarea></Container><ButtonisSelected={!(!title || !message)}onClick={showToastNotification}>Show Toast!</Button></>);};export default Form;
Conclusion
And there we have it, we have got elegant-looking alert notification implemented. The Code is available on Github. Would love to hear your valuable feedback in the comments down below.
See you guys 👋🏻 in the next article of this Component series!
Happy coding & Stay safe! ✨