react-toastify icon indicating copy to clipboard operation
react-toastify copied to clipboard

Use completely custom toast instead of overwriting classes etc.

Open agcty opened this issue 4 years ago β€’ 21 comments

I'd really like to use my own completely styled toast component and just use the toastify api to display/close it. It doesn't seem like this is possible (didn't find anything in the docs), is there a way to do it?

agcty avatar Apr 09 '20 17:04 agcty

For the moment the only way is to write your own css. But with the v6 coming soon https://github.com/fkhadra/react-toastify/pull/432 this will be possible

fkhadra avatar Apr 09 '20 17:04 fkhadra

Ah wow, that's good to know, thank you! Really looking forward to v6

agcty avatar Apr 09 '20 18:04 agcty

100% Agree. Overwriting everything is a huge mess. @fkhadra How does v6 solve this?

itayganor avatar Apr 18 '20 00:04 itayganor

You don't have to overwrite everything. Just build yours from scratch.

import 'react-toastify/dist/ReactToastify.minimal.css';

Build yours:

/** Used to define container behavior: width, position: fixed etc... **/
.Toastify__toast-container {
}

/** Used to define the position of the ToastContainer **/
.Toastify__toast-container--top-left {
}
.Toastify__toast-container--top-center {
}
.Toastify__toast-container--top-right {
}
.Toastify__toast-container--bottom-left {
}
.Toastify__toast-container--bottom-center {
}
.Toastify__toast-container--bottom-right {
}

/** Classes for the displayed toast **/
.Toastify__toast {
}
.Toastify__toast--rtl {
}
.Toastify__toast--dark {
}
.Toastify__toast--default {
}
.Toastify__toast--info {
}
.Toastify__toast--success {
}
.Toastify__toast--warning {
}
.Toastify__toast--error {
}
.Toastify__toast-body {
}

/** Classes for the close button. Better use your own closeButton **/
.Toastify__close-button {
}
.Toastify__close-button--default {
}
.Toastify__close-button > svg {
}
.Toastify__close-button:hover, .Toastify__close-button:focus {
}

/** Classes for the progress bar **/
.Toastify__progress-bar {
}
.Toastify__progress-bar--animated {
}
.Toastify__progress-bar--controlled {
}
.Toastify__progress-bar--rtl {
}
.Toastify__progress-bar--default {
}
.Toastify__progress-bar--dark {
}

You also have an example here Edit react-styled-components-toastify transition issue

If you are comfortable with sass. Grab the scss directory of the repository and build your own stylesheet. If you just want to changes some colors most of them are defined inside the _variables.scss file.

scss
β”œβ”€β”€ _closeButton.scss
β”œβ”€β”€ _progressBar.scss
β”œβ”€β”€ _toast.scss
β”œβ”€β”€ _toastContainer.scss
β”œβ”€β”€ _variables.scss
β”œβ”€β”€ πŸ“ animations
β”‚  β”œβ”€β”€ _bounce.scss
β”‚  β”œβ”€β”€ _flip.scss
β”‚  β”œβ”€β”€ _slide.scss
β”‚  └── _zoom.scss
β”œβ”€β”€ main.scss
└── minimal.scss

Hope this can help

fkhadra avatar Apr 18 '20 08:04 fkhadra

It's already 6.0.2 and I can't see the ability to swap toast component for custom one, am I missing something, or feature was cancelled ?

hrytskivr avatar May 12 '20 09:05 hrytskivr

Hello @hrytskivr,

2 new hooks are expose useToast and useToastContainer. Unfortunatelly this is not documented yet how to use them. I'm still thinking about the usability

fkhadra avatar May 12 '20 16:05 fkhadra

I have created my own custom toast @hrytskivr @agcty image

nihalanisumit avatar May 25 '20 00:05 nihalanisumit

Hey @nihalanisumit, looks awesome, do you mind sharing the source if possible ?

EDIT: @itayganor I'm interested by the style here

fkhadra avatar May 25 '20 08:05 fkhadra

@fkhadra as far as I understand you are the maintainer. Yeah I know that it is not documented yet but it is implemented already and can be used and the API will not be changed? Thanks.

pavelspichonak avatar May 26 '20 17:05 pavelspichonak

@pavelspichonak indeed I'm the maintainer and the author of the library. It's not documented yet cause I need to find time to do it. I don't expect the API to change that much, I would prefer to simplify it a bit.

If you are interested you can check how ToastContainer and Toast component are implemented.

fkhadra avatar May 26 '20 18:05 fkhadra

Toast.tsx

import React from 'react'
import styles from './toast.module.css'
import successIcon from './images/greentick.svg'
import errorIcon from './images/redalert.svg'
import closeIcon from './images/closebutton.svg'
export declare type ToastType = 'info' | 'success' | 'error'

interface Props {
  message: string
  type: ToastType
}

const Toast: React.SFC<Props> = (props) => {
  return (
    <div
      className={styles.container}
      style={{ borderColor: props.type === 'success' ? '#27AE60' : '#EB5757' }}
    >
      <div className={styles.flex}>
        <div>
          <img src={props.type === 'success' ? successIcon : errorIcon} />
        </div>
        <p className={styles.message}>{props.message}</p>
        <div className={styles.closeButton}>
          <img src={closeIcon} />{' '}
        </div>
      </div>
    </div>
  )
}

export default Toast

toast.module.css

.container {
  padding: 20px 16px;
  background: #333;
  width: 100%;
  border-left: solid 4px #27ae60;
}

.flex {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  font-size: 16px;
  font-family: Open Sans;
}

.message {
  padding: 0px 16px;
  margin: 0px;
  color: #fff;
}

.closeButton {
  margin-left: auto;
}

In app.css

.Toastify__toast {
  border-radius: 4px;
  background-color: #333;
  padding: 0px;
}

.Toastify__toast-container {
  width: min(400px, 100vw);
}

Finally,

import React from 'react'
import { toast, ToastOptions, Slide } from 'react-toastify'
import ToastUI, { ToastType } from './Toast'

const toastOptions: ToastOptions = {
  position: 'top-center',
  autoClose: 10000,
  hideProgressBar: true,
  closeOnClick: true,
  pauseOnHover: true,
  draggable: true,
  progress: undefined,
  transition: Slide,
  rtl: false,
  closeButton: false,
}

export const sendNotification = (message: string, type: ToastType) => {
  toast(<ToastUI message={message} type={type} />, toastOptions)
}

cc @fkhadra

nihalanisumit avatar May 26 '20 18:05 nihalanisumit

This example is not working for me. Is it possible to get some official docs on how to do this?

stoplion avatar Jul 03 '20 20:07 stoplion

@nihalanisumit

This is really interesting, but for some reason the toast is displaying incorrectly for me (I made some small modifications so it looked like I needed, but the strange margin/padding on the toast couldn't be removed) Π—Π½Ρ–ΠΌΠΎΠΊ Π΅ΠΊΡ€Π°Π½Π°  ΠΎ 21 35 11 (Also sorry for necromancy)

Delta-official avatar May 08 '21 18:05 Delta-official

@nihalanisumit

This is really interesting, but for some reason the toast is displaying incorrectly for me (I made some small modifications so it looked like I needed, but the strange margin/padding on the toast couldn't be removed) Π—Π½Ρ–ΠΌΠΎΠΊ Π΅ΠΊΡ€Π°Π½Π° ΠΎ 21 35 11 (Also sorry for necromancy)

Inspect the CSS it can be removed by overwriting the styles

Godwin9911 avatar Jun 25 '21 15:06 Godwin9911

@fkhadra hey , I just wanted to change the background color for all the toast that are available, I am using scss , react-typescript and I have parcel bundler too. I tried all the possible way from your documentation to change the background but it's not working can you help me out. @fkhadra

PukarHub avatar Aug 01 '21 12:08 PukarHub

Hey @PukarHub sorry for the late reply. I've released a new major version that allows more configuration when it comes to styling. https://fkhadra.github.io/react-toastify/migration-v8

fkhadra avatar Aug 31 '21 13:08 fkhadra

Hey there , It is still not working on my application. Can you help me please??

On Tue, Aug 31, 2021 at 7:06 PM Fadi Khadra @.***> wrote:

Hey @PukarHub https://github.com/PukarHub sorry for the late reply. I've released a new major version that allows more configuration when it comes to styling. https://fkhadra.github.io/react-toastify/migration-v8

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/fkhadra/react-toastify/issues/455#issuecomment-909232803, or unsubscribe https://github.com/notifications/unsubscribe-auth/AJNAUY3WFJA4RJL2ARRNHMTT7TJPFANCNFSM4ME4S4CA .

PukarHub avatar Sep 01 '21 07:09 PukarHub

Another way of doing this (and I suspect @fkhadra's intention) is to create your own implementation of ToastContainer and Toast by using the useToastContainer and useToast hooks. This implementation can take inspiration from the existing ToastContainer.tsx and Toast.tsx but instead of rendering plain divs in Toast.tsx you render your own custom toast.

This is how I plugged the ToastNotification from the Carbon Design System into react-toastify: Toast.tsx ToastContainer.tsx toast.ts Toast.module.scss toastUtils.ts

I created a new toast function that takes a title, subtitle and caption and renders a Carbon Toast notification like so:

toast("My title", "My subtitle", "My caption")

image

This solution requires quite a lot of code though. It would be nicer if the react-toastify's ToastContainer component could take a custom Toast component to render. E.g. customToast: (props: ToastProps) => ReactNode @fkhadra

mthaak avatar Jul 22 '22 10:07 mthaak

Since you're allowed to render a React component as a prop you can just wrap library's methods, like this, I believe. Ideally there would be no extra wrapper divs from library, but you can neutralize them easily enough. Other than that, I believe ergonomics are quite tolerable. You can also leverage existing animations as an extra benefit.


type MyToastProps = {
  title: string
  description: string
  timestamp: string
}

export const showToast = (myProps: MyToastProps, options: ToastOptions) => {
   return toast(<MyToastImplementation {...myProps} />, options);
}

export const updateToast = (id: string | number, myProps: MyToastProps, options: ToastOptions) => {
   return toast.update(id, {
        render: <MyToastImplementation {...myProps} />,
        ...options
    });
}

Faithfinder avatar Aug 03 '22 23:08 Faithfinder