react-toastify
react-toastify copied to clipboard
Feature request: separate onDismiss callback & don't trigger onClose on manual dismiss
This is a feature request, but also a bug report.
FEATURE REQUEST: Anytime a toast closes, manually or automatically, onClose is called. This makes the undo toast recipe unuseful in certain scenarios. For example, I've to handle in onClose whether or not I manually dismissed the toast. It gets really complicated when the toast can be manually dismissed at different points.
Proposal: Add an onDismiss callback option which is called when and only when the toast is manually dismissed. For onClick, either we can have it so that it maintains the current behaviour if onDismiss is not provided but doesn't trigger when it is provided. Otherwise it should stop triggering on manual dismiss altogether, making this a breaking change.
BUG: In the example linked above, click on multiple delete row buttons back to back. Now depending on the order you click undo buttons, one or more undos will not work.
VERSIONS: OS: macOS 10.15 Browser: Firefox Stable (latest) React: 17.0.1 Plugin: 6.2.0
Here is a custom hook I wrote to tackle this issue for now. It is designed to only have 1 toast at time, so if another entity is deleted, then the undo/deletion will be grouped together.
import React, { useRef } from "react";
import { toast } from "react-toastify";
import "./useButtonToast.css";
const useButtonToast = (onClick, onClose) => {
const toastId = useRef(null);
const isRepeatToast = useRef(false);
const isDismissOnClick = useRef(false);
const isDismissOnRepeat = useRef(false);
return {
showToast: (text, buttonText) => {
if (isRepeatToast.current) {
isDismissOnRepeat.current = true;
toast.dismiss(toastId.current);
} else {
isRepeatToast.current = true;
}
toastId.current = toast.dark(
() => {
return (
<div id="buttonToastView">
{text}
<button
id="toast"
type="button"
onClick={() => {
isDismissOnClick.current = true;
toast.dismiss(toastId.current);
onClick();
}}
>
{buttonText}
</button>
</div>
);
},
{
className: "buttonToast",
closeOnClick: false,
onClose: () => {
if (isDismissOnRepeat.current) {
isDismissOnRepeat.current = false;
} else if (isDismissOnClick.current) {
isRepeatToast.current = false;
isDismissOnClick.current = false;
} else {
isRepeatToast.current = false;
onClose();
}
},
}
);
},
};
};
export default useButtonToast;
div.buttonToast {
cursor: unset;
}
div.buttonToast .Toastify__progress-bar--dark {
background: #ee0000;
}
div#buttonToastView {
display: grid;
grid-template-columns: auto auto;
grid-template-rows: 2rem;
padding: 0.5rem;
place-items: center;
color: #ffffff;
}
button#toast {
float: right;
border: 0;
padding: 0.5rem 1rem;
font-size: 1rem;
font-weight: 700;
background: #202020;
color: #ffffff;
cursor: pointer;
}
button#toast:hover {
background: #303030;
}
i solved this by not using onClose, and just setting a timeout alongside my toast instead so i could clear it manually.
Closing the issue, onClose and onOpen callback will be removed in the next major release