← All proposals

Suggestion Card

A card for use inside an agent `ChatMessage`:

Net-new componentOpen in Storybook

proposals/SuggestionCard/SuggestionCard.mdx34 lines · View on GitHub
import { Canvas, Controls, Meta, Title } from '@storybook/addon-docs/blocks';

import * as SuggestionCardStories from './SuggestionCard.stories';

<Meta of={SuggestionCardStories} name='Usage' />

<Title />

## Purpose

Shows changes an agent suggests, and lets the user decide what to do with them.

## Usage

Use it inside an agent message in a chat, when the agent proposes a change and waits for the user.

- The content area is a slot (`children`); what goes in it is up to the screen. `SuggestionChange` is an optional helper for the before and after case: the field name over a stacked diff, the old value on a red line with a minus and the new value on a green line with a plus. "Before" and "After" are visually hidden text for screen readers.
- Set `type='choice'` for multiple choice: the header, a list of `SuggestionChoice` rows (a radio for one answer, a checkbox for one or more) and the footer, divided by lines across the card. A row's `children` sit under its label (for example a text field for an Other option). The screen owns the selection. To let people retry and browse earlier sets, see the recipe **Regenerate a suggestion**.
- Put the decision buttons in `actionsStart`, at the left of the footer. The reference has Accept (primary), Refine (secondary) and Dismiss (subtle).
- While `state` is `pending` the buttons show. When the user accepts, set `state` to `accepted` and pass `statusLabel`; it replaces `actionsStart` and is announced to screen readers. When the user dismisses, set `state` to `dismissed`: the changes hide, the card shrinks to a record with `statusLabel` (for example "Dismissed"), and an Undo button in `actionsEnd` can bring it back; move focus to Undo, since the Dismiss button is gone. `actionsEnd` (for example a Feedback Bar) sits at the right of the footer in every state; the screen chooses what to show in each. Both slots are optional, and with neither the footer takes no space.
- `buttonSize` (`xs` by default, or `s`) sets the size of the whole button set in `actionsStart`, so the buttons always match. It applies to every PDS `Button` in `actionsStart`, not to `actionsEnd`.
- `padding` takes the same options as `Panel` (`none`, `condensed`, `standard`, `spacious`). It defaults to `condensed`, which suits a card in a chat.
- The title is a heading. Set `headingLevel` so it fits the page outline, and `headingSize` (`m` by default, or `l`) for how large it looks. They are separate: the level is the tag, the size is the type.
- It is a decision prompt for the message stream. A full-width report on a page is a Panel with an agentic border, not this component.

## Implementation

See the table below for the available props. The other stories show the accepted state (with a Feedback Bar in `actionsEnd`), the dismissed state (with Undo) and an interactive version.

<hr />

<Canvas of={SuggestionCardStories.Default} />
<Controls of={SuggestionCardStories.Default} />