ComponentsAgent patterns

Review Card

Asks someone to review a proposed change in chat before it happens. The header names the change and its status and opens or closes the details. The footer holds the outcome and the decision buttons.ReviewRows, ReviewSteps, andReviewValues lay out what will change.

ChangeDraft statusValues

Needs approval
Change
Updates an existing row
Table
Supplier deliveries
Supplier
Northwind TradersCurrently Northwind Traders
Delivery date
14 Nov 2026Currently 7 Nov 2026
Status
DelayedCurrently On track
Notes
Carrier confirmed a one-week delay on the October order.Currently —

This chat used content from outside your tables, such as web pages, knowledge, files or connected apps, so the change waits for your approval. Approving makes this exact change with your table access.

Usage

A row change waiting for approvalTSX
import { Database } from "reicon-react/icons/Database";
import {
  ReviewCard,
  ReviewRow,
  ReviewRows,
} from "@tulipfarm/sprout/review-card";

<ReviewCard
  label="Review row change"
  icon={<Database size={16} />}
  title="Update a row in Supplier deliveries"
  badge={{ label: "Needs approval", variant: "warning" }}
  settled={status !== "pending"}
  actions={
    <>
      <Button onClick={approve}>Approve change</Button>
      <Button variant="ghost" onClick={dismiss}>Dismiss</Button>
    </>
  }
  status={<p role="status">{outcome}</p>}
>
  <ReviewRows>
    <ReviewRow label="Change">Updates an existing row</ReviewRow>
    <ReviewRow label="Table">Supplier deliveries</ReviewRow>
  </ReviewRows>
</ReviewCard>

  • icon: a 14 or 16px icon shown in a tile before the title.
  • badge: { label, variant }. The variant is "warning", "info","success", "secondary","destructive", "default", or"outline".
  • settled: the decision is made. The card folds to its header and footer, and folds again each time settledturns true. It opens again when settled turns false.
  • status: footer content that stays visible when folded, such as the outcome, feedback, or a status check.
  • actions: decision buttons. They show only while the card is open.
  • label: names the card, such as “Review row change”. Without it the title names the card.

Badge variants

Badge variantsEach card starts folded; click a header to open it

Needs approval

Awaiting your review

Active

Draft

Not applied

Ready for your approval

Partially completed

Long titles end with an ellipsis; the badge and chevron keep their place.

Approval

An action that waits for approval. While submitting, both buttons are disabled and the chosen one shows a spinner. When settled, the card folds and focus moves to the outcome if the decision was made here.

ApprovalApprove or decline changes local state only
Approval stateLocked

Approval required

The agent wants to post this reply with your Slack account.

App
Slack
Channel
#supplier-updates
Posts as
Your Slack account
Message
Thanks, Northwind. We’ve moved the October delivery to 14 November and updated the tracker.

Drafts

Workflow, agent, and skill drafts share one card. Agent drafts list the change, team, model, actions, and skills; long instructions keep their line breaks. Feedback, technical details, and a status check sit below.

Workflow, agent, and skill draftsDecisions change local state only
DraftAuthoring statusFeedback

Draft
Change
Updates existing agent “Supplier follow-up”
Changed fields
Instructions, Tools, Model family

Each Monday, check the Supplier deliveries table for late orders. Email each late supplier a polite reminder and post a summary in #supplier-updates.

Team
Operations
Model
Claude Sonnet
Actions
  • Read Gmail
  • Send Gmail
  • Read Slack
  • Post to Slack
  • Read GitHub issues

2 actions change data.

Skills
  • Summarize meeting notes
  • Built-in skill: web-research

Saving does not activate these changes. An agent manager must activate the exact saved revision separately.

Agent setup

Three decisions, with activation disabled until each consent box is checked. A sponsor conflict shows as an alert.

Agent setupActivation waits for both consent boxes
Setup status

Draft

Updates the existing agent. The earlier active setup remains until this replacement succeeds.

Team
Operations
Schedule 1
Every Monday at 9:00 (Asia/Kolkata)
Schedule 2
Every day at 17:30 (Europe/London)
Slack channel 1
#supplier-updates

Only this review action can save or activate the setup. Chat text is not approval.

Workflow steps

ReviewSteps numbers each step. A step’sdetail can hold ReviewValues, code, or notes.

Steps with exact valuesTSX
<ReviewSteps
  title="3 steps"
  steps={[
    {
      summary: "notify api: send POST to https://hooks.example.com/suppliers",
      detail: (
        <ReviewValues
          values={[
            { name: "content-type", value: "application/json" },
            { name: "Body", value: body },
          ]}
        />
      ),
    },
    { summary: "pause: wait 3600 seconds" },
  ]}
/>

Workflow detailsTrigger rows, then every step kind
Trigger

Draft
Change
Creates a new workflow. It stays inactive.
Trigger
When a row of “Supplier deliveries” is updated. Run input holds the row ID and its values before and after the change
Watched fields
“Status”, “Delivery date”
Only rows where
“Status” is “Delayed”
Next run
Within about a minute of each matching change
12 steps
  1. find late: find up to 50 rows in “Supplier deliveries” matching 2 conditions

    “Status”
    is “Delayed”
    “Delivery date”
    before {{ trigger.date }}
  2. check count: check whether {{ steps.find_late.count }} is greater than 0

    If it holds
    run draft reply, post summary
    Otherwise
    skip draft reply, post summary
  3. draft reply: ask Supplier follow-up to write a reminder for each late supplier

    Limits: 40 tool calls, 120 seconds, 25 Credits.

  4. shape: set subject, owner

    subject
    Delivery reminder: {{ row.supplier }}
    owner
    {{ trigger.requester }}
  5. notify api: send POST to https://hooks.example.com/suppliers

    content-type
    application/json
    x-shop-id
    northwind-eu
    Body
    { "supplier": "{{ row.supplier }}", "status": "delayed" }
  6. score: run JavaScript code with {{ steps.find_late.rows }}

    score.js
    export default (rows) =>
      rows.filter((row) => row.daysLate > 3).length;
  7. log result: add a row to “Follow-up log”, writing 2 fields

    “Supplier”
    {{ row.supplier }}
    “Sent at”
    {{ now }}
  8. mark sent: update the row in {{ trigger.row }} in “Supplier deliveries”, writing 1 field

    unavailable field (fld_93a1)
    Reminder sent
  9. approve: ask for a response. “Should we escalate suppliers more than two weeks late?”

  10. pause: wait 3600 seconds

  11. follow up: wait until the time in {{ trigger.row.delivery_date }}

  12. post summary: send a Slack message

    #supplier-updates · Slack workspace T024BE7LD

    Channel C061EG9SL

    Destination ID: dst_6f2b91e0

    Message
    {{ steps.find_late.count }} suppliers are late this week.
    Posts as
    TulipFarm app

    Saving this workflow does not approve a send. Each run asks its requester or sponsor to approve the exact message. Approval expires after 24 hours.

Without actions

A table proposal whose values expired. It has no actions, only a status check, and scrolls inside a bounded area.

Expired table proposalBounded to 16rem and scrolls inside chat
Proposal status

Partially completed

History values expired. Proposal values were permanently removed on 2 October 2026, 18:42.

The original digest and execution outcomes remain available. Ask for a new proposal to make further changes.

  • Table 1: completed. 1,284 of 1,500 rows imported. 216 not yet imported.
  • Table 2: Not completed

e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Composition

Rows, steps, and valuesThe plain parts together, open and settled

Needs review
Owner
Alex Meadow
Status
Draft
Changes
  1. Create a planting list

    Plant
    Tulip
    Quantity
    12
  2. Assign watering to Robin

No review action taken.

Accepted

Accessibility

The card is a section named by label or the title. The title is an h4 holding the button that opens and closes the details, with aria-expanded; the whole header is its click target, and its focus ring outlines the header. Enter and Space toggle it. The icon and chevron are hidden from assistive tech. Rows and values are description lists; steps are an ordered list under an h5, with the numbers hidden so screen readers use the list order.

The details grow and shrink in 180ms and the chevron turns in 120ms; with reduced motion both happen at once.

Theme tokens

The card uses --sprout-surface,--sprout-line, --sprout-canvas for the icon tile,--sprout-hover, --sprout-focus,--sprout-muted, and --sprout-secondary for step numbers. Badges use the Badge tokens.