Action receipt
Records what an agent did.
Result
- Refunded $48.00 on order 4812Done
donedefault
- Refunded order 4812Done
steps
- Refunded order 4812Partly done
partial
- Refund on order 4812 failedFailed
failed
States
- Refunded $48.00 on order 4812Done
undo open
- Refunded $48.00 on order 4812Done
undoing
- UndoneRefunded $48.00 on order 4812Undone
undone
- Refunded $48.00 on order 4812Done
window passed
Usage
When to use it
- Use
- An agent finished an action that changed something outside the thread: a refund, an email sent, a deploy.
- Use
- Several changes from one request that should read as one record (steps).
- Use
- An action that can be reversed for a while.
- Not for
- A step while the agent is still working. Use Tool call.
- Not for
- Asking before the action runs. Use Tool call.
- Not for
- An answer that changed nothing. Use Message.
- Not for
- A short note that something saved. Use Toast.
Rules
7 rules
- Must
- Write title and each step label in the past tense with the object and amount. Because the receipt is the record after the fact, and "Refunding" claims nothing happened.
- Must
- Pass onUndo with undoUntil set to the last moment the undo works; never leave Undo up past it. Because Undo leaves on its own at undoUntil, and an Undo that fails after the window breaks the one promise the receipt makes.
- Must
- Set undoing while the undo runs and undone when it lands. Because undoing holds Undo pending so it cannot run twice, and undone swaps the result for Undone and greys the steps.
- Must
- Set result="partial" and mark the failed steps with failed and the reason in detail; keep the steps that worked. Because dropping the steps that worked hides changes that did happen, and only detail says why one failed.
- Should
- Put an ID in a step's detail inside <code>, so it takes mono at 0.8.
- Never
- Make Undo a glass button or add a second action beside it. Because reversing is not the next step the receipt leads to, and the footer holds meta and at most one quiet action.
- Never
- Wrap the receipt in another Card or panel. Because it is a card already, and a card in a card is a box in a box.
State order
4 states, highest first
- 1
- undone
- 2
- undoing
- 3
- window passed
- 4
- undo open
Accessibility
4 checks
- role="group" named by the title.
- The result is a word, never colour alone; each step reads its own word (Done, Failed, Undone) before the label.
- A polite status region says Undone when the undo lands.
- Undo keeps focus while pending and announces busy.
Keyboard
2 keys
- Tab
- Reaches the time's hint, then Undo.
- Enter, Space
- Undoes.
Edge cases
6 edge cases
- Window passes while open
- Undo leaves at that moment; the meta stays.
- Undo running at the deadline
- Undo stays pending until undone or the call settles.
- Failed result
- No Undo: nothing changed.
- Long title
- Wraps; the result word keeps the first line.
- Long step
- The label truncates, the detail truncates first.
- No time and no Undo
- No footer; the card is the panel alone.
API
8 props
titleReactNodesteps{label, detail?, failed?}[]result'done' | 'partial' | 'failed'default'done'at, nowDate | string | numberbyReactNodeonUndo, undoUntil() => void, Date | string | numberundoing, undonebooleandefaultfalselabels{done?, partial?, failed?, undone?, undo?, undoing?}defaultEnglish words
Tokens
16 tokens
--shell- #f1f1f0
--paper- #ffffff
--line-faint- rgb(5 5 5 / 0.06)
--text-1- rgb(5 5 5 / 0.80)
--text-2- rgb(5 5 5 / 0.60)
--text-3- rgb(5 5 5 / 0.45)
--ok-text- #1a7640
--warn-text- #8a5a00
--fail-text- #b23c29
--menu-row-sm- 28px
--radius-shell- 14px
--radius-panel- 11px
--shell-inset- 3px
--type-label- 500 13px/1.35 var(--font-sans)
--type-body-sm- 400 13px/1.5 var(--font-sans)
--type-caption- 400 12px/1.35 var(--font-sans)