Skip to content

feat: migrate ButtonIcon to ADR-0003 and ADR-0004 (DSYS-485)#1038

Merged
georgewrmarshall merged 2 commits intomainfrom
cursor/enum-shared-type-migration-398d
Apr 28, 2026
Merged

feat: migrate ButtonIcon to ADR-0003 and ADR-0004 (DSYS-485)#1038
georgewrmarshall merged 2 commits intomainfrom
cursor/enum-shared-type-migration-398d

Conversation

@cursor
Copy link
Copy Markdown
Contributor

@cursor cursor Bot commented Apr 3, 2026

Description

Migrates the ButtonIcon component to follow ADR-0003 (String Unions) and ADR-0004 (Centralized Types Architecture).

Changes:

  • Creates ButtonIconSize and ButtonIconVariant const objects in @metamask/design-system-shared (ADR-0003), replacing the duplicate TypeScript enums in both platform packages
  • Creates ButtonIconPropsShared type in shared package (ADR-0004) with platform-independent props (iconName: string, size, isDisabled, variant)
  • Updates ButtonIconProps in both React and React Native to import and extend from shared (platform-specific props like iconProps: Partial<IconProps>, ariaLabel, className/twClassName, and style remain in platform packages)
  • Updates index.ts files in both platform packages to re-export const objects from shared
  • Removes old ButtonIconSize and ButtonIconVariant enums from platform types/index.ts files
  • Updates all consumers (ButtonIcon.tsx, ButtonIcon.constants.ts, ButtonIcon.stories.tsx, ButtonIcon.test.tsx, BannerBase.tsx) to import from @metamask/design-system-shared

Related issues

Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-485

Manual testing steps

  1. Run yarn build — should complete with no errors
  2. Run yarn test — all tests pass with 100% coverage
  3. Run yarn lint — no errors

Screenshots/Recordings

After

no visual changes

after720.mov

Pre-merge author checklist

  • I've followed 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 format if applicable
  • I've applied the right labels on the PR (see labeling guidelines). Not required for external contributors.

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.
Open in Web View Automation 

Note

Medium Risk
Moderate risk because it changes exported ButtonIcon type/value sources (enums → const objects) across both React and React Native packages, which can break downstream imports or type expectations even though runtime behavior is unchanged.

Overview
Migrates ButtonIcon to the centralized shared-types architecture by moving ButtonIconSize, ButtonIconVariant, and new ButtonIconPropsShared into @metamask/design-system-shared (as ADR-0003 string-union const objects) and exporting them from the shared entrypoint.

Updates both design-system-react and design-system-react-native to consume/re-export these shared types, refactors ButtonIconProps to extend ButtonIconPropsShared, and removes the duplicated ButtonIconSize/ButtonIconVariant enums from each platform’s types/index.ts, along with updating affected consumers/tests/stories (e.g., BannerBase, KeyValue*, and ButtonIcon files) to import from shared.

Reviewed by Cursor Bugbot for commit 9143505. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 3, 2026

📖 Storybook Preview

@georgewrmarshall georgewrmarshall force-pushed the cursor/enum-shared-type-migration-398d branch from c42c609 to caa0050 Compare April 27, 2026 22:34
@github-actions
Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@georgewrmarshall georgewrmarshall force-pushed the cursor/enum-shared-type-migration-398d branch from caa0050 to e538281 Compare April 28, 2026 05:03
@github-actions
Copy link
Copy Markdown
Contributor

📖 Storybook Preview

cursoragent and others added 2 commits April 28, 2026 10:02
- Create ButtonIconSize and ButtonIconVariant const objects in shared package (ADR-0003)
- Create ButtonIconPropsShared type in shared package (ADR-0004)
- Update React and React Native ButtonIcon.types.ts to import from shared
- Update ButtonIcon index.ts files to re-export const objects from shared
- Update ButtonIcon.tsx, constants, stories, and test files to import from shared
- Remove old ButtonIconSize and ButtonIconVariant enums from platform types/index.ts
- Update BannerBase.tsx in both packages to import ButtonIconSize from shared

Co-authored-by: George Marshall <georgewrmarshall@users.noreply.github.com>
import React from 'react';

import { ButtonIconSize, IconColor } from '../../types';
import { IconColor } from '../../types';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will move IconColor and other related Icon types in a separate PR

@georgewrmarshall georgewrmarshall force-pushed the cursor/enum-shared-type-migration-398d branch from e538281 to 9143505 Compare April 28, 2026 17:05
@github-actions
Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@georgewrmarshall georgewrmarshall marked this pull request as ready for review April 28, 2026 17:09
@georgewrmarshall georgewrmarshall requested a review from a team as a code owner April 28, 2026 17:09
@georgewrmarshall georgewrmarshall enabled auto-merge (squash) April 28, 2026 17:09
@georgewrmarshall georgewrmarshall merged commit 7f665f1 into main Apr 28, 2026
44 checks passed
@georgewrmarshall georgewrmarshall deleted the cursor/enum-shared-type-migration-398d branch April 28, 2026 18:18
georgewrmarshall added a commit that referenced this pull request Apr 28, 2026
## **Description**

Migrates the `ButtonIcon` component to follow ADR-0003 (String Unions)
and ADR-0004 (Centralized Types Architecture).

**Changes:**
- Creates `ButtonIconSize` and `ButtonIconVariant` const objects in
`@metamask/design-system-shared` (ADR-0003), replacing the duplicate
TypeScript enums in both platform packages
- Creates `ButtonIconPropsShared` type in shared package (ADR-0004) with
platform-independent props (`iconName: string`, `size`, `isDisabled`,
`variant`)
- Updates `ButtonIconProps` in both React and React Native to import and
extend from shared (platform-specific props like `iconProps:
Partial<IconProps>`, `ariaLabel`, `className`/`twClassName`, and `style`
remain in platform packages)
- Updates `index.ts` files in both platform packages to re-export const
objects from shared
- Removes old `ButtonIconSize` and `ButtonIconVariant` enums from
platform `types/index.ts` files
- Updates all consumers (`ButtonIcon.tsx`, `ButtonIcon.constants.ts`,
`ButtonIcon.stories.tsx`, `ButtonIcon.test.tsx`, `BannerBase.tsx`) to
import from `@metamask/design-system-shared`

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-485

## **Manual testing steps**

1. Run `yarn build` — should complete with no errors
2. Run `yarn test` — all tests pass with 100% coverage
3. Run `yarn lint` — no errors

## **Screenshots/Recordings**

### **After**

no visual changes


https://github.com/user-attachments/assets/f5fa6c56-39c4-4a12-ae68-dff0f815b3b4

## **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
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **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.


<div><a
href="https://cursor.com/agents/bc-4b0130be-b329-4548-8988-f73a378b9712"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/automations/864f6729-e11f-445a-9607-65e9539d53c1"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/view-automation-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/view-automation-light.png"><img
alt="View Automation" width="141" height="28"
src="https://cursor.com/assets/images/view-automation-dark.png"></picture></a>&nbsp;</div>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes exported `ButtonIcon` type/value
sources (enums → const objects) across both React and React Native
packages, which can break downstream imports or type expectations even
though runtime behavior is unchanged.
> 
> **Overview**
> Migrates `ButtonIcon` to the centralized shared-types architecture by
moving `ButtonIconSize`, `ButtonIconVariant`, and new
`ButtonIconPropsShared` into `@metamask/design-system-shared` (as
ADR-0003 string-union const objects) and exporting them from the shared
entrypoint.
> 
> Updates both `design-system-react` and `design-system-react-native` to
consume/re-export these shared types, refactors `ButtonIconProps` to
extend `ButtonIconPropsShared`, and removes the duplicated
`ButtonIconSize`/`ButtonIconVariant` enums from each platform’s
`types/index.ts`, along with updating affected consumers/tests/stories
(e.g., `BannerBase`, `KeyValue*`, and `ButtonIcon` files) to import from
shared.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
9143505. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: George Marshall <georgewrmarshall@users.noreply.github.com>
Co-authored-by: georgewrmarshall <george.marshall@consensys.net>
cursor Bot added a commit that referenced this pull request Apr 28, 2026
## **Description**

Migrates the `ButtonIcon` component to follow ADR-0003 (String Unions)
and ADR-0004 (Centralized Types Architecture).

**Changes:**
- Creates `ButtonIconSize` and `ButtonIconVariant` const objects in
`@metamask/design-system-shared` (ADR-0003), replacing the duplicate
TypeScript enums in both platform packages
- Creates `ButtonIconPropsShared` type in shared package (ADR-0004) with
platform-independent props (`iconName: string`, `size`, `isDisabled`,
`variant`)
- Updates `ButtonIconProps` in both React and React Native to import and
extend from shared (platform-specific props like `iconProps:
Partial<IconProps>`, `ariaLabel`, `className`/`twClassName`, and `style`
remain in platform packages)
- Updates `index.ts` files in both platform packages to re-export const
objects from shared
- Removes old `ButtonIconSize` and `ButtonIconVariant` enums from
platform `types/index.ts` files
- Updates all consumers (`ButtonIcon.tsx`, `ButtonIcon.constants.ts`,
`ButtonIcon.stories.tsx`, `ButtonIcon.test.tsx`, `BannerBase.tsx`) to
import from `@metamask/design-system-shared`

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-485

## **Manual testing steps**

1. Run `yarn build` — should complete with no errors
2. Run `yarn test` — all tests pass with 100% coverage
3. Run `yarn lint` — no errors

## **Screenshots/Recordings**

### **After**

no visual changes


https://github.com/user-attachments/assets/f5fa6c56-39c4-4a12-ae68-dff0f815b3b4

## **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
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **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.


<div><a
href="https://cursor.com/agents/bc-4b0130be-b329-4548-8988-f73a378b9712"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/automations/864f6729-e11f-445a-9607-65e9539d53c1"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/view-automation-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/view-automation-light.png"><img
alt="View Automation" width="141" height="28"
src="https://cursor.com/assets/images/view-automation-dark.png"></picture></a>&nbsp;</div>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes exported `ButtonIcon` type/value
sources (enums → const objects) across both React and React Native
packages, which can break downstream imports or type expectations even
though runtime behavior is unchanged.
> 
> **Overview**
> Migrates `ButtonIcon` to the centralized shared-types architecture by
moving `ButtonIconSize`, `ButtonIconVariant`, and new
`ButtonIconPropsShared` into `@metamask/design-system-shared` (as
ADR-0003 string-union const objects) and exporting them from the shared
entrypoint.
> 
> Updates both `design-system-react` and `design-system-react-native` to
consume/re-export these shared types, refactors `ButtonIconProps` to
extend `ButtonIconPropsShared`, and removes the duplicated
`ButtonIconSize`/`ButtonIconVariant` enums from each platform’s
`types/index.ts`, along with updating affected consumers/tests/stories
(e.g., `BannerBase`, `KeyValue*`, and `ButtonIcon` files) to import from
shared.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
9143505. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: George Marshall <georgewrmarshall@users.noreply.github.com>
Co-authored-by: georgewrmarshall <george.marshall@consensys.net>
@georgewrmarshall georgewrmarshall mentioned this pull request Apr 30, 2026
18 tasks
georgewrmarshall added a commit that referenced this pull request Apr 30, 2026
## Release 37.0.0

This release focuses on consumer-facing changelog cleanup for the
packages being published, plus migration-guide coverage for the React
Native `TextField` API changes included in this release.

### 📦 Package Versions

- `@metamask/design-system-shared`: **0.15.0**
- `@metamask/design-system-react`: **0.20.0**
- `@metamask/design-system-react-native`: **0.22.0**

### 🔄 Shared Type Updates (0.15.0)

#### Shared type additions
([#1034](#1034),
[#1038](#1038),
[#1081](#1081))

**What Changed:**

- Added shared `ButtonBaseSize`, `ButtonSize`, `ButtonHeroSize`,
`ButtonVariant`, `ButtonBasePropsShared`, and `ButtonPropsShared`
- Added shared `ButtonIconSize`, `ButtonIconVariant`, and
`ButtonIconPropsShared`
- Added shared `TextFieldPropsShared` for the controlled text-field
contract used across platforms

**Impact:**

- Continues ADR-0003 and ADR-0004 migration toward shared const-object
plus string-union exports
- Gives React and React Native one shared source of truth for these
component contracts

### 🌐 React Web Updates (0.20.0)

#### Changed

- **BREAKING:** Updated `Button`, `ButtonBase`, and `ButtonHero` size
and variant exports to use shared const-object + string-union types
rather than platform-local enum-based definitions
([#1034](#1034))
- No migration required for typical usage; continue importing from
`@metamask/design-system-react` as before
- **BREAKING:** Updated `ButtonIconSize` and `ButtonIconVariant` to use
shared const-object + string-union types rather than platform-local
enum-based definitions
([#1038](#1038))
- No migration required for typical usage; continue importing from
`@metamask/design-system-react` as before
- Updated Figma Code Connect to the live `MMDS Components` file and
aligned `ButtonIcon` and `TextButton` mappings with the current
component APIs shown in Dev Mode
([#1109](#1109))
- Expanded the `TextButton` migration guide for extension consumers
replacing `ButtonLink` and `ButtonVariant.Link` with the current
design-system APIs
([#1098](#1098))

### 📱 React Native Updates (0.22.0)

#### Changed

- **BREAKING:** Updated `Button`, `ButtonBase`, and `ButtonHero` size
and variant exports to use shared const-object + string-union types
rather than platform-local enum-based definitions
([#1034](#1034))
- No migration required for typical usage; continue importing from
`@metamask/design-system-react-native` as before
- **BREAKING:** Updated `ButtonIconSize` and `ButtonIconVariant` to use
shared const-object + string-union types rather than platform-local
enum-based definitions
([#1038](#1038))
- No migration required for typical usage; continue importing from
`@metamask/design-system-react-native` as before
- **BREAKING:** `TextField` and `TextFieldSearch` now use a root
`Box`/`View`, require native `TextInput` props under `inputProps`,
rename `isReadonly` to `isReadOnly`, and use `inputRef` for the inner
input ref
([#1081](#1081))
- Updated Figma Code Connect to the live `MMDS Components` file and
aligned `ButtonIcon` and `TextButton` mappings with the current
component APIs shown in Dev Mode
([#1109](#1109))

### ⚠️ Breaking Changes

#### Shared button size and variant exports (Both Platforms)

**What Changed:**

- `ButtonVariant`, `ButtonBaseSize`, `ButtonSize`, `ButtonHeroSize`,
`ButtonIconSize`, and `ButtonIconVariant` now come from shared
ADR-0003/ADR-0004 definitions instead of platform-local enums
- Runtime values and standard imports remain stable for typical usage

**Impact:**

- Affects TypeScript consumers that depended on enum-specific behavior
rather than the exported members themselves

#### React Native TextField prop layering (React Native)

**What Changed:**

- `TextField` and `TextFieldSearch` now treat the root as a `Box`/`View`
- Native `TextInput` props must move under `inputProps`
- `isReadonly` is renamed to `isReadOnly`
- `ref` now targets the outer container and `inputRef` targets the inner
`TextInput`

**Migration:**

```tsx
// Before (0.21.0)
<TextField
  value={query}
  onChangeText={setQuery}
  placeholder="Search"
  keyboardType="default"
  secureTextEntry
  onFocus={handleFocus}
/>

// After (0.22.0)
<TextField
  value={query}
  onChangeText={setQuery}
  placeholder="Search"
  onFocus={handleFocus}
  inputProps={{
    keyboardType: 'default',
    secureTextEntry: true,
  }}
/>
```

**Impact:**

- Affects React Native consumers passing `TextInput` props or
pressable-only props at the top level of `TextField` / `TextFieldSearch`

See migration guides for complete instructions:

- [React Native Migration
Guide](./packages/design-system-react-native/MIGRATION.md#from-version-0210-to-0220)

### ✅ 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.14.0` → `0.15.0`) - shared type
additions
- [x] design-system-react: minor (`0.19.0` → `0.20.0`) - includes
breaking changes under pre-1.0 semver
- [x] design-system-react-native: minor (`0.21.0` → `0.22.0`) - includes
breaking changes under pre-1.0 semver
- [x] Breaking changes documented with migration guidance where needed
- [x] Migration guides updated with before/after examples for the React
Native `TextField` 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**

- [ ] 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 where migration
guidance is required
- [ ] All unreleased changes are accounted for in changelogs

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Release-only change: bumps package versions and updates
changelog/migration documentation without modifying runtime code. Low
risk aside from potential downstream confusion if documented breaking
changes don’t match what was actually published.
> 
> **Overview**
> Bumps the monorepo release to `37.0.0` and increments package versions
for `@metamask/design-system-shared` (`0.15.0`),
`@metamask/design-system-react` (`0.20.0`), and
`@metamask/design-system-react-native` (`0.22.0`).
> 
> Updates consumer-facing release notes: adds new changelog entries
(including documented *breaking* type-export contract changes and RN
`TextField` API migration details), refreshes the RN migration guide
section for `0.21.0` → `0.22.0`, and updates changelog compare links
accordingly.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
2140b12. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants