fix: Polish React Native Toast background, description color and border radius - #1391
Conversation
Co-authored-by: Cursor <cursoragent@cursor.com>
📖 Storybook LinksCompare the preview for this pull request with the latest Storybooks from the 🔀 Pull Request Preview
🌳 Main Branch (Latest)
|
Co-authored-by: Cursor <cursoragent@cursor.com>
📖 Storybook LinksCompare the preview for this pull request with the latest Storybooks from the 🔀 Pull Request Preview
🌳 Main Branch (Latest)
|
|
Follow-up: We don't use default parameter values for props objects — the convention is to spread defaults inline in the JSX so consumer-provided values can override rather than replace: // ❌ Current — any consumer-passed `descriptionProps` silently drops the color default
descriptionProps = { color: TextColor.TextAlternative },
// ✅ Preferred — merge in JSX so consumers can still override individual keys
descriptionProps={{ color: TextColor.TextAlternative, ...descriptionProps }}As-is, passing |
|
@brianacnguyen — do we have shadow utility classes in the twrnc preset (e.g. If twrnc shadow classes don't exist yet, this is a good candidate to add them to |
Nope we don't have shadow utilities yet. Agreeing that they’re a good candidate to add |
## **Description** Follow-up to [#1391](#1391) (Toast polish: background, description color, border radius). ### **What issues does this PR address?** * **`descriptionProps` defaults replace instead of merge**: In [#1391](#1391), Toast defaulted `descriptionProps` in the destructure (`descriptionProps = { color: TextColor.TextAlternative }`). Passing any consumer object (e.g. `{ numberOfLines: 2 }` or `{ testID: '...' }`) replaced the whole default, so `TextAlternative` was silently dropped. ### **Key improvements** * Merge the default description color inline in JSX: `descriptionProps={{ color: TextColor.TextAlternative, ...descriptionProps }}`, matching the team convention for props objects. * Add a regression test that passes partial `descriptionProps` and asserts the default color is still applied. ### **Notes for reviewers** - Addresses George’s post-merge follow-up on [#1391](#1391): merge `descriptionProps` in JSX instead of defaulting in the destructure. ## **Related issues** Follow-up to: #1391 ## **Manual testing steps** 1. Open React Native Storybook (`yarn storybook:ios` or `yarn storybook:android`) and navigate to Toast stories. 2. Confirm description text still uses the alternative text color by default. 3. Optionally verify a toast with `descriptionProps={{ testID: '...' }}` (or `numberOfLines`) keeps the alternative color. ## **Screenshots/Recordings** ### **Before** N/A — behavior fix; visual default is unchanged when `descriptionProps` is omitted ### **After** N/A — behavior fix; visual default is unchanged when `descriptionProps` is omitted ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. Made with [Cursor](https://cursor.com) Co-authored-by: Cursor <cursoragent@cursor.com>
<!-- Release PR Template Use this template for release PRs by creating your PR with: https://github.com/MetaMask/metamask-design-system/compare/main...release/VERSION?template=release.md Or use the default PR template and manually copy this structure. --> ## Release 55.0.0 React Native Toast moves to iOS-style top placement with spring motion, related offset/padding renames, and surface polish (theme background, description color, border radius). ### 📦 Package Versions - `@metamask/design-system-react-native`: **0.37.0** ### 📱 React Native Updates (0.37.0) #### Changed - **BREAKING:** Updated `Toast` / `Toaster` to slide in from the top of the screen (below the safe area) with spring-based enter/exit motion ([#1304](#1304)) - Renamed `bottomOffset` and `customTopOffset` to `topOffset` - Renamed exported `TOAST_BOTTOM_PADDING` to `TOAST_TOP_PADDING` (default padding 36 → 8) - Migration: [Toast topOffset renames](./packages/design-system-react-native/MIGRATION.md#toast-bottomoffset-to-topoffset) - Updated `Toast` surface styling for light/dark themes: light uses `background.default` with medium shadow; dark uses `background.section` with no shadow; border radius 12px → 16px; description defaults to `TextColor.TextAlternative` ([#1391](#1391)) #### Fixed - Fixed `Toast` `descriptionProps` so partial consumer props merge with the default `TextAlternative` color instead of replacing it ([#1396](#1396)) ###⚠️ Breaking Changes #### Toast top placement and offset renames (React Native Only) **What Changed:** - Toasts now appear from the **top** of the screen (below the safe area) instead of the bottom - `bottomOffset` / `customTopOffset` → `topOffset` - `TOAST_BOTTOM_PADDING` → `TOAST_TOP_PADDING` (default 36 → 8) **Migration:** ```tsx // Before (0.36.0) import { TOAST_BOTTOM_PADDING, toast, } from '@metamask/design-system-react-native'; toast({ hasNoTimeout: false, title: 'Saved', bottomOffset: 24, }); const padding = TOAST_BOTTOM_PADDING; // After (0.37.0) import { TOAST_TOP_PADDING, toast } from '@metamask/design-system-react-native'; toast({ hasNoTimeout: false, title: 'Saved', topOffset: 24, }); const padding = TOAST_TOP_PADDING; ``` **Impact:** - Call sites using `bottomOffset`, `customTopOffset`, or `TOAST_BOTTOM_PADDING` must rename and re-evaluate numeric offsets tuned for bottom placement See [React Native Migration Guide](./packages/design-system-react-native/MIGRATION.md#from-version-0360-to-0370) ### ✅ Checklist - [x] Changelogs updated with human-readable descriptions - [x] Changelog validation passed (`yarn changelog:validate`) - [x] Version bumps follow semantic versioning - [x] design-system-react-native: minor (0.36.0 → 0.37.0) - Toast top placement feature + breaking offset/padding renames - [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 - [x] 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 --------- Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description**
Polishes React Native `BannerBase` spacing so padding and
title/description gap match design more closely.
1. **Bottom padding:** When an action button is below content, use
`paddingBottom={4}` (16px); otherwise keep `3` (12px).
2. **Right padding:** When a close button is present, use
`paddingRight={2}` (8px); otherwise keep `4` (16px).
3. **Title → description gap:** When both are present, add `mt-0.5`
(2px) above the description.
### Impacted components
* `BannerAlert`
* `Toast`
## **Related issues**
Fixes:
#1304
#1391
#1394
## **Manual testing steps**
1. Run `yarn storybook:ios` (or Android) and open **BannerBase** /
**BannerAlert** / **Toast** stories (they compose `BannerBase`).
2. Confirm default padding: 12px vertical, 16px horizontal when there is
no close button and no below action button.
3. With a close button: right padding is 8px.
4. With an action button in `Below` layout: bottom padding is 16px.
5. With title + description: 2px gap between them; description-only has
no extra top margin.
## **Screenshots/Recordings**
### **Before**
https://github.com/user-attachments/assets/070f0754-9b52-45a7-b543-988e10ebbd6f
### **After**
https://github.com/user-attachments/assets/02764783-f984-4e4b-9f02-ba9e18206eca
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs)
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
Made with [Cursor](https://cursor.com)
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Description
Polish React Native
Toastsurface styling so it matches the intended light/dark treatment.Why: Toast was always using section background, 12px radius, and default description color, which didn’t match the desired visual spec.
What changed:
background.default+ medium shadowbackground.section(no shadow)TextColor.TextAlternativerounded-xl) to 16px (rounded-2xl)Related issues
Fixes:
#1304
MetaMask/metamask-mobile#32933
Manual testing steps
yarn storybook:ios(or Android) and open Components → ToastScreenshots/Recordings
Before
Screen.Recording.2026-07-21.at.4.29.10.PM.mov
After
Screen.Recording.2026-07-21.at.4.17.55.PM.mov
Pre-merge author checklist
Pre-merge reviewer checklist
Made with Cursor