Advanced Toast

PreviousNext

A feature-rich toast notification component with expandable details, progress indicator, and customizable accent colors

'use client';

import { AdvancedToast } from '@/ui/AdvancedToast';
import { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';
import { getHotToastConfig } from '@/ui/AdvancedToast.config';
import { Colors } from '@/ui/helpers/colors/colors';

export function AdvancedToastDemo() {
  const { handlers } = useToaster();

  const showToast = () => {
    toast.custom(
      (t) => (
        <AdvancedToast
          title="Upload Complete"
          body="Your file has been successfully uploaded"
          icon="CheckDefault"
          isVisible={t.visible}
          labels={{ close: 'Close', details: 'Details' }}
          onClose={() => toast.dismiss(t.id)}
          accentColor={Colors.orange}
          toastId={t.id}
          updateHeight={handlers.updateHeight}
        />
      ),
      { duration: Infinity },
    );
  };

  return (
    <>
      <Toaster {...(getHotToastConfig() as ToasterProps)} />
      <button onClick={showToast}>Show Toast</button>
    </>
  );
}

Installation

npx shadcn@latest add https://develop.trident-ui.pro.clubmed/r/advanced-toast.json

Usage

import { AdvancedToast } from '@/ui/AdvancedToast';
import { toast } from 'react-hot-toast';
 
export function Component() {
  const showToast = () => {
    toast.custom((t) => (
      <AdvancedToast
        title="Upload Complete"
        body="Your file has been successfully uploaded"
        icon="CheckDefault"
        isVisible={t.visible}
        labels={{ close: 'Close', details: 'Details' }}
        onClose={() => toast.dismiss(t.id)}
        accentColor="orange"
      />
    ));
  };
 
  return <button onClick={showToast}>Show Toast</button>;
}

API Reference

AdvancedToast

PropTypeDefaultDescription
titlestringrequiredThe main heading text of the toast
bodystringrequiredThe descriptive text content of the toast
iconIconicNamesrequiredIcon name from the Trident Icons library
isVisiblebooleanrequiredControls the visibility state and animation of the toast
labels{ close, details }requiredAccessibility labels for close button and details toggle
onClose() => voidundefinedDismiss the toast (provided by react-hot-toast)
childrenReactNodeundefinedOptional expandable details content
accentColorColorsColors.orangeColor theme for the border and progress indicator
durationfalse | number10000 (10 seconds)Auto-dismiss duration in milliseconds, or false to disable auto-dismissal
toastIdstringundefinedUnique identifier for the toast (provided by react-hot-toast)
updateHeight() => voidundefinedCallback function to update the height of the toast, get it from react-hot-toast's useToaster

Examples

Basic Toast

'use client';

import { AdvancedToast } from '@/ui/AdvancedToast';
import { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';
import { getHotToastConfig } from '@/ui/AdvancedToast.config';
import { Colors } from '@/ui/helpers/colors/colors';

export function AdvancedToastDemo() {
  const { handlers } = useToaster();

  const showToast = () => {
    toast.custom(
      (t) => (
        <AdvancedToast
          title="Upload Complete"
          body="Your file has been successfully uploaded"
          icon="CheckDefault"
          isVisible={t.visible}
          labels={{ close: 'Close', details: 'Details' }}
          onClose={() => toast.dismiss(t.id)}
          accentColor={Colors.orange}
          toastId={t.id}
          updateHeight={handlers.updateHeight}
        />
      ),
      { duration: Infinity },
    );
  };

  return (
    <>
      <Toaster {...(getHotToastConfig() as ToasterProps)} />
      <button onClick={showToast}>Show Toast</button>
    </>
  );
}

With Details

'use client';

import { AdvancedToast } from '@/ui/AdvancedToast';
import { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';
import { getHotToastConfig } from '@/ui/AdvancedToast.config';
import { Colors } from '@/ui/helpers/colors/colors';

export function AdvancedToastWithDetailsDemo() {
  const { handlers } = useToaster();

  const showToast = () => {
    toast.custom(
      (t) => (
        <AdvancedToast
          title="Upload Complete"
          body="Your file has been successfully uploaded"
          icon="CheckDefault"
          isVisible={t.visible}
          labels={{ close: 'Close', details: 'Details' }}
          onClose={() => toast.dismiss(t.id)}
          accentColor={Colors.orange}
          toastId={t.id}
          updateHeight={handlers.updateHeight}
        >
          <div className="text-b4">
            <p>File: document.pdf</p>
            <p>Size: 2.5 MB</p>
            <p>Uploaded at: {new Date().toLocaleTimeString()}</p>
          </div>
        </AdvancedToast>
      ),
      { duration: Infinity },
    );
  };

  return (
    <>
      <Toaster {...(getHotToastConfig() as ToasterProps)} />
      <button onClick={showToast}>Show Toast</button>
    </>
  );
}

Green Accent (Success)

'use client';

import { AdvancedToast } from '@/ui/AdvancedToast';
import { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';
import { getHotToastConfig } from '@/ui/AdvancedToast.config';
import { Colors } from '@/ui/helpers/colors/colors';

export function AdvancedToastGreenDemo() {
  const { handlers } = useToaster();

  const showToast = () => {
    toast.custom(
      (t) => (
        <AdvancedToast
          title="Success!"
          body="Your changes have been saved successfully"
          icon="CheckDefault"
          isVisible={t.visible}
          labels={{ close: 'Close', details: 'Details' }}
          onClose={() => toast.dismiss(t.id)}
          accentColor={Colors.green}
          toastId={t.id}
          updateHeight={handlers.updateHeight}
        />
      ),
      { duration: Infinity },
    );
  };

  return (
    <>
      <Toaster {...(getHotToastConfig() as ToasterProps)} />
      <button onClick={showToast}>Show Toast</button>
    </>
  );
}

Red Accent (Error)

'use client';

import { AdvancedToast } from '@/ui/AdvancedToast';
import { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';
import { getHotToastConfig } from '@/ui/AdvancedToast.config';
import { Colors } from '@/ui/helpers/colors/colors';

export function AdvancedToastRedDemo() {
  const { handlers } = useToaster();

  const showToast = () => {
    toast.custom(
      (t) => (
        <AdvancedToast
          title="Error"
          body="Something went wrong. Please try again."
          icon="CrossDefault"
          isVisible={t.visible}
          labels={{ close: 'Close', details: 'Details' }}
          onClose={() => toast.dismiss(t.id)}
          accentColor={Colors.red}
          toastId={t.id}
          updateHeight={handlers.updateHeight}
        />
      ),
      { duration: Infinity },
    );
  };

  return (
    <>
      <Toaster {...(getHotToastConfig() as ToasterProps)} />
      <button onClick={showToast}>Show Toast</button>
    </>
  );
}

No Auto-Dismiss

'use client';

import { AdvancedToast } from '@/ui/AdvancedToast';
import { type ToasterProps, Toaster, toast, useToaster } from 'react-hot-toast';
import { getHotToastConfig } from '@/ui/AdvancedToast.config';
import { Colors } from '@/ui/helpers/colors/colors';

export function AdvancedToastNoDismissDemo() {
  const { handlers } = useToaster();

  const showToast = () => {
    toast.custom(
      (t) => (
        <AdvancedToast
          title="Important Notice"
          body="This notification will not auto-dismiss"
          icon="Trident"
          isVisible={t.visible}
          labels={{ close: 'Close', details: 'Details' }}
          onClose={() => toast.dismiss(t.id)}
          accentColor={Colors.orange}
          duration={false}
          toastId={t.id}
          updateHeight={handlers.updateHeight}
        />
      ),
      { duration: Infinity },
    );
  };

  return (
    <>
      <Toaster {...(getHotToastConfig() as ToasterProps)} />
      <button onClick={showToast}>Show Toast</button>
    </>
  );
}

Notes

  • The toast automatically dismisses after the specified duration unless set to false
  • Hovering over the toast pauses the auto-dismiss timer
  • The progress indicator at the bottom shows the remaining time before auto-dismiss
  • When children is provided, a details toggle button appears to expand/collapse additional content
  • The component uses react-hot-toast for toast management
  • The component requires the useCountdown hook for the progress indicator functionality