import type { StatusType } from "@openstatus/ui/components/blocks/status.types";
import { cn } from "@openstatus/ui/lib/utils";
import {
AlertCircleIcon,
CheckIcon,
TriangleAlertIcon,
WrenchIcon,
} from "lucide-react";
interface StatusIconProps extends React.ComponentProps<"div"> {
/**
* The status type to display
*/
status?: StatusType;
/**
* The variant determines the CSS selector pattern used for status-based styling
* - "default": Uses group-data-[variant=...] (for Status component)
* - "banner": Uses group-data-[status=...]/status-banner (for StatusBanner component)
* - "component": Uses group-data-[variant=...]/component (for StatusComponent)
*/
variant?: "default" | "banner" | "component";
}
/**
* StatusIcon - A unified icon component for displaying status indicators
*
* This component renders the appropriate icon based on the status type:
* - success: CheckIcon
* - degraded: TriangleAlertIcon
* - error: AlertCircleIcon
* - info: WrenchIcon
* - empty: No icon (muted background)
*
* @example
* // In Status component context
*
*
* @example
* // In StatusBanner context
*
*
* @example
* // In StatusComponent context
*
*/
export function StatusIcon({
className,
variant = "default",
status,
...props
}: StatusIconProps) {
// Define size classes based on variant
const sizeClasses =
variant === "component"
? "size-[12.5px] [&>svg]:size-[9px]"
: "size-7 [&>svg]:size-4";
// Define status-based classes based on variant
const statusClasses = (() => {
switch (variant) {
case "banner":
return [
"group-data-[status=success]/status-banner:bg-success",
"group-data-[status=degraded]/status-banner:bg-warning",
"group-data-[status=error]/status-banner:bg-destructive",
"group-data-[status=info]/status-banner:bg-info",
];
case "component":
return [
"group-data-[variant=success]/component:bg-success",
"group-data-[variant=degraded]/component:bg-warning",
"group-data-[variant=error]/component:bg-destructive",
"group-data-[variant=info]/component:bg-info",
];
case "default":
default:
return [
"group-data-[variant=success]:bg-success",
"group-data-[variant=degraded]:bg-warning",
"group-data-[variant=error]:bg-destructive",
"group-data-[variant=info]:bg-info",
];
}
})();
// Define icon visibility classes based on variant
const iconVisibilityClasses = (() => {
switch (variant) {
case "banner":
return {
success: "group-data-[status=success]/status-banner:block",
degraded: "group-data-[status=degraded]/status-banner:block",
error: "group-data-[status=error]/status-banner:block",
info: "group-data-[status=info]/status-banner:block",
};
case "component":
return {
success: "group-data-[variant=success]/component:block",
degraded: "group-data-[variant=degraded]/component:block",
error: "group-data-[variant=error]/component:block",
info: "group-data-[variant=info]/component:block",
};
case "default":
default:
return {
success: "group-data-[variant=success]:block",
degraded: "group-data-[variant=degraded]:block",
error: "group-data-[variant=error]:block",
info: "group-data-[variant=info]:block",
};
}
})();
return (
);
}