refactor: Added default padding and added isInteractive to SectionHeader#1210
Conversation
📖 Storybook Preview |
📖 Storybook Preview |
📖 Storybook Preview |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ 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 5b42e83. Configure here.
…design-system into update/section-header
📖 Storybook Preview |
📖 Storybook Preview |
| decorators: [ | ||
| (Story) => ( | ||
| <Box twClassName="w-full bg-background-default p-4"> | ||
| <Story /> | ||
| </Box> | ||
| ), | ||
| ], |
There was a problem hiding this comment.
Nice. I think we should actually remove all of these types of wrappers from our stories regardless of how they sit within the page...
There was a problem hiding this comment.
Nice work adding the interactive SectionHeader behavior. The implementation looks good overall, Bugbot's disabled pressed-state concern appears addressed in the latest commits, and the focused SectionHeader test suite passes locally. I left a few non-blocking comments around Storybook controls, accessibility defaults, prop typing, and docs consistency.
brianacnguyen
left a comment
There was a problem hiding this comment.
Let me update
…o update/section-header
📖 Storybook Preview |
📖 Storybook Preview |
georgewrmarshall
left a comment
There was a problem hiding this comment.
Approved. I left non-blocking follow-up comments.
| import { SectionHeader } from './SectionHeader'; | ||
| import type { SectionHeaderProps } from './SectionHeader.types'; | ||
|
|
||
| const noopPress = () => undefined; |
There was a problem hiding this comment.
non-blocking: this would be a good use of actions but we can do a bulk update not critical
| jest.clearAllMocks(); | ||
| }); | ||
|
|
||
| const flattenStyles = ( |
There was a problem hiding this comment.
non-blocking: I think this is okay to approve and merge, but could we avoid leaning further into flattenStyles, findPressableStyleFn, and getPressableStyleFn long term? PR #1184 moved us away from react-test-renderer tree traversal because it is related to RNTL implementation-detail anti-patterns: RNTL cautions against navigating the ReactTestInstance tree because it makes tests fragile, and its type/props queries are explicitly marked UNSAFE for the same reason. I have not found a reliable way to test Pressable pressed-state visual logic through RNTL without reaching into renderer internals, so we may want to remove these helpers and accept/document the reduced branch coverage in the PR that upgrades RNTL. References: https://callstack.github.io/react-native-testing-library/docs/advanced/testing-env#tree-navigation and https://callstack.github.io/react-native-testing-library/docs/api/queries#legacy-unit-testing-helpers
There was a problem hiding this comment.
Sure. Should we do a change to remove these tips and add a rule to the testing rules?
📖 Storybook Preview |
## 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 -->

Description
This PR updates the React Native
SectionHeadercomponent to match design specs and support tappable section headers.Why: Section headers needed consistent default spacing, and some headers (e.g. "See all") should be pressable with clear visual feedback.
What changed:
px-4 pt-3 pb-2to the outer wrapper by default (still overridable viatwClassName).isInteractiveprop — Discriminated union type:false/omitted: staticBoxRowwithViewProps(unchanged behavior).true: wraps the header inPressablewithPressableProps; opacity reduces to0.7while pressed.isInteractiveistrue, rendersIconName.ArrowRightunlessendIconName,endIconProps.name, orendAccessoryis provided.IconColor.IconAlternative.Also includes README updates, an
InteractiveStorybook story, unit tests, and a jest branch coverage override for the untestable pressed-state branch (same pattern asActionListItem).Related issues
Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-772
Manual testing steps
yarn storybook:iosoryarn storybook:androidpx-4 pt-3 pb-2) on static headersonPressfires)endIconName,endAccessory, andtwClassNamestill work whenisInteractiveistrueScreenshots/Recordings
Before
After
Simulator.Screen.Recording.-.iPhone.15.Pro.Max.-.2026-06-02.at.21.52.29.mov
Pre-merge author checklist
Pre-merge reviewer checklist
Note
Medium Risk
Default padding and optional Pressable behavior change layout and touch targets for every SectionHeader consumer; removing icon name resolution via iconProps is a subtle breaking API change.
Overview
React Native
SectionHeadernow applies default outer padding (px-4 pt-3 pb-2) and supportsisInteractive: whentrue, the row is aPressablewithPressableProps, defaultaccessibilityRoleofbutton,opacity-70while pressed (skipped whendisabled), and a defaultArrowRightend icon unlessendIconNameorendAccessoryis set. Non-interactive usage stays on a static outerBoxRowwithViewProps.API / styling tweaks:
SectionHeaderPropsis a discriminated union onisInteractive;startIconProps/endIconPropsno longer acceptname(icons come only fromstartIconName/endIconName). End icons useIconColor.IconAlternative. Layout is refactored so the title sits in an inner row and start/end accessories sit on the outer wrapper (or inside the pressable inner row when interactive).Docs, Storybook (
Interactivestory), expanded unit tests, and a Jest branch coverage exception forSectionHeader.tsx(same pressed-state limitation asActionListItem) are included.Reviewed by Cursor Bugbot for commit 879e660. Bugbot is set up for automated code reviews on this repo. Configure here.