Approval Card
spectrumui/approval-cardFreeBlock
A human-in-the-loop approval for an action an agent wants to take.
Install it
npx shadcn@latest add https://ui.spectrumhq.in/r/approval-card.jsonSource
1'use client';23import { useState } from 'react';4import { Check, X } from 'lucide-react';5import { cn } from '@/lib/utils';67const KEYFRAMES = `8@keyframes su-pop { 0% { opacity: 0; transform: scale(0.85) } 100% { opacity: 1; transform: none } }9@keyframes su-msg-in { from { opacity: 0; transform: translateY(6px) } to { opacity: 1; transform: none } }10`;1112export type ApprovalDecision = 'approved' | 'rejected';1314export interface ApprovalCardProps {15 title?: string;16 description?: string;17 meta?: string;18 approveLabel?: string;19 rejectLabel?: string;20 decision?: ApprovalDecision | null;21 onDecide?: (decision: ApprovalDecision) => void;22 className?: string;23}2425export function ApprovalCard({26 title = 'Send carrier notice?',27 description = 'A formal SLA-breach notice to Meridian Lines for the Rotterdam–Felixstowe lane, citing 2.3 days over contracted transit.',28 meta = 'drafted by agent · draft_carrier_notice',29 approveLabel = 'Approve & send',30 rejectLabel = 'Dismiss',31 decision: decisionProp,32 onDecide,33 className,34}: ApprovalCardProps) {35 const [decisionState, setDecisionState] = useState<ApprovalDecision | null>(null);36 const decision = decisionProp !== undefined ? decisionProp : decisionState;3738 function decide(next: ApprovalDecision) {39 setDecisionState(next);40 onDecide?.(next);41 }4243 return (44 <div45 className={cn(46 'w-full max-w-[420px] rounded-2xl border border-black/[0.08] bg-white p-4 shadow-xs dark:border-white/[0.09] dark:bg-[#0B0B0D]',47 className,48 )}49 >50 <style dangerouslySetInnerHTML={{ __html: KEYFRAMES }} />5152 {decision ? (53 <div className="flex flex-col items-center py-4 text-center motion-safe:animate-[su-msg-in_240ms_cubic-bezier(0.23,1,0.32,1)_both]">54 <span55 className={cn(56 'grid size-8 place-items-center rounded-full motion-safe:animate-[su-pop_200ms_cubic-bezier(0.23,1,0.32,1)_both]',57 decision === 'approved'58 ? 'bg-emerald-500/15 text-emerald-600 dark:text-emerald-400'59 : 'bg-neutral-500/10 text-neutral-500 dark:text-neutral-400',60 )}61 >62 {decision === 'approved' ? (63 <Check className="size-4" strokeWidth={2.5} />64 ) : (65 <X className="size-4" strokeWidth={2.5} />66 )}67 </span>68 <p className="mt-2.5 text-[13.5px] font-medium text-neutral-900 dark:text-neutral-50">69// … truncated
What it pulls in
npm packages
Files it writes
More from spectrumui
All 182 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Agent Planagent-plan | spectrumui | Blocks | Free | 1 dep | |
| Agent Stepsagent-steps | spectrumui | Blocks | Free | 1 dep · 2 files | |
| Chat Empty Statechat-empty-state | spectrumui | Blocks | Free | 1 dep · 2 files | |
| Citation Sourcescitation-sources | spectrumui | Blocks | Free | no deps · 2 files | |
| Code Blockcode-block | spectrumui | Blocks | Free | 1 dep | |
| Conversation Listconversation-list | spectrumui | Blocks | Free | 1 dep | |
| Diff Viewdiff-view | spectrumui | Blocks | Free | 1 dep | |
| Error Stateerror-state | spectrumui | Blocks | Free | 1 dep |
