react-toastify
react-toastify copied to clipboard
Use completely custom toast instead of overwriting classes etc.
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?
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
Ah wow, that's good to know, thank you! Really looking forward to v6
100% Agree. Overwriting everything is a huge mess. @fkhadra How does v6 solve this?
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 {
}
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
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 ?
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
I have created my own custom toast @hrytskivr @agcty
Hey @nihalanisumit, looks awesome, do you mind sharing the source if possible ?
EDIT: @itayganor I'm interested by the style here
@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 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.
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
This example is not working for me. Is it possible to get some official docs on how to do this?
@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) (Also sorry for necromancy)
@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) (Also sorry for necromancy)
Inspect the CSS it can be removed by overwriting the styles
@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
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
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 .
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")
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
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
});
}