Handoff: Content Diff
What and why
A before and after of a piece of content, stacked like a text diff: the old value on a red line with a minus, the new value on a green line with a plus, in one bordered block. For text an agent proposes to change (page copy); code diffs use the Code diff recipe. PDS has nothing like it. It started as the body of the Suggestion Card's SuggestionChange and was taken out as its own component on 2026-10-21; SuggestionChange now composes it.
- Figma / Jira: Figma page under Preview; Jira none. Source: the designer's screenshot of the stacked diff in the Suggestion Card.
- Context:
context.md
Exploration and decisions
- Stacked, not columns. It reads top to bottom, gives long text the full width and matches the diff look used elsewhere.
- A definition list.
dlwith a visually hiddendt("Before", "After") and addper value;beforeLabelandafterLabelare required strings so they can be translated. The minus and plus icons arearia-hidden. - Color is not the only cue: the minus and plus carry the meaning too.
- Colors are the status tokens: critical for before, success for after (medium weight).
Full list: decisions.md.
API
| Prop | Type | Default | Purpose |
|---|---|---|---|
after |
ReactNode |
required | The new value. |
afterLabel |
string |
required | Name of the new value for screen readers (hidden). Translated. |
before |
ReactNode |
required | The current value. |
beforeLabel |
string |
required | Name of the current value for screen readers (hidden). |
className |
string |
none | Additional class names. |
size |
'xs' | 's' |
's' |
Text size, as a pds-copy-* class. The icons stay the same size. |
It extends the props of a dl. Variants and states: size s (default) and xs, switched with the size control. Story: Default.
Tokens used
--pds-border-radius-default,--pds-border-width-default--pds-color-border-default--pds-color-status-critical-background,--pds-color-status-critical-foreground--pds-color-status-success-background,--pds-color-status-success-foreground--pds-spacing-2xs,--pds-spacing-5xs,--pds-spacing-xs--pds-typography-fw-medium
Impact
From impact.md: no existing PDS component is reached. SuggestionCard builds on it (SuggestionChange); it uses the default size s, which is what it rendered before the size prop, so it is unchanged (look at it in Storybook to confirm).
Reused vs net-new
- Reused: the local
Iconwrapper (minus,plus, the PDS icons, sizes),pds-copy-sandpds-copy-xs, thevisually-hiddenclass. - Net-new:
.pds-content-diffwith__line,--before,--after,__markerand__text; all props. Seecustom.md(no custom variables, no raw values).
Accessibility
- A
dlwith hiddendtnames, so a screen reader hears "Before: ..." and "After: ...". Give the block a name from the screen around it (for example the field), asSuggestionChangedoes. - Contrast: the status foreground on the status background. a11y panel on Default at both sizes, light and dark (2026-10-22): no violations, no inconclusive checks. Dark mode was not checked by eye.
- The
sizeprop only changes the text size; semantics and the icons are the same.
Decisions and open questions
- Size added 2026-10-22 (after handoff):
sizesorxs, text only; seedecisions.md. - Highlight the changed words inside each line?
- Should it take a visible title (the field name) itself?
Port notes
- New component (
npm run generate:component). Swap the localIconwrapper andmergeClassesfor the real ones. Port it before SuggestionCard.
Preview
npm run storybook, then Component Proposals/Content Diff. Figma: https://www.figma.com/design/AMGWJbraJoi2PKWnxo29Ah/PDS-Proposals?node-id=489-43