Approval Card
The human-in-the-loop gate: what the agent wants to do, how risky it is, approve or reject.
Usage
Send 14 payment reminders
Medium riskEmails the contact on every invoice more than 30 days overdue. Nothing is charged.
Installation
npm install @wunderui/reactThen import what you need:
import { ApprovalCard } from "@wunderui/react"Examples
Inline, low risk
The default: what will run sits behind a disclosure.
Publish the changelog entry
Low riskPushes the 0.2.0 notes to the docs site. Nothing else changes.
Dialog with a diff
kind="dialog-diff" shows the edit directly and offers Allow once, Always allow or Reject.
Apply 1 file edit
Medium riskSwitch TabsList to roving focus so arrow keys move between tabs.
return <div role="tablist" {...props} /> const ref = useRovingFocus() return ( <div ref={ref} role="tablist" {...props} /> )Permission request in an approval
An Approval Card of kind permission: the scopes and their countdown live in a ScopeList.
Access the WunderUI repository
Medium riskNeeded to sync tokens from Figma and open a pull request.
Requested access
Expires in- Read the docs siteapps/docs · 412 files
- Write tokenspackages/react/src/styles.css
- Open a pull requestKl-webmedia/wunderui · branch tokens-sync
High cost
kind="high-cost" adds an amber banner with the estimate and the budget, and a cheaper alternative.
Render 1,240 screenshots
High riskThis run renders every block in light, dark and mobile before the release.
Estimated $18.40 · run budget $10.00
About 3× the usual release run. Rendering 400 screenshots stays within budget.
In context
How the component is used inside real screens — the same compositions as the Usage section of the Figma page.
Budget & recovery
Spend, a failed run and an approval request side by side.
Spend today
$10 budget
$8.60
Rate limit exceeded.
Draft the follow-up email· Attempt 2 of 3Send 12 emails
High riskTemplated follow-up to at-risk customers.
API Reference
| Prop | Type | Default |
|---|---|---|
| title | ReactNode | — |
| summary | ReactNode | — |
| preview | ReactNode | — |
| risk | "low" | "medium" | "high" | "medium" |
| requestedAt | ReactNode | — |
| expiresAt | Date | string | number | — |
| state | "pending" | "approved" | "rejected" | "expired" | uncontrolled |
| kind | "inline" | "dialog-diff" | "permission" | "high-cost" | "inline" |
| cost | { estimate: ReactNode; budget?: ReactNode; note?: ReactNode } | — |
| approveLabel / rejectLabel | string | per kind |
| secondaryAction | { label: string; onClick?: () => void } | — |
| onApprove / onReject / onEdit | () => void | — |