Skip to content
Sign in
CommerceSpend approvalMenu

Spend approvalPro

The agent asks to spend over your limit: what, how far over, why, and a clear approve or decline that expires.

ProThe agent wants $128 against a $100 limit, with its reason and a five minute window.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/spend-approval

Usage

tsx
import { SpendApproval } from "@/components/ui/chatcn/pro/spend-approval"

<SpendApproval
  agent="Shopping agent"
  item={{ title: "Tarn 22 L daypack", merchant: "Northfold Supply" }}
  amount={128}
  limit={100}
  reason="The only waterproof one that arrives before your trip."
  expiresIn={300}
  onApprove={({ raiseLimit }) => wallet.approve(request.id, raiseLimit)}
  onDecline={() => wallet.decline(request.id)}
/>

The limit meter is scaled to the request: the part inside your limit in quiet gray, the overrun hatched in amber, with a tick and label at the limit. The over amount is also written out, so the hatch is never the only signal. The agent's reason sits in a quote in its own words. Approval covers this purchase only; with suggestedLimit, a checkbox raises the limit at the same time. With expiresIn, a countdown runs in the corner and the request lapses on its own, saying nothing was charged. Pass status to drive it from your server instead.

Examples

States

ProApproved, declined, about to expire with a failed approval and expired.

Props

PropTypeNotes
agentstringWho asks. Default "The agent"
item{ title, merchant, image?, detail? }What it wants to buy
amount, limit, suggestedLimitnumberThe request, the limit and an optional raise
currency, localestringPrices format with Intl, tabular figures. Default USD, en-US
reasonReactNodeThe agent's words
expiresIn, onExpirenumber, () => voidSeconds until it lapses
status"pending" | "approving" | "approved" | "declined" | "expired" | "error"Controlled; otherwise it runs itself
onApprove, onDecline({ raiseLimit }) => unknown | Promise<unknown>, () => voidReject to show the error
labelsPartial<SpendApprovalLabels>Every string, for translation

Keyboard

KeyAction
TabThe raise checkbox, Decline, then Approve
Enter or SpacePress the focused button

Accessibility

  • The card is named by its request line, which includes the amount.
  • The countdown is read as Expires in, not as a bare clock.
  • The outcome is a status message; errors are alerts with what to do.

Motion

The outcome line fades up 4 px in 180 ms. The countdown ticks without animation. Reduced motion keeps the fade only.