feat(frontend): add ErrorState primitive
This commit is contained in:
@@ -0,0 +1,62 @@
|
|||||||
|
import { AlertCircle } from "lucide-react";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
type ErrorStateProps = {
|
||||||
|
/** All-caps instrument label, defaults to "ERROR". */
|
||||||
|
eyebrow?: string;
|
||||||
|
/** One-line plain-language summary of what went wrong. */
|
||||||
|
message: string;
|
||||||
|
/** Optional secondary detail (e.g. error.message or status code). */
|
||||||
|
detail?: string;
|
||||||
|
/** Optional retry handler — renders an outline "Retry" button. */
|
||||||
|
onRetry?: () => void;
|
||||||
|
className?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error surface state.
|
||||||
|
* Voice: destructive-hairline row with an "ERROR" eyebrow and a one-line
|
||||||
|
* message. No alarm colors — uses the existing --destructive token at low
|
||||||
|
* opacity so the chrome stays the headline.
|
||||||
|
*/
|
||||||
|
export function ErrorState({
|
||||||
|
eyebrow = "ERROR",
|
||||||
|
message,
|
||||||
|
detail,
|
||||||
|
onRetry,
|
||||||
|
className,
|
||||||
|
}: ErrorStateProps) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"surface rounded-xl border border-destructive/30 p-4",
|
||||||
|
"flex items-center gap-3",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
<AlertCircle
|
||||||
|
className="h-4 w-4 text-destructive shrink-0"
|
||||||
|
strokeWidth={1.75}
|
||||||
|
aria-hidden
|
||||||
|
/>
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<div className="text-[10.5px] font-semibold uppercase tracking-[0.18em] text-destructive/80">
|
||||||
|
{eyebrow}
|
||||||
|
</div>
|
||||||
|
<div className="text-sm text-foreground/90 truncate">{message}</div>
|
||||||
|
{detail ? (
|
||||||
|
<div className="text-xs text-muted-foreground truncate mt-0.5">
|
||||||
|
{detail}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
{onRetry ? (
|
||||||
|
<Button variant="outline" size="sm" onClick={onRetry}>
|
||||||
|
Retry
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user