Build a Toast Message Component via React and Styled Components with Ease by@parmeetsasija
412 reads

Build a Toast Message Component via React and Styled Components with Ease

tldt arrow
Read on Terminal Reader

Too Long; Didn't Read

This article aims to explain how we could use [react-hot-toast] and [styled-components] to create some beautiful-looking toast messages. Notifications are yet another way to provide feedback to the user. Toast notifications usually contain brief messages and sometimes get accompanied by CTAs as well. The toast notification function is called 'Toast Notification' and 'Toaster' component is called inside App component. Toast Notification component contains the styles for Toast Notification. component.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Build a Toast Message Component via React and Styled Components with Ease
Parmeet Singh Asija HackerNoon profile picture

@parmeetsasija

Parmeet Singh Asija

Freelance Frontend Developer with 3+ years experience in React, Javascript...

Learn More
LEARN MORE ABOUT @PARMEETSASIJA'S EXPERTISE AND PLACE ON THE INTERNET.
react to story with heart

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

yarn add react-hot-toast styled-components

Constants

Default Title, Default Description & variants enum is stored in this file.

// path: src/components/toast-notification/data.js

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.

// path: src/App.js

// External
import { Toaster } from "react-hot-toast";

// Components
import Form from "./components/form";

// Styles
import { 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.

// path: src/components/toast-notification/index.js

import React from "react";

// External
import toast from "react-hot-toast";

// Components
import CustomIcon from "../CustomIcon";

// Styles
import {
  NotificationCard,
  NotificationImage,
  NotificationImageWrapper,
  NotificationContent,
  NotificationTitle,
  NotificationDescription,
  NotificationIconButton,
  BubblesImage,
} from "../../styles";

const ToastNotification = ({
  t,
  bgColor,
  icon,
  bubbleImage,
  title,
  message,
}) => {
  // handlers
  const 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.

//path: src/components/form/index.js

import React, { useState, useEffect } from "react";

// External
import toast from "react-hot-toast";

// Components
import ToastNotification from "../toast-notification";

// Styles
import {
  Button,
  RadioButtonContainer,
  RadioButtonInput,
  OptionsContainer,
  Container,
} from "../../styles";

// Image
import 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";

// Constants
import {
  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 changes
  useEffect(() => {
    setTitle(DEFAULT_TITLE[currentVariant]);
    setMessage(DEFAULT_DESCRIPTION[currentVariant]);
  }, [currentVariant]);

  // show appropriate toast notification as per the variant
  const showToastNotification = () => {
    if (currentVariant === variants.SUCCESS) {
      toast.custom(t => (
        <ToastNotification
          t={t}
          icon={successImage}
          bubbleImage={greenBubbles}
          bgColor="#76bf4c"
          title={title}
          message={message}
        />
      ));
    }

    if (currentVariant === variants.QUESTION) {
      toast.custom(t => (
        <ToastNotification
          t={t}
          icon={questionImage}
          bubbleImage={blueBubbles}
          bgColor="#B8B5FF"
          title={title}
          message={message}
        />
      ));
    }

    if (currentVariant === variants.WARNING) {
      toast.custom(t => (
        <ToastNotification
          t={t}
          icon={warningImage}
          bubbleImage={yellowBubbles}
          bgColor="#FCA652"
          title={title}
          message={message}
        />
      ));
    }
    if (currentVariant === variants.FAIL) {
      toast.custom(t => (
        <ToastNotification
          t={t}
          icon={failImage}
          bubbleImage={redBubbles}
          bgColor="#F05454"
          title={title}
          message={message}
        />
      ));
    }
  };

  // handlers
  const 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}>
            <RadioButtonInput
              type="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>
        <input
          id="title-field"
          type="text"
          value={title}
          onChange={handleTitleChange}
        />
        <label htmlFor="message-field">Message</label>
        <textarea
          id="message-field"
          rows="6"
          value={message}
          onChange={handleMessageChange}
        ></textarea>
      </Container>
      <Button
        isSelected={!(!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! ✨

Follow me on Twitter & Instagram for more!

This article can also be read on my website.

RELATED STORIES

L O A D I N G
. . . comments & more!
Hackernoon hq - po box 2206, edwards, colorado 81632, usa