Command Palette

Search for a command to run...

54
Components
PreviousNext

Status Indicator

A toast notification that displays animated status transitions using Sonner.

Loading...
"use client";
 
import { TbCloudUpload, TbCreditCard, TbSend } from "react-icons/tb";
 
import { showStatusIndicator } from "@/components/jyotirmoydas/status-indicator";
 
/**
 * Basic Status Indicator Demo
 * Shows the core functionality with default styling
 */
export function StatusIndicatorDemo01() {
  const handlePayment = () => {
    showStatusIndicator({
      icon: <TbCreditCard strokeWidth={2.5} className="size-5" />,
      label: "Pay $49.99",
      text: {
        loading: "Processing Payment",
        success: "Payment Complete",
        error: "Payment Failed",
      },
    });
  };
 
  const handleSendMessage = () => {
    showStatusIndicator({
      icon: <TbSend strokeWidth={2.5} className="size-5" />,
      label: "Send Message",
      text: {
        loading: "Sending Message",
        success: "Message Sent",
        error: "Send Failed",
      },
      simulationDuration: 1500,
      successRate: 0.9,
    });
  };
 
  const handleUpload = () => {
    showStatusIndicator({
      icon: <TbCloudUpload strokeWidth={2.5} className="size-5" />,
      label: "Upload Files",
      text: {
        loading: "Uploading Files",
        success: "Upload Complete",
        error: "Upload Failed",
      },
      simulationDuration: 2500,
      successRate: 0.8,
    });
  };
 
  return (
    <div className="flex flex-col items-center gap-6 py-8">
      <p className="text-sm text-muted-foreground">
        Click to trigger Status Indicator toast
      </p>
 
      <div className="flex flex-wrap items-center justify-center gap-3">
        <button
          onClick={handlePayment}
          className="flex items-center gap-2 rounded-full border border-border bg-secondary px-5 py-2.5 text-sm font-medium text-secondary-foreground transition-colors hover:bg-accent active:scale-95"
        >
          <TbCreditCard className="size-4" />
          Pay $49.99
        </button>
 
        <button
          onClick={handleSendMessage}
          className="flex items-center gap-2 rounded-full border border-border bg-secondary px-5 py-2.5 text-sm font-medium text-secondary-foreground transition-colors hover:bg-accent active:scale-95"
        >
          <TbSend className="size-4" />
          Send Message
        </button>
 
        <button
          onClick={handleUpload}
          className="flex items-center gap-2 rounded-full border border-border bg-secondary px-5 py-2.5 text-sm font-medium text-secondary-foreground transition-colors hover:bg-accent active:scale-95"
        >
          <TbCloudUpload className="size-4" />
          Upload Files
        </button>
      </div>
    </div>
  );
}

Features

  • Toast notification: Shows Status Button as a Sonner toast
  • Animated states: Loading → Success/Error with smooth transitions
  • Auto-dismiss: Automatically dismisses after completion
  • 6 color presets: Default, Primary, Secondary, Success, Warning, Danger
  • 5 radius options: None, Small, Medium, Large, Full
  • Custom colors: Use any Tailwind classes
  • Helper function: Simple showStatusIndicator() API

Colors

Loading...
"use client";
 
import { TbCreditCard } from "react-icons/tb";
 
import { cn } from "@/lib/utils";
import type { StatusButtonColor } from "@/components/jyotirmoydas/status-button";
import { showStatusIndicator } from "@/components/jyotirmoydas/status-indicator";
 
const colors: { value: StatusButtonColor; label: string }[] = [
  { value: "default", label: "Default" },
  { value: "primary", label: "Primary" },
  { value: "secondary", label: "Secondary" },
  { value: "success", label: "Success" },
  { value: "warning", label: "Warning" },
  { value: "danger", label: "Danger" },
];
 
const colorClasses: Record<StatusButtonColor, string> = {
  default: "border-gray-300 bg-gray-100 text-gray-700",
  primary: "border-blue-300 bg-blue-100 text-blue-700",
  secondary: "border-purple-300 bg-purple-100 text-purple-700",
  success: "border-green-300 bg-green-100 text-green-700",
  warning: "border-amber-300 bg-amber-100 text-amber-700",
  danger: "border-rose-300 bg-rose-100 text-rose-700",
};
 
/**
 * Color Variants Demo
 * Shows all 6 color presets
 */
export function StatusIndicatorDemo02() {
  const triggerWithColor = (color: StatusButtonColor) => {
    showStatusIndicator({
      icon: <TbCreditCard strokeWidth={2.5} className="size-5" />,
      label: `${color.charAt(0).toUpperCase() + color.slice(1)} Color`,
      text: {
        loading: "Processing...",
        success: "Success!",
        error: "Failed!",
      },
      color,
      simulationDuration: 1500,
    });
  };
 
  return (
    <div className="flex flex-col items-center gap-6 py-8">
      <p className="text-sm text-muted-foreground">Click to see each color</p>
 
      <div className="flex flex-wrap items-center justify-center gap-2">
        {colors.map((item) => (
          <button
            key={item.value}
            onClick={() => triggerWithColor(item.value)}
            className={cn(
              "rounded-full border px-4 py-2 text-sm font-medium transition-colors active:scale-95",
              colorClasses[item.value]
            )}
          >
            {item.label}
          </button>
        ))}
      </div>
    </div>
  );
}

Radius

Loading...
"use client";
 
import { TbSend } from "react-icons/tb";
 
import { cn } from "@/lib/utils";
import type { StatusButtonRadius } from "@/components/jyotirmoydas/status-button";
import { showStatusIndicator } from "@/components/jyotirmoydas/status-indicator";
 
const radiusOptions: { value: StatusButtonRadius; label: string }[] = [
  { value: "none", label: "None" },
  { value: "sm", label: "Small" },
  { value: "md", label: "Medium" },
  { value: "lg", label: "Large" },
  { value: "full", label: "Full" },
];
 
/**
 * Radius Variants Demo
 * Shows all 5 border radius options
 */
export function StatusIndicatorDemo03() {
  const triggerWithRadius = (radius: StatusButtonRadius) => {
    showStatusIndicator({
      icon: <TbSend strokeWidth={2.5} className="size-5" />,
      label: `Radius: ${radius}`,
      text: {
        loading: "Loading...",
        success: "Done!",
        error: "Error!",
      },
      radius,
      simulationDuration: 1500,
    });
  };
 
  return (
    <div className="flex flex-col items-center gap-6 py-8">
      <p className="text-sm text-muted-foreground">
        Click to see each border radius
      </p>
 
      <div className="flex flex-wrap items-center justify-center gap-2">
        {radiusOptions.map((item) => (
          <button
            key={item.value}
            onClick={() => triggerWithRadius(item.value)}
            className={cn(
              "border border-border bg-secondary px-4 py-2 text-sm font-medium text-secondary-foreground transition-colors hover:bg-accent active:scale-95",
              item.value === "none" && "rounded-none",
              item.value === "sm" && "rounded-lg",
              item.value === "md" && "rounded-xl",
              item.value === "lg" && "rounded-2xl",
              item.value === "full" && "rounded-full"
            )}
          >
            {item.label}
          </button>
        ))}
      </div>
    </div>
  );
}

Custom Colors

Loading...
"use client";
 
import { TbDownload, TbHeart, TbShoppingCart } from "react-icons/tb";
 
import { showStatusIndicator } from "@/components/jyotirmoydas/status-indicator";
 
/**
 * Custom Colors Demo
 * Shows how to use any custom Tailwind classes
 */
export function StatusIndicatorDemo04() {
  const handleAddToCart = () => {
    showStatusIndicator({
      icon: <TbShoppingCart strokeWidth={2.5} className="size-5" />,
      label: "Add to Cart",
      text: {
        loading: "Adding to Cart",
        success: "Added to Cart",
        error: "Failed to Add",
      },
      colors: {
        loading: "bg-indigo-100 text-indigo-600",
        success: "bg-teal-100 text-teal-600",
        error: "bg-orange-100 text-orange-600",
      },
    });
  };
 
  const handleDownload = () => {
    showStatusIndicator({
      icon: <TbDownload strokeWidth={2.5} className="size-5" />,
      label: "Download",
      text: {
        loading: "Downloading...",
        success: "Downloaded!",
        error: "Download Failed",
      },
      colors: {
        loading: "bg-cyan-100 text-cyan-600",
        success: "bg-emerald-100 text-emerald-600",
        error: "bg-red-100 text-red-600",
      },
    });
  };
 
  const handleLike = () => {
    showStatusIndicator({
      icon: <TbHeart strokeWidth={2.5} className="size-5" />,
      label: "Like",
      text: {
        loading: "Liking...",
        success: "Liked!",
        error: "Failed",
      },
      colors: {
        loading: "bg-pink-100 text-pink-500",
        success: "bg-pink-100 text-pink-600",
        error: "bg-gray-100 text-gray-500",
      },
      successRate: 1, // Always succeeds
    });
  };
 
  return (
    <div className="flex flex-col items-center gap-6 py-8">
      <p className="text-sm text-muted-foreground">
        Custom Tailwind classes for any color
      </p>
 
      <div className="flex flex-wrap items-center justify-center gap-3">
        <button
          onClick={handleAddToCart}
          className="flex items-center gap-2 rounded-full border border-indigo-200 bg-indigo-50 px-5 py-2.5 text-sm font-medium text-indigo-600 transition-colors hover:bg-indigo-100 active:scale-95"
        >
          <TbShoppingCart className="size-4" />
          Indigo Theme
        </button>
 
        <button
          onClick={handleDownload}
          className="flex items-center gap-2 rounded-full border border-cyan-200 bg-cyan-50 px-5 py-2.5 text-sm font-medium text-cyan-600 transition-colors hover:bg-cyan-100 active:scale-95"
        >
          <TbDownload className="size-4" />
          Cyan Theme
        </button>
 
        <button
          onClick={handleLike}
          className="flex items-center gap-2 rounded-full border border-pink-200 bg-pink-50 px-5 py-2.5 text-sm font-medium text-pink-600 transition-colors hover:bg-pink-100 active:scale-95"
        >
          <TbHeart className="size-4" />
          Pink Theme
        </button>
      </div>
 
      <p className="max-w-sm text-center text-xs text-muted-foreground">
        Use the <code className="text-foreground">colors</code> prop with any
        Tailwind classes
      </p>
    </div>
  );
}

Installation

bunx --bun shadcn@latest add "https://jyotimoydas.in/r/status-indicator.json"

Usage

import { showStatusIndicator } from "@/registry/status-indicator";
import { TbCreditCard } from "react-icons/tb";
 
function PaymentButton() {
  const handlePayment = () => {
    showStatusIndicator({
      icon: <TbCreditCard className="size-5" />,
      label: "Pay $49.99",
      text: {
        loading: "Processing Payment",
        success: "Payment Complete",
        error: "Payment Failed",
      },
      onComplete: (success) => {
        if (success) {
          // Handle success
        }
      },
    });
  };
 
  return <button onClick={handlePayment}>Pay Now</button>;
}

API

showStatusIndicator(options)

Shows a status indicator toast and returns the toast ID.

OptionTypeDefaultDescription
iconReactNodeRequiredIcon to display
labelstringRequiredButton label text
text{ loading; success; error }RequiredState text
color"default" | "primary" | "secondary" | "success" | "warning" | "danger""default"Color preset
radius"none" | "sm" | "md" | "lg" | "full""full"Border radius
colors{ loading?; success?; error? }-Custom Tailwind classes per state
classNamestring-Additional CSS classes
styleCSSProperties-Inline styles
simulationDurationnumber2000Duration before resolving (ms)
successRatenumber0.7Probability of success (0-1)
onComplete(success: boolean) => void-Completion callback
positionstring"top-center"Toast position
dismissDelaynumber2000Delay before auto-dismiss (ms)

dismissStatusIndicator(id)

Manually dismiss a status indicator by ID.

Credits

Based on Status Button and Sonner.