<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Fadi Khadra</title>
    <description>The latest articles on DEV Community by Fadi Khadra (@fkhadra).</description>
    <link>https://dev.to/fkhadra</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F50677%2Fd4d0cd29-0d05-43cf-97db-994b8f7f712b.png</url>
      <title>DEV Community: Fadi Khadra</title>
      <link>https://dev.to/fkhadra</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fkhadra"/>
    <language>en</language>
    <item>
      <title>React-toastify v11 - finally easy to customize</title>
      <dc:creator>Fadi Khadra</dc:creator>
      <pubDate>Mon, 16 Dec 2024 23:38:40 +0000</pubDate>
      <link>https://dev.to/fkhadra/react-toastify-v11-finally-easy-to-customize-2g74</link>
      <guid>https://dev.to/fkhadra/react-toastify-v11-finally-easy-to-customize-2g74</guid>
      <description>&lt;p&gt;Never heard of react-toastify before? Go check the &lt;a href="https://fkhadra.github.io/react-toastify/introduction" rel="noopener noreferrer"&gt;demo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is new in v11
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;In short, react-toastify should be able to blend into any design system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feoywx1ljosdvl0qusndh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feoywx1ljosdvl0qusndh.png" alt="customization" width="800" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  No need to import the css file anymore
&lt;/h3&gt;

&lt;p&gt;The stylesheet is now injected automatically, so you no longer need to import it. The CSS file is still exported by the library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ToastContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;toast&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-toastify&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notify&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Wow so easy !&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;notify&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Notify !&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ToastContainer&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Easy customization!
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Below, I’ve implemented a couple of different designs using only Tailwind. &lt;strong&gt;I didn’t override a single CSS class from react-toastify 🤯!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feoywx1ljosdvl0qusndh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feoywx1ljosdvl0qusndh.png" alt="customization" width="800" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Head to &lt;a href="https://stackblitz.com/edit/react-toastify-how-to-style?file=src%2FApp.tsx" rel="noopener noreferrer"&gt;stackblitz&lt;/a&gt; to check the code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;How does it work in practice? On the left side, we have the old DOM structure vs the new one on the right side.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibmbkpsaknz4cld2nd1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibmbkpsaknz4cld2nd1w.png" alt="noti-struct" width="800" height="116"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Toastify__toast-body&lt;/code&gt; and its child are now completely gone.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;CloseButton&lt;/code&gt; now uses an absolute position.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks to those changes, &lt;strong&gt;nothing will interfere with your content.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Toastify__toast&lt;/code&gt; has some sensible default values(e.g., border-radius, shadow, etc...) that can be customized using css or by updating the associated css variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--toastify-toast-width&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;min-height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--toastify-toast-min-height&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--toastify-toast-padding&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;border-radius&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--toastify-toast-bd-radius&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;box-shadow&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--toastify-toast-shadow&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;max-height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--toastify-toast-max-height&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;font-family&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--toastify-font-family&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Custom progress bar
&lt;/h3&gt;

&lt;p&gt;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 😆.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fuser-attachments%2Fassets%2F1ec197de-df35-4c13-9252-035368f78e47" class="article-body-image-wrapper"&gt;&lt;img alt="custom-progress-bar" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fuser-attachments%2Fassets%2F1ec197de-df35-4c13-9252-035368f78e47" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a small gist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notify&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CustomComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;autoClose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;// removes the built-in progress bar&lt;/span&gt;
      &lt;span class="na"&gt;customProgressBar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;notify&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;notify&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ToastContainer&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// isPaused is now available in your component&lt;/span&gt;
&lt;span class="c1"&gt;// it tells you when to pause the animation: pauseOnHover, pauseOnFocusLoss etc...&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;CustomComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;isPaused&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;closeToast&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;ToastContentProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyCustomProgressBar&lt;/span&gt; &lt;span class="na"&gt;isPaused&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isPaused&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onAnimationEnd&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;closeToast&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Head to &lt;a href="https://stackblitz.com/edit/react-toastify-custom-progress-bar?file=src%2FApp.tsx" rel="noopener noreferrer"&gt;stackblitz&lt;/a&gt; for a live example.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Accessibility and keyboard navigation
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;ariaLabel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;something&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a notification is visible and the user presses &lt;code&gt;alt+t&lt;/code&gt; it will focus on the first notification allowing the user to use &lt;code&gt;Tab&lt;/code&gt; to navigate through the different elements within the notification.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;hotKeys&lt;/code&gt; can be changed of course.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// focus when user presses ⌘ + F&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;matchShortcut&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;KeyboardEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metaKey&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;f&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ToastContainer&lt;/span&gt; &lt;span class="nx"&gt;hotKeys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;matchShortcut&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;ariaLabel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Notifications ⌘ + F&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Notification removal reason with onClose callback
&lt;/h3&gt;

&lt;p&gt;Do you want to know whether the user closed the notification or if it closed automatically? Rest assured, this is now possible!&lt;/p&gt;

&lt;p&gt;The signature of the &lt;code&gt;onClose&lt;/code&gt; callback is now &lt;code&gt;onClose(reason?: boolean | string) =&amp;gt; void&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When the user closes the notification, the &lt;code&gt;reason&lt;/code&gt; argument is equal to &lt;code&gt;true&lt;/code&gt;. In the example below, I've named my argument&lt;br&gt;
&lt;code&gt;removedByUser&lt;/code&gt; to make the intent clear.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;onClose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;removedByUser&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;removedByUser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// do something&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// auto close do something else&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using a custom component for your notification, you might want more control over the reason, especially if it contains&lt;br&gt;
multiple call to actions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ToastContentProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-toastify&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;CustomNotification&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;closeToast&lt;/span&gt;&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;ToastContentProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      You received a new message
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;closeToast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reply&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Reply&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;closeToast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ignore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Ignore&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CustomNotification&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;onClose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reply&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// navigate to reply page for example or open a dialog&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ignore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// tell the other user that she/he was ghosted xD&lt;/span&gt;
      &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// 🤷‍♂️&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  💥 Breaking Changes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  useToastContainer and useToast no longer exposed
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  onClose and onOpen no longer receive children props
&lt;/h3&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;onOpen: () =&amp;gt; void&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;onClose: (reason?: boolean | string) =&amp;gt; void&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Styling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;react-toastify/dist/ReactToastify.minimal.css&lt;/code&gt; has been removed.&lt;/li&gt;
&lt;li&gt;Scss is out of the picture now. The library uses good old css.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bodyClassName&lt;/code&gt; and &lt;code&gt;bodyStyle&lt;/code&gt; are no longer needed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;progressBarStyle&lt;/code&gt; in order to reduce the api surface. They are now better way to customize everything without relying on inline style.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;injectStyle&lt;/code&gt; has been removed. This function is no longer needed.&lt;/li&gt;
&lt;li&gt;The css class &lt;code&gt;Toastify__toast-body&lt;/code&gt; and its direct child have been removed.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibmbkpsaknz4cld2nd1w.png" alt="noti-struct" width="800" height="116"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🐞 Bug Fixes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;add support for react19 &lt;a href="https://github.com/fkhadra/react-toastify/issues/1177" rel="noopener noreferrer"&gt;#1177&lt;/a&gt; &lt;a href="https://github.com/fkhadra/react-toastify/issues/1185" rel="noopener noreferrer"&gt;#1185&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;reexport CloseButtonProps &lt;a href="https://github.com/fkhadra/react-toastify/issues/1165" rel="noopener noreferrer"&gt;#1165&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;fix newestOnTop for real this time &lt;a href="https://github.com/fkhadra/react-toastify/issues/1176" rel="noopener noreferrer"&gt;#1176&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;no longer throw this ugly error: Cannot set properties of undefined (setting 'toggle') &lt;a href="https://github.com/fkhadra/react-toastify/issues/1170" rel="noopener noreferrer"&gt;#1170&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;onClose callback is no longer delayed until the exit animation completes &lt;a href="https://github.com/fkhadra/react-toastify/issues/1179" rel="noopener noreferrer"&gt;#1179&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔮What's next?
&lt;/h2&gt;

&lt;p&gt;I'm gradually rewriting part of the documentation. I've created a &lt;a href="https://stackblitz.com/@fkhadra/collections/react-toastify" rel="noopener noreferrer"&gt;collection on stackblitz&lt;/a&gt;, this way you can find all the examples in one place. I'll keep adding more examples as I go.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffbjp787y0qly981vhap3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffbjp787y0qly981vhap3.png" alt="Screenshot 2024-12-16 at 09 50 48" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>library</category>
    </item>
    <item>
      <title>A beautiful TUI for caniuse.com</title>
      <dc:creator>Fadi Khadra</dc:creator>
      <pubDate>Tue, 10 Jan 2023 21:25:26 +0000</pubDate>
      <link>https://dev.to/fkhadra/a-beautiful-tui-for-caniusecom-3a37</link>
      <guid>https://dev.to/fkhadra/a-beautiful-tui-for-caniusecom-3a37</guid>
      <description>&lt;p&gt;Hey, I just released a TUI for caniuse.com. I tried to keep the most important informations from the web version. It work offline as well after the initial launch and it update itself as well on regular basis.&lt;/p&gt;

&lt;p&gt;more details here: &lt;a href="https://github.com/fkhadra/caniuse" rel="noopener noreferrer"&gt;https://github.com/fkhadra/caniuse&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb4ex5vvxkevzbcdjc9pp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb4ex5vvxkevzbcdjc9pp.png" alt="main screen" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9u4gsyt3ooewm7iwh57.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9u4gsyt3ooewm7iwh57.png" alt="search" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibeh2bioliygudb882ox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibeh2bioliygudb882ox.png" alt="support table" width="800" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>go</category>
      <category>javascript</category>
      <category>cli</category>
    </item>
    <item>
      <title>React-contexify v6 is live!</title>
      <dc:creator>Fadi Khadra</dc:creator>
      <pubDate>Mon, 14 Nov 2022 10:49:19 +0000</pubDate>
      <link>https://dev.to/fkhadra/react-contexify-v6-is-live-535d</link>
      <guid>https://dev.to/fkhadra/react-contexify-v6-is-live-535d</guid>
      <description>&lt;p&gt;Never heard of react-contexify before? Go check the &lt;a href="https://fkhadra.github.io/react-contexify/"&gt;demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React-contexify let you add a context menu (right click) to your react app with ease.&lt;br&gt;
It comes with a lot of features: prevent menu from going off screen, keyboard shortcut, keyboard navigation, custom positioning, subemnu support, super easy to customize, etc...&lt;/p&gt;

&lt;p&gt;It can even be used to be simple dropdown 😆.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QAUprT-z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fmcb86o8hlye5cyeq9is.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QAUprT-z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fmcb86o8hlye5cyeq9is.gif" alt="react-contexify dropdown" width="370" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React-contexify is the first react library I've open sourced, it was also my sandbox when learning react. I'm super excited by this release!&lt;/p&gt;

&lt;h2&gt;
  
  
  New features in v6
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Allow to disable boundaries check&lt;/li&gt;
&lt;li&gt;Allow to disable preventDefault on key down&lt;/li&gt;
&lt;li&gt;Add support for hidden property to Separator&lt;/li&gt;
&lt;li&gt;Add visual feedback when item is clicked&lt;/li&gt;
&lt;li&gt;Easy customization thanks to css variables. Check out the &lt;a href="https://fkhadra.github.io/react-contexify/theme-builder"&gt;theme builder&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Keyboard shortcut made easy! A keyMatcher prop has been added to the Item component. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Despite adding new features, the library size decreased from 3.4Kb to 3.1Kb 💪.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migrating from an older version?
&lt;/h2&gt;

&lt;p&gt;If you are migrating from an older version, you can follow this &lt;a href="https://fkhadra.github.io/react-contexify/migrate"&gt;guide&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>library</category>
    </item>
    <item>
      <title>React-toastify v8 is live</title>
      <dc:creator>Fadi Khadra</dc:creator>
      <pubDate>Thu, 26 Aug 2021 21:16:33 +0000</pubDate>
      <link>https://dev.to/fkhadra/react-toastify-v8-is-live-4bal</link>
      <guid>https://dev.to/fkhadra/react-toastify-v8-is-live-4bal</guid>
      <description>&lt;p&gt;Never heard of react-toastify before? Go check the &lt;a href="https://fkhadra.github.io/react-toastify/introduction" rel="noopener noreferrer"&gt;demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React-toastify has been around for 5 years(will turn five the 8 November 🎂). Since the beginning, one of the goals was to provide a library that is highly customizable and also able to work out of the box. Every major release introduces breaking changes but this is for the best 👌.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is new in v8
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F5574267%2F130804494-a9d2d69c-f170-4576-b2e1-0bb7f13dd92d.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F5574267%2F130804494-a9d2d69c-f170-4576-b2e1-0bb7f13dd92d.gif" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Who doesn't like icons
&lt;/h3&gt;

&lt;p&gt;Let's break down what is happening in the gif above. Notifications of different types (&lt;code&gt;toast.info&lt;/code&gt;, &lt;code&gt;toast.error&lt;/code&gt;, &lt;code&gt;toast.success&lt;/code&gt;, &lt;code&gt;toast.warning&lt;/code&gt;) display an icon associated with the selected type. You can also notice that the progress bar color matches the type color.&lt;/p&gt;

&lt;p&gt;Don't be afraid 😱, if you don't like those icons you can use your own or remove them. This is what it looks like in practice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Default toast behavior is untouched, no icon to display&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lorem ipsum dolor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// same as toast(message, {type: "info"});&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lorem ipsum dolor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lorem ipsum dolor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lorem ipsum dolor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Without icon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You can provide any string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🚀&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// custom icons have access to the theme and the toast type&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;And of course a component of your choice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MyIcon&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Even a function, given you return something that can be rendered&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;//Disable icons&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ToastContainer&lt;/span&gt; &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Clear separation between type and theme
&lt;/h3&gt;

&lt;p&gt;Prior to v8, &lt;code&gt;toast.info&lt;/code&gt;, &lt;code&gt;toast.error&lt;/code&gt;, etc... Would display respectively a blue notification, a red notification, etc... This is not the case anymore. There are 3 distinct themes: &lt;code&gt;light&lt;/code&gt;, &lt;code&gt;dark&lt;/code&gt;, &lt;code&gt;colored&lt;/code&gt;. The theme can be applied globally or per notification.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Set the theme globally &lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ToastContainer&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"dark"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// define per toast&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Display a dark notification of type info&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Display a light notification of type info&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Display a blue notification of type info&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;colored&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separation will benefit theming in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  I promise this is new, I'll tell you if you await
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F5574267%2F130862557-8d13ddf0-c6bf-4f52-968a-1d91c62b6016.png" class="article-body-image-wrapper"&gt;&lt;img alt="v8-promise" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F5574267%2F130862557-8d13ddf0-c6bf-4f52-968a-1d91c62b6016.png" width="800" height="176"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F5574267%2F130862554-652397ed-1b1e-40d4-a250-c38734ec8e5d.png" class="article-body-image-wrapper"&gt;&lt;img alt="v8-promise-resolved" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F5574267%2F130862554-652397ed-1b1e-40d4-a250-c38734ec8e5d.png" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The library exposes a &lt;code&gt;toast.promise&lt;/code&gt; function. Supply a promise and the notification will be updated if it resolves or fails. When the promise is pending a spinner is displayed. Again you hide it, I bet you already know how to😆.&lt;/p&gt;

&lt;p&gt;Let's start with a simple example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolveAfter3Sec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;resolveAfter3Sec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;pending&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Promise is pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Promise resolved 👌&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Promise rejected 🤯&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Displaying a simple message is what you would want to do in 90% of cases. But what if the message you want to display depends on the promise response, what if you want to change some options for the error notification? Rest assured, under the hood, the library uses &lt;code&gt;toast.update&lt;/code&gt;. Thanks to this, you have full control over each notification.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolveWithSomeData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;resolveAfter3Sec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;pending&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Promise is pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;}){&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Hello &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="c1"&gt;// other options&lt;/span&gt;
        &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🟢&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;}){&lt;/span&gt;
          &lt;span class="c1"&gt;// When the promise reject, data will contains the error&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyErrorComponent&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because you have the full power of &lt;code&gt;toast.update&lt;/code&gt;, you can even supply a custom transition if you want 🤯&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F5574267%2F130869645-586777a3-3326-4664-917e-a13aee367c43.gif" class="article-body-image-wrapper"&gt;&lt;img alt="v8-promise-resolved" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F5574267%2F130869645-586777a3-3326-4664-917e-a13aee367c43.gif" width="600" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to take care of each step yourself you can use &lt;code&gt;toast.loading&lt;/code&gt; and update the notification yourself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please wait...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//do something else&lt;/span&gt;
&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;All is good&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pass data even when you are not rendering a react component
&lt;/h3&gt;

&lt;p&gt;One way to pass data to the notification was to use the context api or provide your own component. Starting v8 a &lt;code&gt;data&lt;/code&gt; option is now available to make it easier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`Hello &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  I just want to change few colors
&lt;/h3&gt;

&lt;p&gt;Most of the time, users are ok with the default style, they just want to change some colors to match their brand. I think one way to improve the DX for all of us is to embrace CSS variables. That's why the library has switched to css variables! &lt;br&gt;
All you want is to change the color of the progress bar? No problem&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;this&lt;/span&gt; &lt;span class="err"&gt;is&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;default&lt;/span&gt; &lt;span class="err"&gt;value&lt;/span&gt; &lt;span class="err"&gt;below&lt;/span&gt;
  &lt;span class="py"&gt;--toastify-color-progress-light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;#4cd964&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;#5ac8fa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;#007aff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;#34aadc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;#5856d6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;#ff2d55&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find the list of all exposed variables &lt;a href="//./how-to-style.md#override-css-variables"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading. You can access the full release note &lt;a href="https://fkhadra.github.io/react-toastify/migration-v8" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>library</category>
    </item>
    <item>
      <title>React-toastify v7 is live</title>
      <dc:creator>Fadi Khadra</dc:creator>
      <pubDate>Tue, 09 Feb 2021 15:38:31 +0000</pubDate>
      <link>https://dev.to/fkhadra/react-toastify-v7-is-live-5fj5</link>
      <guid>https://dev.to/fkhadra/react-toastify-v7-is-live-5fj5</guid>
      <description>&lt;p&gt;The v7 react-toastify has been released. Besides the bug fixes, this version brings really nice improvement.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CSS animation just works! Changing the animation should be as easy as a copy/paste. &lt;br&gt;
&lt;iframe src="https://codesandbox.io/embed/react-toastify-animatecss-jxrx9"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide a way to load the CSS without a CSS loader. &lt;br&gt;
&lt;iframe src="https://codesandbox.io/embed/react-toastify-inject-style-qfg0l"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Specify swipe direction.&lt;br&gt;
&lt;iframe src="https://codesandbox.io/embed/react-toastify-drag-y-lh88i"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Last but not least, the bundle size has been reduced from ~7k to ~5k 🎉  &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/fkhadra/react-toastify"&gt;https://github.com/fkhadra/react-toastify&lt;/a&gt;&lt;br&gt;
Documentation: &lt;a href="https://fkhadra.github.io/react-toastify/introduction/"&gt;https://fkhadra.github.io/react-toastify/introduction/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enjoy !&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>The road to React-contexify v5</title>
      <dc:creator>Fadi Khadra</dc:creator>
      <pubDate>Thu, 03 Dec 2020 18:53:02 +0000</pubDate>
      <link>https://dev.to/fkhadra/the-road-to-react-contexify-v5-5b2e</link>
      <guid>https://dev.to/fkhadra/the-road-to-react-contexify-v5-5b2e</guid>
      <description>&lt;p&gt;TLDR: For those who never heard about react-contexify, the library lets you add a context menu to your app with ease. You can see what it looks like below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7fBFK-Uw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://user-images.githubusercontent.com/5574267/100552409-500dfd80-3287-11eb-96ee-fc1d17ef50b8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7fBFK-Uw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://user-images.githubusercontent.com/5574267/100552409-500dfd80-3287-11eb-96ee-fc1d17ef50b8.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
You can find the project &lt;a href="https://fkhadra.github.io/react-contexify/"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  There is always room for improvement
&lt;/h2&gt;

&lt;p&gt;There were 36 open issues on GitHub 😱(vs 2 today). It doesn't seem like a lot but for a single person, believe me, it takes quite some time to review them all. Every time I wanted to work on it, I had to cancel, I always found a "good" reason to give up.&lt;/p&gt;

&lt;p&gt;One day, while I was working on a new app, I needed a context menu. Without thinking too much I've added react-contexify to my app and I started to work with it. The more I've worked with it the more I was struggling to accomplish even the simple things, and I'm the one who created this 🤦‍♂️.&lt;/p&gt;

&lt;p&gt;Despite the lack of simplicity, some people were still using it. Open source is about people, not about software. I had to thanks those people for their trust. One way of doing that was to improve the library they rely on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do it, do it right, do it well
&lt;/h2&gt;

&lt;p&gt;After browsing the 36 issues, I was able to classify them into 3 categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bug&lt;/li&gt;
&lt;li&gt;features&lt;/li&gt;
&lt;li&gt;lack of documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks to that, I knew exactly what I had to do. I won't go into details on how I fixed the bugs or added new features. What I want to highlight here, is when you understand the problem you have to solve, it become clear in your mind what you should do. It's a real productivity boost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Eat your own dogfood
&lt;/h2&gt;

&lt;p&gt;The documentation is as important as the code, even more important. I noticed that with one of my other library, &lt;a href="https://github.com/fkhadra/react-toastify"&gt;react-toastify&lt;/a&gt;, when I rewrote the documentation for it, the download skyrocketed(currently 2M/Month based on npm stat).&lt;/p&gt;

&lt;p&gt;Based on my previous experience, I decided to rewrite the documentation. During the rewrite, I used my library extensively, thanks to that I spotted bugs and missing features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key take away
&lt;/h2&gt;

&lt;p&gt;Invest your time in the documentation. Good documentation === happy developer 😍&lt;br&gt;
Your project doesn't need to be perfect before you release it. You can always improve it over time.&lt;/p&gt;

&lt;p&gt;Hope you enjoyed that post. Thanks for reading!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
