feat: [DSRN] Added ListItem#1203
Conversation
📖 Storybook Preview |
📖 Storybook Preview |
georgewrmarshall
left a comment
There was a problem hiding this comment.
Really solid work on the component — the Content layout, interactive/non-interactive branching, prop override semantics, and the overall API surface are well thought through. The flat prop API is production-ready and there's no disagreement on the direction: providing both a prop-based API and compound component syntax is the right end state.
The open question — being discussed in MetaMask/decisions#203 — is which mechanism to use for the compound component part (null-marker parsed slots vs render-in-place sub-components). Since that discussion is still live, I'd suggest shipping this PR as a v1 with the flat prop API only and adding compound component support as a follow-up once the approach is settled. This unblocks teams who need ListItem now with a clean, well-tested API:
<ListItem
avatar={<AvatarToken name="ETH" size="lg" />}
title="Account 2"
titleEndAccessory={<Tag>Hardware Wallet</Tag>}
description="Secondary text"
value="$5,678.00"
subvalue="1.2 ETH"
isInteractive
/>Nothing in the ADR conversation changes the prop-based API — it's purely additive. Shipping now avoids blocking on a mechanism decision that doesn't affect v1 consumers at all.
📖 Storybook Preview |
📖 Storybook Preview |
georgewrmarshall
left a comment
There was a problem hiding this comment.
Clean migration from the generic-wrapper pattern to a Content-backed prop API. The discriminated union on isInteractive is well typed, tests follow the correct RN matchers (toBeOnTheScreen, toHaveStyle(tw.style(...))), and the README is consumer-facing throughout. One item to resolve before merging.
📖 Storybook Preview |
📖 Storybook Preview |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d60ab8f. Configure here.
| value="1.234 ETH" | ||
| onPress={() => {}} | ||
| /> | ||
| </Box>; |
There was a problem hiding this comment.
README quick start mismatches Default
Low Severity
The README opening example shows an interactive Network row with onPress, while the Storybook Default story uses non-interactive args (title “Label”, description “Secondary text”, value “Value”) with no isInteractive or parent Box.
Additional Locations (1)
Triggered by learned rule: README quick-start examples must match Default story
Reviewed by Cursor Bugbot for commit d60ab8f. Configure here.
📖 Storybook Preview |
## Release 44.0.0 This release adds `Toast`/`Toaster` and `Tag` to React, `ListItem` to React Native, aligns the `TextButton` API across platforms, and standardizes severity vocabulary (`Error` → `Danger`) across `AvatarIcon`, `IconAlert`, and `Tag`. ### 📦 Package Versions - `@metamask/design-system-shared`: **0.22.0** - `@metamask/design-system-react`: **0.26.0** - `@metamask/design-system-react-native`: **0.29.0** ### 🔄 Shared Type Updates (0.22.0) #### New shared types (#1190, #1203, #1224, #1225) **What Changed:** - Added `ToastPropsShared` and `ToastSeverity` for cross-platform `Toast` support - Added `ListItemPropsShared` and related types for cross-platform `ListItem` support - Added `TextButtonPropsShared` to align `TextButton` API across React and React Native - Added `AvatarNetworkSize` as a named export from the shared package **Impact:** - Enables consistent `Toast` and `ListItem` implementations across both platforms - Continues ADR-0003/0004 const-object + string-union pattern adoption #### Severity vocabulary: `.Error` → `.Danger` ([#1159](#1159)) **What Changed:** - `AvatarIconSeverity.Error` → `AvatarIconSeverity.Danger` - `IconAlertSeverity.Error` → `IconAlertSeverity.Danger` - `TagSeverity.Error` → `TagSeverity.Danger` **Impact:** - Breaking change for any consumer using `.Error` on these three const objects. Rendered colors are unchanged. ### 🌐 React Web Updates (0.26.0) #### Added - Added `Tag` component for categorization and filtering labels ([#1211](#1211)) - Added `Toast` component with `Toaster` provider and imperative `toast()` API ([#1190](#1190)) #### Changed - **BREAKING:** `TextButton` API aligned with React Native — `size`/`TextButtonSize` replaced by `variant`/`TextVariant`; `isInverse`, `isDisabled`, `textProps`, and icon/accessory props removed; `asChild` added ([#1224](#1224)) - **BREAKING:** `AvatarIconSeverity.Error` → `AvatarIconSeverity.Danger` ([#1159](#1159)) #### Fixed - Fixed `Toast` to support `toast()` calls made before `Toaster` mounts ([#1217](#1217)) ### 📱 React Native Updates (0.29.0) #### Added - Added `ListItem` component for list row layouts ([#1203](#1203)) - Added `Toast` component with `Toaster` provider and imperative `toast()` API ([#1190](#1190)) #### Changed - **BREAKING:** `AvatarIconSeverity.Error`, `IconAlertSeverity.Error`, and `TagSeverity.Error` → `.Danger` ([#1159](#1159)) ###⚠️ Breaking Changes #### TextButton rewrite (React Web Only) **What Changed:** - `size` / `TextButtonSize` removed — use `variant` / `TextVariant` instead - `isInverse`, `isDisabled`, `textProps`, start/end icons, and accessory slots removed - `asChild` added for semantic link composition **Migration:** ```tsx // Before (0.25.0) import { TextButton, TextButtonSize } from '@metamask/design-system-react'; <TextButton size={TextButtonSize.BodySm}>Learn more</TextButton> // After (0.26.0) import { TextButton } from '@metamask/design-system-react'; import { TextVariant } from '@metamask/design-system-shared'; <TextButton variant={TextVariant.BodySm}>Learn more</TextButton> ``` See [React Migration Guide](./packages/design-system-react/MIGRATION.md#from-version-0250-to-0260) #### Severity vocabulary: `.Error` → `.Danger` (Both Platforms) **What Changed:** - `AvatarIconSeverity.Error` → `AvatarIconSeverity.Danger` (React + React Native) - `IconAlertSeverity.Error` → `IconAlertSeverity.Danger` (React Native) - `TagSeverity.Error` → `TagSeverity.Danger` (React Native) **Migration:** ```tsx // Before <AvatarIcon severity={AvatarIconSeverity.Error} /> <IconAlert severity={IconAlertSeverity.Error} /> <Tag severity={TagSeverity.Error}>High risk</Tag> // After <AvatarIcon severity={AvatarIconSeverity.Danger} /> <IconAlert severity={IconAlertSeverity.Danger} /> <Tag severity={TagSeverity.Danger}>High risk</Tag> ``` See migration guides for complete instructions: - [React Migration Guide](./packages/design-system-react/MIGRATION.md#from-version-0250-to-0260) - [React Native Migration Guide](./packages/design-system-react-native/MIGRATION.md#from-version-0280-to-0290) ### ✅ Checklist - [x] Changelogs updated with human-readable descriptions - [x] Changelog validation passed (`yarn changelog:validate`) - [x] Version bumps follow semantic versioning - [x] design-system-shared: minor (0.21.0 → 0.22.0) - new shared types + breaking severity rename - [x] design-system-react: minor (0.25.0 → 0.26.0) - new components + breaking API changes - [x] design-system-react-native: minor (0.28.0 → 0.29.0) - new components + breaking severity rename - [x] Breaking changes documented with migration guidance - [x] Migration guides updated with before/after examples - [x] PR references included in changelog entries ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) - [x] I've reviewed the [Release Workflow](./.cursor/rules/release-workflow.md) cursor rule - [ ] All tests pass (`yarn build && yarn test && yarn lint`) - [x] Changelog validation passes (`yarn changelog:validate`) ## **Pre-merge reviewer checklist** - [ ] I've reviewed the [Reviewing Release PRs](./docs/reviewing-release-prs.md) guide - [ ] Package versions follow semantic versioning - [ ] Changelog entries are consumer-facing (not commit message regurgitation) - [ ] Breaking changes are documented in MIGRATION.md with examples - [ ] All unreleased changes are accounted for in changelogs <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > The release documents multiple breaking consumer APIs (TextButton on web, severity `.Error`→`.Danger`); upgrading without following MIGRATION.md will cause compile/runtime mismatches, though this PR does not change component implementation itself. > > **Overview** > **Release 44.0.0** cuts new versions of the design-system packages and records what shipped since the last release: monorepo root **43.0.0 → 44.0.0**, `@metamask/design-system-shared` **0.22.0**, `@metamask/design-system-react` **0.26.0**, and `@metamask/design-system-react-native` **0.29.0**. > > Changelogs document **React** additions (`Tag`, `Toast`/`Toaster`/`toast()`), a **breaking** `TextButton` rewrite (`size`/`TextButtonSize` → `variant`/`TextVariant`, dropped inverse/disabled/icons, added `asChild`), and **`AvatarIconSeverity.Error` → `.Danger`**. **React Native** adds **`ListItem`** and the same **severity rename** on `AvatarIcon`, `IconAlert`, and `Tag`. **Shared** adds cross-platform types (`ListItem`, `Toast`, `TextButton`, `AvatarNetworkSize`) and the shared **`.Error` → `.Danger`** severity vocabulary. > > **MIGRATION.md** on React and React Native gains **0.25→0.26** and **0.28→0.29** sections with before/after examples. The only non-release code change in the diff is reordering the `react-native-worklets` devDependency in `apps/storybook-react-native/package.json`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 9c3345f. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->


Description
Refactors
@metamask/design-system-react-nativeListItem from a generic horizontal child wrapper into a padded list row built on Content.Why: ListItem should match the design system's standard row layout (title, description, value, avatar, accessories) and support tappable rows with consistent press feedback. The previous API laid out arbitrary
childrenin a row withgapspacers, which didn't align with how list rows are used in product.What changed:
px-4 py-3).isInteractivetoggles the root betweenBox(default) andPressable(appliesbg-pressedwhile pressed).title,description,value,subvalue,avatar, accessories, etc.).childrenrender below the Content block (e.g. expanded details), not as siblings in the main row.ListItemPropsSharedin@metamask/design-system-shared(ADR-0004) for cross-platform props (isInteractive,children).Breaking changes:
ListItemVerticalAlignment— useContentVerticalAlignmentfrom shared instead.gap,topAccessoryGap, andbottomAccessoryGap.ListItem.constants.tsand the horizontal child + spacer layout model.ListItemVerticalAlignmentis no longer exported from@metamask/design-system-react-native.For row layout without padding or press handling, use Content directly.
Related issues
Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-773
Manual testing steps
yarn storybook:ios(oryarn storybook:android).yarn workspace @metamask/design-system-react-native run jest --testPathPattern=ListItem.test --watchman=falseScreenshots/Recordings
Before
After
Simulator.Screen.Recording.-.iPhone.15.Pro.Max.-.2026-06-02.at.23.03.17.mov
Pre-merge author checklist
Pre-merge reviewer checklist
Note
High Risk
Large breaking API change to a widely used list primitive (~58 mobile call sites per migration doc); consumers must migrate from children/gap layout to Content props and ContentVerticalAlignment.
Overview
ListItem is rebuilt as a padded list row (
px-4 py-3) around Content, replacing the old horizontalchildren+gapspacer layout.API: Row text and chrome use Content props (
title,description,value,subvalue,avatar, start/end/top/bottom accessories).isInteractiveswitches the root fromBoxtoPressablewith defaultbg-pressedfeedback andaccessibilityRole="button". Optionalchildrenrender below Content, not in the main row.ListItemPropsShared(isInteractive,children) is added in@metamask/design-system-shared.Breaking:
ListItemVerticalAlignmentis removed—useContentVerticalAlignment(Bottomhas no equivalent).gap,topAccessoryGap,bottomAccessoryGap, andListItem.constants.tsare removed.ListItemVerticalAlignmentis no longer exported from the RN package. MIGRATION.md documents mobile → design-system mappings.Tests, Storybook, and README are updated for the new model.
Reviewed by Cursor Bugbot for commit d60ab8f. Bugbot is set up for automated code reviews on this repo. Configure here.