Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(deps): update dependency react-toastify to v11 #401

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

renovate[bot]
Copy link
Contributor

@renovate renovate bot commented Dec 24, 2024

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
react-toastify ^9.1.3 -> ^11.0.0 age adoption passing confidence

Release Notes

fkhadra/react-toastify (react-toastify)

v11.0.2

Compare Source

v11.0.1

Compare Source

v11.0.0: v11

Compare Source

What is new in v11

I’m super excited about this release! The main focus was on customization, and my goal was to empower you (and myself) so you can fully personalize the look and feel for the notifications.

In short, react-toastify should be able to blend into any design system.

Screenshot 2024-12-12 at 22 21 52

No need to import the css file anymore

The stylesheet is now injected automatically, so you no longer need to import it. The CSS file is still exported by the library.

  import { ToastContainer, toast } from 'react-toastify';

  function App(){
    const notify = () => toast("Wow so easy !");

    return (
      <div>
        <button onClick={notify}>Notify !</button>
        <ToastContainer />
      </div>
    );
  }
Easy customization!

One of the top requests has been how to customize notifications. To be fair, until this release, it was quite challenging because it required users to override numerous CSS classes.

I’ve simplified the DOM structure of the notification by removing extraneous div elements, nested elements, etc... It’s a significant breaking change, but it’s truly worth the effort. I can confidently say that the library can now seamlessly integrate into any design system.

Below, I’ve implemented a couple of different designs using only Tailwind. I didn’t override a single CSS class from react-toastify 🤯!

Screenshot 2024-12-12 at 22 21 52

[!NOTE]
Head to stackblitz to check the code.

How does it work in practice? On the left side, we have the old DOM structure vs the new one on the right side.

noti-struct

  • Toastify__toast-body and its child are now completely gone.
  • The CloseButton now uses an absolute position.

Thanks to those changes, nothing will interfere with your content.

Toastify__toast has some sensible default values(e.g., border-radius, shadow, etc...) that can be customized using css or by updating the associated css variables:

width: var(--toastify-toast-width);
min-height: var(--toastify-toast-min-height);
padding: var(--toastify-toast-padding);
border-radius: var(--toastify-toast-bd-radius);
box-shadow: var(--toastify-toast-shadow);
max-height: var(--toastify-toast-max-height);
font-family: var(--toastify-font-family);
Custom progress bar

Allowing a custom progress bar wasn’t on my to-do list at all while working on this release. But seeing how easy it is to customize notifications now, I couldn’t resist 😆.

The best part is that you don’t have to compromise on features like autoClose, pauseOnHover, pauseOnFocusLoss, or even a controlled progress bar—it just works seamlessly for you.

custom-progress-bar

Here is a small gist.

function App() {
  const notify = () => {
    toast(CustomComponent, {
      autoClose: 8000,
      // removes the built-in progress bar
      customProgressBar: true
    });
  };

  return (
    <div>
      <button onClick={notify}>notify</button>
      <ToastContainer />
    </div>
  );
}

// isPaused is now available in your component
// it tells you when to pause the animation: pauseOnHover, pauseOnFocusLoss etc...
function CustomComponent({ isPaused, closeToast }: ToastContentProps) {
  return (
    <div>
      <span>Hello</span>
      <MyCustomProgressBar isPaused={isPaused} onAnimationEnd={() => closeToast()} />
    </div>
  );
}

[!NOTE]
Head to stackblitz for a live example.

Accessibility and keyboard navigation

ToastContainer and toast accept an ariaLabel prop(finally...). This is quite helpful for screen readers and also for testing.
For example, in cypress you could do cy.findByRole("alert", {name: "the aria label you specified"}).

toast("hello", {
  ariaLabel: "something"
})

If a notification is visible and the user presses alt+t it will focus on the first notification allowing the user to use Tab to navigate through the different elements within the notification.

The hotKeys can be changed of course.

// focus when user presses ⌘ + F
const matchShortcut = (e: KeyboardEvent) => e.metaKey && e.key === 'f'

<ToastContainer hotKeys={matchShortcut} ariaLabel="Notifications ⌘ + F" />
Notification removal reason with onClose callback

Do you want to know whether the user closed the notification or if it closed automatically? Rest assured, this is now possible!

The signature of the onClose callback is now onClose(reason?: boolean | string) => void.

When the user closes the notification, the reason argument is equal to true. In the example below, I've named my argument
removedByUser to make the intent clear.

toast("hello", {
  onClose(removedByUser){
    if(removedByUser) {
      // do something
      return
    }

    // auto close do something else
  }
})

If you are using a custom component for your notification, you might want more control over the reason, especially if it contains
multiple call to actions.

import { ToastContentProps } from "react-toastify";

function CustomNotification({closeToast}: ToastContentProps) {
  return <div>
      You received a new message
      <button onClick={() => closeToast("reply")}>Reply</button>
      <button onClick={() => closeToast("ignore")}>Ignore</button>
    </div>
}

toast(CustomNotification, {
  onClose(reason){
    switch (reason) {
      case "reply":
        // navigate to reply page for example or open a dialog
      case "ignore":
        // tell the other user that she/he was ghosted xD
      default:
        // 🤷‍♂️
    }
  }
})

💥 Breaking Changes

useToastContainer and useToast no longer exposed

Those hooks are unusable unless you deep dive in react-toastify source code to understand how to glue things together. This is not what I want for my users, it was a bad decision to expose them in the first place, I've learned a good lesson.

onClose and onOpen no longer receive children props

In hindsight, I should never have done this. The feature is practically not used. Below the new signature for each callback:

  • onOpen: () => void
  • onClose: (reason?: boolean | string) => void
Styling
  • react-toastify/dist/ReactToastify.minimal.css has been removed.
  • Scss is out of the picture now. The library uses good old css.
  • bodyClassName and bodyStyle are no longer needed.
  • progressBarStyle in order to reduce the api surface. They are now better way to customize everything without relying on inline style.
  • injectStyle has been removed. This function is no longer needed.
  • The css class Toastify__toast-body and its direct child have been removed.
    noti-struct

🐞 Bug Fixes

  • add support for react19 #​1177 #​1185
  • reexport CloseButtonProps #​1165
  • fix newestOnTop for real this time #​1176
  • no longer throw this ugly error: Cannot set properties of undefined (setting 'toggle') #​1170
  • onClose callback is no longer delayed until the exit animation completes #​1179

🔮What's next?

I'm gradually rewriting part of the documentation. I've created a collection on stackblitz, this way you can find all the examples in one place. I'll keep adding more examples as I go.

Screenshot 2024-12-16 at 09 50 48

I've been maintaining react-toastify for more than 8 years. If your company depends on it, consider contributing to its continued development and maintenance. Open-source software thrives with community support, and funding helps ensure we(the maintainers) can keep improving and innovating.

Every contribution, big or small, makes a difference and is greatly appreciated.

v10.0.6

Compare Source

v10.0.5

Compare Source

v10.0.4

Compare Source

v10.0.3

Compare Source

v10.0.2

Compare Source

v10.0.1

Compare Source

v10.0.0

Compare Source

What is new in v10

The code for this release has been sitting on my computer for almost a year but with so many things going on it was hard for me to release it but it's finally there! A good chunk of the code has been rewritten, a bunch of bugs have been fixed. I've also addressed the oldest open feature request (Jan 10, 2020) 😆.

stacked

Screenshot 2023-12-17 at 14 53 50

Features

Play or pause the timer programmatically

By default, when the notification is hovered or the window loses focus, the timer for dismissing the notification is paused. There are many other situations where you might want to pause the timer as well. For instance, consider wanting to toggle the notification timer based on the document's visibility. This wasn't possible to do previously, but with the new API, it's a breeze.

document.addEventListener("visibilitychange", () => {
  if (document.visibilityState === "visible") {
    toast.play({ id: "123" });
  } else {
    toast.pause({ id: "123" });
  }
});

More usages:

  • Play/pause all toasts
toast.play()
toast.pause()
  • Play/pause all toasts for a given container
toast.play({ containerId: "123" })
toast.pause({ containerId: "123" })
  • Play/pause toast that has a given id regardless the container
toast.play({ id: "123" })
toast.pause({ id: "123" })
  • Play/pause toast that has a given id for a specific container
toast.play({ id: "123", containerId: "12" })
toast.pause({ id: "123", containerId: "12" })
Remove notification from a given container

This feature was the oldest one in the backlog (Jan 10, 2020). I don't know if the user who requested this feature is still using the library but I bet thanks to her/him, a bunch of user will be happy.

  • Remove all toasts that belongs to a given container
toast.dismiss({ container: "123" })
  • Remove toast that has a given id for a specific container
toast.dismiss({ id: "123", containerId: "12" })

The method is backward compatible. toast.dismis() and toast.dismiss("123") work as usual.

Check if a notification is active for a given container

You can limit the call to toast.isActive to a specific container.

  toast.isActive(toastId, containerId)
Better typescript inference when using data

When providing data to the notification, the content of data is correctly infered by typescript.

toast((props) => {
  return <div>{props.data.foo}</div>
},{
  data: {
    foo: "bar"
  }
})
IconProps now receives isLoading

When providing your own logic to display the icon, you now have access to the isLoading field.

const CustomIcon = props => {
  if (props.isLoading) return <Spinner />;

  switch (props.type) {
    case 'info':
      return <Info color={iconColor} />;
    case 'success':
      return <Success color={iconColor} />;
    case 'error':
      return <Error color={iconColor} />;
    case 'warning':
      return <Warning color={iconColor} />;
    default:
      return undefined;
  }
};

<ToastContainer icon={CustomIcon} />
Stacked Notifications

The initial release for this feature was planned right after the release of the v9. The code was their but things happen in life and I wasn't able to focus on the project that much.

That being said, I'm glad to finally release it.

stacked

To enable it, add the stacked prop to the ToastContainer. I also suggest to disable the progress bar :).

<ToastContainer stacked />
Progress bar background trail

The progress bar leaves a background trail by default.

Screenshot 2023-12-17 at 14 53 50

The opacity of the trail can be customized by overriding the css variable --toastify-color-progress-bgo.

  // disable the trail
  --toastify-color-progress-bgo: 0;

  // increase the opacity
  --toastify-color-progress-bgo: .8;

Breaking Changes

React 18 is the minimum required version, but...

The minimun version of react required is now 18. This version has been released for more than a year. Nextjs, react-query already did this move as well, so I believe it's a good time for the library as well.

That being said, I know that not all code base have the chance to be running on the latest version of react, so I'm considering to have a package for v17 if the demand is high enough.

The enableMultiContainer prop has been removed

The enableMultiContainer props is not needed anymore and has been removed. As long as your container has an id assigned then you are good to go.

// before
<ToastContainer id="myContainer" enableMultiContainer />

// now 🎉
<ToastContainer id="myContainer"  />
The toast.position and toast.type constants have been removed

The toast.POSITION and toast.TYPE constants have been removed. Typescript came a long way since the initial release of the library. The ecosystem has matured to a point where such constants are not needed anymore.

Change for some defaults

The closeOnClick prop is now false by default instead of true. When using the library I keep on turning this feature off which make me realize that it was not a good default in the first place. To turn it on do as follow

<ToastContainer closeOnClick />

The draggable prop is set to touch by default instead of true. Which means that, by default, notifications are only draggable on touch devices (most likely mobiles and tablets). While swipping a notification on mobile feels natural, dragging on desktop is not. If you want your notification to be draggable regardless of the device type just set draggable to true.

<ToastContainer draggable />

Bug Fixes and Chore

  • Remove defaultProps on ToastContainer as it's deprecated #​970
  • Fix className from ToastOptions overrides the toastClassName in ToastContainer props instead of appending #​956
  • Rewrite tests using component testing #​923
  • Memory leak while using multiple containers are goes on in v9.1.1 #​910
  • React toast is showing multiple time. #​744
  • onClose event trigger 2 times. #​741

Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Enabled.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot enabled auto-merge (squash) December 24, 2024 00:43
Copy link
Contributor Author

renovate bot commented Dec 24, 2024

⚠️ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

♻ Renovate will retry this branch, including artifacts, only when one of the following happens:

  • any of the package files in this branch needs updating, or
  • the branch becomes conflicted, or
  • you click the rebase/retry checkbox if found above, or
  • you rename this PR's title to start with "rebase!" to trigger it manually

The artifact failure details are included below:

File name: frontend/package-lock.json
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: [email protected]
npm error Found: [email protected]
npm error node_modules/react
npm error   react@"^17.0.0" from the root project
npm error
npm error Could not resolve dependency:
npm error peer react@"^18 || ^19" from [email protected]
npm error node_modules/react-toastify
npm error   react-toastify@"^11.0.0" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error /tmp/renovate/cache/others/npm/_logs/2024-12-25T01_01_07_675Z-eresolve-report.txt
npm error A complete log of this run can be found in: /tmp/renovate/cache/others/npm/_logs/2024-12-25T01_01_07_675Z-debug-0.log

@renovate renovate bot force-pushed the renovate/react-toastify-11.x branch from 6324024 to 47822a0 Compare December 25, 2024 01:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

0 participants