{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "approval-card",
  "title": "Approval card",
  "description": "consent before consequence · says what changes and whether it can be undone",
  "dependencies": [
    "cn@^0.4.0",
    "lucide-react@^1.52.0"
  ],
  "registryDependencies": [
    "@kit/button"
  ],
  "files": [
    {
      "path": "components/kit/approval-card.tsx",
      "content": "'use client';\nimport { ShieldAlertIcon } from 'lucide-react';\nimport { cn } from 'cn';\nimport * as React from 'react';\nimport { Button } from '@/components/ui/button';\n\ntype Props = {\n  /** The action, as a sentence the person can say yes to: \"Refund £48.00 to Alex Morgan\". */\n  title: string;\n  /** The consequence: what changes, and whether it can be undone. */\n  description?: string;\n  /** Read-only details that matter for the decision. */\n  details?: { label: string; value: string }[];\n  onApprove: () => void;\n  onDeny: () => void;\n  approveLabel?: string;\n  denyLabel?: string;\n  className?: string;\n};\n\n/**\n * Consent before consequence: the assistant asks before it does something irreversible or costly. Once\n * answered it shows the decision instead of the buttons.\n */\nexport function ApprovalCard({ title, description, details, onApprove, onDeny, approveLabel = 'Approve', denyLabel = 'Not now', className }: Props) {\n  const [decision, setDecision] = React.useState<'approved' | 'denied' | null>(null);\n  return (\n    <div className={cn('border-warning/40 bg-warning/10 flex flex-col gap-3 rounded-xl border p-4', className)}>\n      <div className=\"flex gap-3\">\n        <ShieldAlertIcon className=\"text-warning mt-0.5 size-5 shrink-0\" aria-hidden />\n        <div className=\"flex flex-col gap-1\">\n          <p className=\"font-semibold\">{title}</p>\n          {description ? <p className=\"text-muted-foreground text-sm\">{description}</p> : null}\n        </div>\n      </div>\n      {details?.length ? (\n        <dl className=\"bg-card grid gap-x-4 gap-y-1 rounded-lg p-3 text-sm sm:grid-cols-[auto_1fr]\">\n          {details.map((d) => (\n            <React.Fragment key={d.label}>\n              <dt className=\"text-muted-foreground\">{d.label}</dt>\n              <dd className=\"font-medium\">{d.value}</dd>\n            </React.Fragment>\n          ))}\n        </dl>\n      ) : null}\n      {decision ? (\n        <p role=\"status\" className=\"text-sm font-medium\">\n          {decision === 'approved' ? 'Approved. The assistant will go ahead.' : 'Declined. Nothing was changed.'}\n        </p>\n      ) : (\n        <div className=\"flex flex-wrap gap-2\">\n          <Button\n            size=\"sm\"\n            onClick={() => {\n              setDecision('approved');\n              onApprove();\n            }}>\n            {approveLabel}\n          </Button>\n          <Button\n            size=\"sm\"\n            variant=\"outline\"\n            onClick={() => {\n              setDecision('denied');\n              onDeny();\n            }}>\n            {denyLabel}\n          </Button>\n        </div>\n      )}\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/kit/approval-card.tsx"
    }
  ],
  "meta": {
    "exports": [
      "ApprovalCard"
    ],
    "api": "<ApprovalCard title description? details? onApprove onDeny />"
  },
  "docs": "Needs the kit theme (`@kit/theme`) and a next-themes ThemeProvider (attribute=\"class\") at the root.",
  "categories": [
    "ai"
  ],
  "type": "registry:component"
}