refactor: Updated fallback behavior for avatar token, network, and favicon#1212
Merged
Conversation
Contributor
📖 Storybook Preview |
Contributor
📖 Storybook Preview |
…ask-design-system into refactor/avatar-fallbacks
Contributor
📖 Storybook Preview |
georgewrmarshall
previously approved these changes
Jun 3, 2026
Contributor
There was a problem hiding this comment.
Nice work tightening up the avatar fallback behavior. The main behavior looks good and the focused React/React Native avatar tests pass locally with coverage disabled. I left a few non-blocking comments around handler ordering, RN test assertions, and a deprecated RN image error type.
…o refactor/avatar-fallbacks
Contributor
📖 Storybook Preview |
Contributor
📖 Storybook Preview |
georgewrmarshall
approved these changes
Jun 4, 2026
georgewrmarshall
left a comment
Contributor
There was a problem hiding this comment.
LGTM! Nice work 🚀
georgewrmarshall
added a commit
that referenced
this pull request
Jun 4, 2026
## Release 43.0.0 This release drops Node.js 18 support across the release line, adds several new components, and includes a small set of breaking API changes that are documented in the migration guides. ### 📦 Package Versions - `@metamask/design-system-shared`: **0.21.0** - `@metamask/design-system-react`: **0.25.0** - `@metamask/design-system-react-native`: **0.28.0** - `@metamask/design-tokens`: **8.5.0** - `@metamask/design-system-tailwind-preset`: **0.9.0** - `@metamask/design-system-twrnc-preset`: **0.5.0** ### 🔄 Shared Type Updates (0.21.0) #### Added - Added `ContentPropsShared` and `ContentVerticalAlignment` for React Native list-style rows and related layout patterns ([#1192](#1192)) #### Changed - **BREAKING:** Dropped Node.js 18 support for the release line; consumers must run Node 20 or newer ([#1206](#1206)) - **BREAKING:** Updated `TextAreaPropsShared` to remove `inputElement` so React Native `TextArea` can render the root `TextInput` directly ([#1205](#1205)) ### 🌐 React Web Updates (0.25.0) #### Added - Added `Popover` for anchored overlays such as menus, tooltips, and dialogs ([#1153](#1153)) - Added `TextArea` for controlled multiline text entry ([#1036](#1036)) - Added `TextFieldSearch` for controlled search-field flows on top of `TextField` ([#1171](#1171)) - Added `FormTextField` for labeled form controls built from `Label`, `TextField`, and `HelpText` ([#1197](#1197)) #### Changed - **BREAKING:** Dropped Node.js 18 support for the release line; consumers must run Node 20 or newer ([#1206](#1206)) - Updated avatar fallback handling so `AvatarToken`, `AvatarNetwork`, and `AvatarFavicon` resolve consistently when the requested image is unavailable ([#1212](#1212)) ### 📱 React Native Updates (0.28.0) #### Added - Added `Content` for composing scrollable and padded content sections on React Native screens; it is closely related to the upcoming `ListItem` work ([#1192](#1192)) #### Changed - **BREAKING:** Dropped Node.js 18 support for the release line; consumers must run Node 20 or newer ([#1206](#1206)) - Added default padding and `isInteractive` support to `SectionHeader` so section rows match the new mobile layout patterns ([#1210](#1210)) - **BREAKING:** Flattened `TextArea` so it renders the root `TextInput` directly; pass `TextInput` props on `TextArea`, use the component `ref` for the input, and stop relying on `inputProps` or `inputElement` ([#1205](#1205)) - Updated avatar fallback handling so `AvatarToken`, `AvatarNetwork`, and `AvatarFavicon` resolve consistently when the requested image is unavailable ([#1212](#1212)) ###⚠️ Breaking Changes #### Node.js 18 support removed **What Changed:** - The release line now requires Node 20 or newer. - This applies across the monorepo, including the shared package, web package, React Native package, tokens, and both preset packages. **Impact:** - Consumers still on Node 18 must upgrade their runtime before installing or developing against this release line. - Node 18 is end-of-life, so this change aligns the repo with the supported app runtimes. #### React Native `TextArea` flattening **What Changed:** - `TextArea` now renders the root `TextInput` directly. - `inputProps` and `inputElement` are removed. - `inputRef` is replaced by the component `ref`. **Migration:** ```tsx // Before (0.27.0) <TextArea inputProps={{ placeholder: 'Message' }} inputElement={<CustomInput />} /> // After (0.28.0) <TextArea placeholder="Message" ref={inputRef} /> ``` **Impact:** - Affects React Native consumers using `TextArea`. - Call sites that depended on the wrapper/input split need to be updated. See migration guides for complete instructions: - [React Migration Guide](./packages/design-system-react/MIGRATION.md#from-version-0220-to-0230) - [React Native Migration Guide](./packages/design-system-react-native/MIGRATION.md#from-version-0270-to-0280) ### ✅ 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.20.0 → 0.21.0) - shared type additions and breaking TextArea/shared runtime baseline - [x] design-system-react: minor (0.24.0 → 0.25.0) - new components and release-line update - [x] design-system-react-native: minor (0.27.0 → 0.28.0) - new component, SectionHeader update, and breaking TextArea change - [x] Breaking changes documented with migration guidance - [x] Migration guides updated with before/after examples (if breaking changes) - [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** - [x] I've reviewed the [Reviewing Release PRs](./docs/reviewing-release-prs.md) guide - [x] Package versions follow semantic versioning - [x] Changelog entries are consumer-facing (not commit message regurgitation) - [x] Breaking changes are documented in MIGRATION.md with examples - [x] All unreleased changes are accounted for in changelogs <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Breaking React Native TextArea and Node 18 removal affect consumer upgrades; most diff is release metadata with coordinated peer dependency bumps. > > **Overview** > **Release 43.0.0** bumps the monorepo root to **43.0.0** and publishes coordinated semver bumps across design-system packages, with **yarn.lock** peer ranges updated for `@metamask/design-system-tailwind-preset` **^0.9.0** and `@metamask/design-system-twrnc-preset` **^0.5.0**. > > Across the release line, changelogs record **Node.js 18 dropped** (Node **20+** required). **@metamask/design-system-react** **0.25.0** documents new **`Popover`**, **`TextArea`**, **`TextFieldSearch`**, and **`FormTextField`**, plus avatar fallback fixes. **@metamask/design-system-react-native** **0.28.0** adds **`Content`**, updates **`SectionHeader`** (default padding, **`isInteractive`**), and includes a **breaking** **`TextArea`** flattening (`inputProps` / `inputElement` / `inputRef` removed; props and **`ref`** target the root **`TextInput`**). **@metamask/design-system-shared** **0.21.0** adds **`ContentPropsShared`** / **`ContentVerticalAlignment`** and removes **`inputElement`** from shared **`TextArea`** props. > > Migration guide edits in this diff: React Native **0.27.0 → 0.28.0** **`TextArea`** guidance; React version heading **0.22.0 → 0.23.0** for **`BannerBase`** (changelog-driven **0.25.0** items are not new migration sections here). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 23b0cda. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Improves avatar placeholder behavior across
AvatarFavicon,AvatarNetwork, andAvatarTokenin both@metamask/design-system-reactand@metamask/design-system-react-native.Why: When no
srcwas provided, image-based avatars rendered an empty placeholder because fallback text was only set after an image load error. Avatars without anameorfallbackTextalso showed nothing instead of a meaningful default.What changed:
srcis missing — Avatars now showfallbackText, the first character ofname, or?right away when there is no image source, instead of waiting for an error that never occurs.?instead of an empty string when neitherfallbackTextnornameis provided.AvatarBasebackground token — Updated the default background frombg-sectiontobg-alternativeso placeholders are visible on section-colored surfaces.Fallbackstories for all three avatar variants on web and mobile to document and manually verify placeholder states.Related issues
Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-774
Manual testing steps
yarn storybookand open AvatarFavicon, AvatarNetwork, and AvatarToken.fallbackTextis shown when provided (e.g."OS","ETH","BTC").nameis shown whenfallbackTextis omitted (e.g."G"for Github,"A"for Arbitrum).?is shown when neithersrc,name, norfallbackTextis provided.yarn storybook:iosoryarn storybook:androidand repeat the same checks on the Fallback stories.AvatarBaseplaceholders use thebg-alternativebackground and remain readable on section backgrounds.Screenshots/Recordings
Before
After
Simulator.Screen.Recording.-.iPhone.15.Pro.Max.-.2026-06-02.at.22.36.47.mov
Pre-merge author checklist
bg-alternative)Pre-merge reviewer checklist
Note
Low Risk
Design-system UI and placeholder behavior only; no auth, data, or API surface changes beyond visual fallback semantics.
Overview
Image avatars (
AvatarFavicon,AvatarNetwork,AvatarToken) on web and React Native now show placeholders immediately whensrcis missing, usingfallbackText, the first letter ofname, or?instead of staying blank until a load error. The same?default applies after image/SVG failures when neither name nor fallback is set.AvatarBasedefault background changes frombg-sectiontobg-alternativeso placeholders read on section surfaces; RN tests and both platforms’ implementations are updated.Storybook gains Fallback stories; tests assert no-
srcbehavior and use text queries for error fallbacks. RNImageOrSvgimage error typing moves toImageErrorEvent; webAvatarTokenensuresonErrorruns afterimagePropsspread.Reviewed by Cursor Bugbot for commit 96f729e. Bugbot is set up for automated code reviews on this repo. Configure here.