Files
Stirling-PDF/frontend/shared/components/EmptyState.tsx
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

52 lines
1.4 KiB
TypeScript
Raw Normal View History

2026-06-02 17:08:24 +01:00
import type { ReactNode } from "react";
import "@shared/components/EmptyState.css";
export interface EmptyStateProps {
/** Eyebrow text shown above the title (e.g. "No pipelines yet"). */
eyebrow?: ReactNode;
/** Headline. */
title: ReactNode;
/** One- or two-line body copy. */
description?: ReactNode;
/** Optional visual at the top (icon, illustration, etc). */
icon?: ReactNode;
/** Primary + secondary CTAs. */
actions?: ReactNode;
/** Visual size. `compact` removes the icon row's padding for inline use. */
size?: "compact" | "default";
className?: string;
}
/**
* Centered "nothing here yet" panel. Replaces the bespoke empty cards inline
* in Pipelines (free tier), NotificationsDropdown (all caught up), and the
* search modal (no matches).
*/
export function EmptyState({
eyebrow,
title,
description,
icon,
actions,
size = "default",
className,
}: EmptyStateProps) {
return (
<div
className={["sui-empty", `sui-empty--${size}`, className ?? ""]
.filter(Boolean)
.join(" ")}
>
{icon && (
<div className="sui-empty__icon" aria-hidden>
{icon}
</div>
)}
{eyebrow && <div className="sui-empty__eyebrow">{eyebrow}</div>}
<h2 className="sui-empty__title">{title}</h2>
{description && <p className="sui-empty__copy">{description}</p>}
{actions && <div className="sui-empty__actions">{actions}</div>}
</div>
);
}