Approval request
Asks you to say yes before the assistant does something for you.
Examples
Pay Lena for rent
minus 450.00 US dollarsDue Friday, same as last month
Pay the phone bill
minus 45.00 US dollarsDue Thursday, same as last month
Pay Sam for the trip
minus 620.00 US dollars, more than you have availableYour share of the cabin
More than you have available
State
Pay Lena for rent
minus 450.00 US dollarsDue Friday, same as last month
waitingdefault
Pay Lena for rent
minus 450.00 US dollarsDue Friday, same as last month
Approvedapproved
Pay Lena for rent
minus 450.00 US dollarsDue Friday, same as last month
Declineddeclined
States
Pay Lena for rent
minus 450.00 US dollarsDue Friday, same as last month
waiting
Pay Lena for rent
minus 450.00 US dollarsDue Friday, same as last month
pending
Pay Lena for rent
minus 450.00 US dollarsDue Friday, same as last month
Approvedapproved
Pay Lena for rent
minus 450.00 US dollarsDue Friday, same as last month
Declineddeclined
Usage
When to use it
- Use
- The assistant is about to move money, pay a bill or change a goal.
- Use
- A check needs the person to decide.
- Not for
- Confirming a delete or another blocking choice. Use Alert dialog.
- Not for
- Reporting what the assistant already did. Use Action receipt.
- Not for
- Something the assistant noticed that needs no decision. Use Insight.
Rules
11 rules
- Must
- Ask with an ApprovalRequest before the assistant moves any money; a payment the person starts uses a review step and Payment done instead. Because the assistant acting on its own is the case people need to stop.
- Must
- Make Approve the one primary on the screen; turn other primaries secondary while it shows. Because two lime buttons leave the person unsure which one sends the payment.
- Must
- Pass amount signed, negative for money out, and available when you know it. Because a positive amount reads as money in and never warns, and without available Approve stays on when short.
- Must
- Write the title as a verb and its object with the person named, under about 28 characters; a longer title truncates on a phone. Because the title is the group name a screen reader announces and the line the person decides on.
- Should
- Keep reason to one line; put more in reasons, behind the Why?.
- Must
- Give every entry in reasons a source: a rule you set or past activity. Because without a source the person has to take the assistant at its word before money moves.
- Should
- Pass two or three reasons, the strongest first.
- Never
- Give a confidence score as a reason; name the evidence instead. Because a percentage gives the person nothing to check and reads as the assistant grading itself.
- Must
- Pass available so Approve turns off when the account cannot cover the amount; the card then says why and leaves Edit and Decline. Because Send in ChatInput is off for the same case, and an Approve that can only fail teaches people to press it blindly.
- Should
- Set pending while the payment goes out, then state approved.
- Never
- Make Decline red or primary; keep it the quiet ghost button. Because red tells the person that saying no is risky, and a primary Decline takes the one glow from Approve.
Accessibility
4 checks
- The card is a group named by its title; Edit is a pencil button named Edit.
- The footer is a polite live region, so Approved or Declined is announced.
- Pending keeps focus on Approve and sets aria-busy.
- The amount is read with its sign and currency.
Edge cases
5 edge cases
- Long title
- Truncates; the amount stays whole.
- Long reason
- Truncates to one line; move detail into reasons.
- Amount above the balance
- With available, the amount turns danger, Approve turns off and a red line under the reason says why.
- Phone width
- Approve grows to fill the row; Edit and Decline keep their width, and the row fits 260px.
- Choice made
- The status line takes the buttons' height, so nothing below moves.
API
10 props
titlestringdefaultrequiredamountnumberdefaultrequiredavailablenumberreasonstringdefaultrequiredstate'waiting' | 'approved' | 'declined'default'waiting'pendingbooleanonApprove, onEdit, onDecline() => voidreasons{text, source, href?}[]childrenReactNodelabels{approve?, decline?, edit?, why?, approved?, declined?, insufficient?}defaultEnglish words
Tokens
11 tokens
--surface- #f6f5f2
--radius-panel- 16px
--text-sm- 14px
--fg- #0f0f0d
--fg-2- #4a4943
--weight-medium- 500
--control-md- 40px
--accent- #e4f222
--success- #1e8e4a
--fg-disabled- #a6a49b
--danger-text- #b42323