Approval Card

Asks a person to allow or deny an action before an agent runs it.

Place a reorder?

The agent wants to buy your usual coffee.

orders.create({ item: "ethiopia-guji-250", quantity: 2 })
'use client';

import { useState } from 'react';
import { ApprovalCard } from '@brand-studio/ui';
import type { ApprovalStatus } from '@brand-studio/ui';

export default function ApprovalCardDemo() {
  const [status, setStatus] = useState<ApprovalStatus>('pending');
  return (
    <div style={{ width: '100%', maxWidth: 440 }}>
      <ApprovalCard
        title="Place a reorder?"
        description="The agent wants to buy your usual coffee."
        detail={'orders.create({ item: "ethiopia-guji-250", quantity: 2 })'}
        status={status}
        onApprove={() => setStatus('approved')}
        onReject={() => setStatus('rejected')}
      />
    </div>
  );
}

Installation

pnpm add @brand-studio/ui

Usage

import { ApprovalCard } from '@brand-studio/ui';
<ApprovalCard
  title="Place a reorder?"
  status={status}
  onApprove={() => setStatus('approved')}
  onReject={() => setStatus('rejected')}
/>

Accessibility

  • Deny comes first and Allow is the primary action, so the keyboard reaches the safe choice first.
  • After a decision the buttons give way to the outcome, announced through a live region.

API Reference

PropTypeDefault
titlestring
description?string
detail?React.ReactNode
status?"approved" | "pending" | "rejected"'pending'
onApprove?(() => void)
onReject?(() => void)
approveLabel?string'Allow'
rejectLabel?string'Deny'
className?string''

Still, Deskhand and Hollis are fictional brands. The coffee photographs are original generated artwork. @brand-studio/ui is MIT licensed.