ApprovalCard
Asks the user to approve an action Wally wants to take — a tool call, a config change — before it runs. While status is pending the card shows its children (ApprovalCardContent and ApprovalCardActions); once the app sets approved or rejected, the children are replaced by a one-line status, so the buttons need no gating of their own. The card has no outer margins or horizontal padding: the panel gutter (ChatBody / ChatFooter) places it, whether it sits inline in the conversation or docked above the input. Buttons are plain DS components composed by the app, which also owns loading — disable them while the request is in flight.
Usage
Examples
Pending long text
Long text wraps, and unbroken strings such as URLs break rather than overflow the card.
Pending with code snippet
Arguments the user should read verbatim go in a CodeSnippet, 8px under the text.
Allow once menu
The chevron half of the split button opens the narrower "Allow once" option.
Loading
There is no loading variant: while the decision is being sent, the app disables its own buttons.
Approved
After approval the content and buttons collapse into a status row; the caption stays. The
children are kept on purpose: the app renders the same tree and only flips status.
Rejected
The rejected status row. rejectedLabel (like approvedLabel and caption) is a prop, so
the app can say what was rejected.
Analytics
Analytics attributes go on the composed DS buttons themselves — the card adds no seam of
its own, so each data-analytics-id lands on the real <button>.