MetaMask / MetaMask/metamask-extension

Replace deprecated Button component with new Button component

Open
#18,896 8 comments 0 reactions 0 assignees View on GitHub
ai-eligible good first issue INVALID-ISSUE-TEMPLATE team-design-system
Dominant language
TypeScript
Stars
13.2k
Forks
5.6k
Avg merge
2d 5h
Merged PRs (30d)
451

Description

### Description

The extension still uses legacy Button implementations that should be migrated to the MMDS `Button` component from `@metamask/design-system-react`.

This issue is a reusable tracker for many small PRs. Do not try to migrate every Button usage in one PR. Each PR should migrate a small set of files completely and leave this issue open for the remaining work.

### Migration target

Migrate Button usage from both legacy extension sources:

- `ui/components/ui/button`
- `ui/components/component-library/button`

To the MMDS Button:

```ts
import { Button } from '@metamask/design-system-react';
```

The `ui/components/component-library` Button is **not** the destination for this migration. It is also part of the legacy extension Button surface that should eventually be replaced.

### Migration docs

Use the MMDS docs and migration guide when updating each file:

- [MMDS Button documentation](https://metamask.github.io/metamask-design-system/?path=/docs/react-components-button--docs)
- [MMDS Button migration guide](https://github.com/MetaMask/metamask-design-system/blob/main/packages/design-system-react/MIGRATION.md#button-component)
- [MMDS TextButton migration guide](https://github.com/MetaMask/metamask-design-system/blob/main/packages/design-system-react/MIGRATION.md#textbutton-component-from-buttonlink) for legacy link-style button usage

Pay special attention to prop, variant, size, and type differences. This should not be treated as an import-only migration.

### Common failure mode

A PR that changes imports from `ui/components/ui/button` to `ui/components/component-library` does **not** complete this migration. The selected files must import `Button` from `@metamask/design-system-react` and update any incompatible props/types.

Legacy `Button` usages with `ButtonVariant.Link`, `href`, `as`, or other link-style behavior may need to migrate to `TextButton` instead of MMDS `Button`. Follow the migration guide for those cases.

### PR scope and linking

- PRs should contain no more than 3 migrated product files. Necessary test, snapshot, or story updates may be included alongside those files.
- Do **not** use auto-closing keywords such as `Fixes #18896`, `Closes #18896`, or `Resolves #18896`.
- Use `Part of #18896` or `Part of: https://github.com/MetaMask/metamask-extension/issues/18896` so this tracker stays open until all legacy Button usage is migrated.

### Type and API requirements

For every migrated file:

- Audit the Button props being used; do not only change the import path.
- Follow the [MMDS Button migration guide](https://github.com/MetaMask/metamask-design-system/blob/main/packages/design-system-react/MIGRATION.md#button-component) for renamed props such as `disabled` -> `isDisabled`, `loading` -> `isLoading`, `block` -> `isFullWidth`, and `danger` -> `isDanger`.
- Replace unsupported sizes such as `ButtonSize.Inherit` and `ButtonSize.Auto` with supported MMDS behavior.
- Replace unsupported polymorphic/link props such as `as`, `href`, and `externalLink` with the correct MMDS pattern or `TextButton` where appropriate.
- Update imported Button-related constants/types to MMDS exports where applicable.
- Do not add broad `any`, unsafe casts, or type suppressions to force compatibility.
- Fix TypeScript, Flow, Jest, or lint failures caused by Button prop/type differences.

### Acceptance Criteria

- Selected files no longer import `Button` from `ui/components/ui/button`, `ui/components/component-library`, or `ui/components/component-library/button`.
- Selected files import `Button` from `@metamask/design-system-react`, or use the documented MMDS alternative such as `TextButton` for link-style button behavior.
- Any legacy Button props are migrated according to the MMDS Button migration guide.
- Type usage is updated cleanly with no new unsafe casts, `any`, or suppressions.
- Each PR migrates no more than 3 product files, excluding necessary tests, snapshots, or stories.
- Each PR links this issue with `Part of`, not an auto-closing keyword.
- Relevant Jest tests pass.
- Lint/type checks pass for touched files or for the repo's normal validation command.
- Before/after screenshots are included for reachable UI. If the UI is unreachable or dead code, the PR must clearly prove that with search evidence and still include test coverage where possible.

If the acceptance criteria are not met, PRs may be closed.

### Difficulty: Intermediate

Good first issue for external contributors who are familiar with running the extension locally, React component props, type checking, Jest tests, linting, and Storybook.

Contributor guide

Open the contributing guide

Research direction

Search the legacy Button imports under ui/components/ui/button and ui/components/component-library, then select no more than three product files for one migration PR. Read the MMDS Button and TextButton migration guides first, audit props and types, and confirm completion with relevant Jest tests plus the repository's normal lint and type checks.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend
Issue type
Refactor
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.