Enrich column

Pro

An AI enrichment column for a data table, where one prompt runs down every row and each cell shimmers while it works, then settles into a value with its source or a failure you can retry.

Live · keyboard ready
Target accounts7 rows · sample data
Company
Headcount and fundingFind the headcount and latest funding round
Linearlinear.app
Not run
Vercelvercel.com
Not run
Notionnotion.com
Not run
Figmafigma.com
Not run
Stripestripe.com
Not run
Rampramp.com
Not run
Retoolretool.com
Not run
Claude Haiku 5.5 · Web searchNot run yet
  • Enriching a list of companies or leads with facts an agent can look up (headcount, funding, tech stack).
  • Classifying or summarizing rows with one prompt, with a visible source per answer.
  • Showing per-row AI progress with stop, re-run and retry in a CRM, sales tool or internal admin.
  • Large spreadsheets with many columns and editing; use Data grid and add an AI column there.
  • A single question over a dataset; use Ask your data.
  • A log of one agent's tool calls; use Tool call.

Installation

Pro source and install commands unlock with a Pro plan.

example.tsx
import { EnrichColumn } from "@/components/arc/enrich-column/enrich-column"; <EnrichColumn  title="Pipeline"  rows={accounts.map(account => ({ id: account.id, name: account.name, domain: account.domain }))}  defaultColumn={{ name: "Headcount and funding", prompt: "Find the headcount and latest funding round" }}  enrich={async (row, { prompt, signal, setActivity }) => {    setActivity(`Searching for ${row.name}`);    const response = await fetch("/api/enrich", { method: "POST", body: JSON.stringify({ domain: row.domain, prompt }), signal });    if (!response.ok) throw new Error("No source found");    return response.json(); // { value, source: { label, href } }  }}  onCellChange={(row, cell) => cell.status === "done" && save(row.id, cell)}/>

EnrichColumn

A table card with an AI column. One prompt runs down every row; each cell shimmers while it works, then settles into a value with its source, or a failure with a retry. With no props it runs a simulated sample of seven companies.

PropTypeDefaultDescription
titlestring"Target accounts"The table's name in the top bar.
rowsEnrichColumnRow[]seven sample companiesThe rows to enrich: { id, name, domain?, logo? }. Logos render at 16px.
defaultColumn{ name: string; prompt: string }{ name: "Headcount and funding", prompt: "Find the headcount and latest funding round" }The AI column's name and prompt on first render. The person can edit both from the column header.
onColumnChange(column: EnrichColumnDefinition) => void–Called when the person saves an edited column. Saving re-runs every row.
enrich(row, context) => Promise<{ value: string; source?: { label: string; href: string } }>local simulationFills one cell. The context carries prompt, column, an AbortSignal, the attempt number and setActivity(text) for the shimmering label. Reject to mark the cell failed with the error's message.
initialCellsRecord<string, EnrichColumnCell>–Values you already have, keyed by row id, such as cells saved from an earlier run.
concurrencynumber2How many cells run at once. Workers start 140ms apart so the column fills top to bottom.
autoRunbooleantrue with the simulation, false with enrichRuns the column once when it first scrolls into view, if no cell has a value yet.
model{ name: string; detail?: string; mark?: ReactNode } | nullClaude Haiku 5.5, web searchThe model shown in the footer. Pass null to hide it.
editablebooleantrueShows the edit control on the AI column header.
notestring"sample data" with the simulationA short note after the row count.
onCellChange(row: EnrichColumnRow, cell: EnrichColumnCell) => void–Called whenever a cell changes state (queued, running, done, failed). Use it to persist values.
onRunComplete(cells: Record<string, EnrichColumnCell>) => void–Called when a run settles, with every cell.
classNamestring–Class on the root.
Tab
Moves through Run column, the column's edit control, each row's run or retry control and source links. Row controls appear on focus.
EnterorSpace
Runs, stops or re-runs the column, runs one row, or retries a failed cell.
Cmd/Ctrl+Enter
Saves the edited column and re-runs it.
Escape
Closes the column editor without saving and returns focus to the edit control.
  • A real table: the company is a row header and the AI column's name and prompt are its column header.
  • Every cell state pairs an icon with text (Queued, a shimmering activity, the value, Failed with a reason), never color alone.
  • A polite live region announces runs, stops and the final count, and says when values are simulated and nothing was sent.
  • Icon buttons carry labels that name the row (Run Linear, Retry Retool); source links say they open a new tab.
  • Cell swaps are one crossfade in a shared grid cell: old content out in 100ms, new in 160ms with a 2px rise. Nothing changes size.
  • Status icons crossfade with a bounce-free scale; the done tick draws in 240ms; the running label uses a calm text shimmer.
  • The editor opens with a critically damped height spring (240ms, no bounce).
  • Reduced motion keeps every state and cuts travel and the tick draw; the spinner slows down.
  • Fluid up to 760px. Below 560px the domain, source text and model detail fold away; the source keeps its arrow link.
  • Below 440px the gutters tighten to 16px, values wrap to two lines in 60px rows, and failure reasons hide behind the Failed label.
  • On touch screens the row run controls stay visible since there is no hover.
  • Only changed cells re-render visibly; runs are capped by concurrency and every request is abortable.
  • Workers read the latest rows and prompt through refs, so editing mid-run never acts on stale data.
  • Built for tens of rows; for hundreds, virtualize the table body and keep concurrency low.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Use for AI-filled columns in tables of accounts, leads, documents or tickets, where one prompt runs per row.
  • Pass a real enrich function and honor the AbortSignal; throw an Error with a short message to show a failed cell with retry.
  • Persist values with onCellChange and feed them back through initialCells on the next render.
  • Keep values to one short line; the cell truncates with an ellipsis and shows the full value on hover.

The full library index for assistants is at /llms.txt.