From 511230ec04f2d7deaae7f5f9033fe2bbf08264d9 Mon Sep 17 00:00:00 2001 From: Tyler Date: Fri, 19 Jun 2026 19:36:22 -0600 Subject: [PATCH] feat(frontend): add ErrorState primitive --- src/components/ui/error-state.tsx | 62 +++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/components/ui/error-state.tsx diff --git a/src/components/ui/error-state.tsx b/src/components/ui/error-state.tsx new file mode 100644 index 0000000..1f27165 --- /dev/null +++ b/src/components/ui/error-state.tsx @@ -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 ( +
+ +
+
+ {eyebrow} +
+
{message}
+ {detail ? ( +
+ {detail} +
+ ) : null} +
+ {onRetry ? ( + + ) : null} +
+ ); +}