Skip to content

feat: Add Tag component for React#1211

Merged
amandaye0h merged 5 commits into
mainfrom
tag/extension
Jun 5, 2026
Merged

feat: Add Tag component for React#1211
amandaye0h merged 5 commits into
mainfrom
tag/extension

Conversation

@amandaye0h

@amandaye0h amandaye0h commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Description

What is the reason for the change

The MetaMask Design System already ships Tag for React Native, but the React (@metamask/design-system-react) package did not expose an equivalent component.

What is the improvement/solution?

This PR adds a React Tag component that mirrors the React Native component. It includes Storybook stories and docs (including a vertically stacked Severity story to match RN), unit tests, package exports, and Figma Code Connect for the MMDS Tag component. Consumers can import Tag from @metamask/design-system-react and use it consistently with the design system in Figma Dev Mode.
-->

Related issues

Fixes:

Manual testing steps

  • Run yarn build && yarn storybook
  • Cross check there are no visual differences from the React Native and Figma components

Screenshots/Recordings

Before

Legacy Component

02-tag-legacy.mov

Note: The correct instance referenced is the tag with the label Native Segwit, not Earn. The former is part of component-library, latter was built by feature teams.

After

React Component

01-tag-react.mov

Comparison with React Native

03-tag-rn.mov

Comparison with Figma

04-tag-figma.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.

Note

Low Risk
New presentational UI in the design-system package with tests and docs; no auth, data, or runtime behavior changes for consumers until they adopt the export.

Overview
Adds a React Tag to @metamask/design-system-react, aligning web with the existing React Native and shared TagPropsShared / TagSeverity APIs.

The implementation maps severities to muted backgrounds and semantic text/icon colors, wraps string labels in Text (BodyXs, medium), and supports start/end icons (via name or *IconProps) or custom accessories on a Box root with twMerge for className. Tag and TagSeverity are exported from the package barrel.

Also ships Storybook (MDX + severity/icon/accessory stories), unit tests, and Figma Code Connect for the MMDS Tag node.

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

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@amandaye0h amandaye0h marked this pull request as ready for review June 4, 2026 10:54
@amandaye0h amandaye0h requested a review from a team as a code owner June 4, 2026 10:54

@cursor cursor Bot left a comment

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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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 34a7dd9. Configure here.

Comment thread packages/design-system-react/src/components/Tag/README.mdx Outdated
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@georgewrmarshall georgewrmarshall left a comment

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.

Thanks for adding the React Tag implementation. The component structure looks good, and the tests cover the main API paths clearly.

I left a few non-blocking suggestions around docs/story consistency. None of these need to block this PR, and I'm happy for them to be handled in a follow-up PR if that's easier. The main reason I'm calling them out is to keep the React docs aligned with our README template, keep severity naming moving toward Danger, and make the Storybook examples more representative of production usage.


<Canvas of={TagStories.Default} />

## Props

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.

non-blocking: Could we update this README to follow the React README template in docs/component-readme-examples/react-readme-example.mdx? That template includes the standard prop tables, per-prop Canvas examples, Component API, and references sections, which keeps the generated docs consistent with the rest of the design system. This can be handled in a follow-up PR.

> = {
[TagSeverity.Neutral]: BoxBackgroundColor.BackgroundMuted,
[TagSeverity.Success]: BoxBackgroundColor.SuccessMuted,
[TagSeverity.Error]: BoxBackgroundColor.ErrorMuted,

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.

non-blocking: We are moving severity APIs toward Danger instead of Error in #1159. Could we align the new React Tag API/docs/stories with TagSeverity.Danger so this component does not reintroduce the older severity vocabulary? This can be handled in a follow-up PR.

children: 'Tag',
severity: TagSeverity.Neutral,
},
};

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.

non-blocking: Could we use Box here instead of a raw div? The Cursor styling rules prefer design system primitives in examples, and it helps the story model the same composition we want consumers to copy. This can be handled in a follow-up PR.

};

export const EndIconName: Story = {
render: () => <Tag endIconName={IconName.ArrowRight}>Tag</Tag>,

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.

non-blocking: The accessory examples would be more production-like if they used an Icon or another design-system element instead of arrow glyph spans. That makes the examples a better reference for expected usage. This can be handled in a follow-up PR.

@amandaye0h

Copy link
Copy Markdown
Contributor Author

Thanks @georgewrmarshall for the quick review. I'll file follow up PRs so we can hit our migration target for the week.

@amandaye0h amandaye0h enabled auto-merge (squash) June 5, 2026 07:00
@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@amandaye0h amandaye0h merged commit ce127e0 into main Jun 5, 2026
36 checks passed
@amandaye0h amandaye0h deleted the tag/extension branch June 5, 2026 07:04
@georgewrmarshall georgewrmarshall mentioned this pull request Jun 9, 2026
18 tasks
georgewrmarshall added a commit that referenced this pull request Jun 9, 2026
## Release 44.0.0

This release adds `Toast`/`Toaster` and `Tag` to React, `ListItem` to
React Native, aligns the `TextButton` API across platforms, and
standardizes severity vocabulary (`Error` → `Danger`) across
`AvatarIcon`, `IconAlert`, and `Tag`.

### 📦 Package Versions

- `@metamask/design-system-shared`: **0.22.0**
- `@metamask/design-system-react`: **0.26.0**
- `@metamask/design-system-react-native`: **0.29.0**

### 🔄 Shared Type Updates (0.22.0)

#### New shared types (#1190, #1203, #1224, #1225)

**What Changed:**

- Added `ToastPropsShared` and `ToastSeverity` for cross-platform
`Toast` support
- Added `ListItemPropsShared` and related types for cross-platform
`ListItem` support
- Added `TextButtonPropsShared` to align `TextButton` API across React
and React Native
- Added `AvatarNetworkSize` as a named export from the shared package

**Impact:**

- Enables consistent `Toast` and `ListItem` implementations across both
platforms
- Continues ADR-0003/0004 const-object + string-union pattern adoption

#### Severity vocabulary: `.Error` → `.Danger`
([#1159](#1159))

**What Changed:**

- `AvatarIconSeverity.Error` → `AvatarIconSeverity.Danger`
- `IconAlertSeverity.Error` → `IconAlertSeverity.Danger`
- `TagSeverity.Error` → `TagSeverity.Danger`

**Impact:**

- Breaking change for any consumer using `.Error` on these three const
objects. Rendered colors are unchanged.

### 🌐 React Web Updates (0.26.0)

#### Added

- Added `Tag` component for categorization and filtering labels
([#1211](#1211))
- Added `Toast` component with `Toaster` provider and imperative
`toast()` API
([#1190](#1190))

#### Changed

- **BREAKING:** `TextButton` API aligned with React Native —
`size`/`TextButtonSize` replaced by `variant`/`TextVariant`;
`isInverse`, `isDisabled`, `textProps`, and icon/accessory props
removed; `asChild` added
([#1224](#1224))
- **BREAKING:** `AvatarIconSeverity.Error` → `AvatarIconSeverity.Danger`
([#1159](#1159))

#### Fixed

- Fixed `Toast` to support `toast()` calls made before `Toaster` mounts
([#1217](#1217))

### 📱 React Native Updates (0.29.0)

#### Added

- Added `ListItem` component for list row layouts
([#1203](#1203))
- Added `Toast` component with `Toaster` provider and imperative
`toast()` API
([#1190](#1190))

#### Changed

- **BREAKING:** `AvatarIconSeverity.Error`, `IconAlertSeverity.Error`,
and `TagSeverity.Error` → `.Danger`
([#1159](#1159))

### ⚠️ Breaking Changes

#### TextButton rewrite (React Web Only)

**What Changed:**

- `size` / `TextButtonSize` removed — use `variant` / `TextVariant`
instead
- `isInverse`, `isDisabled`, `textProps`, start/end icons, and accessory
slots removed
- `asChild` added for semantic link composition

**Migration:**

```tsx
// Before (0.25.0)
import { TextButton, TextButtonSize } from '@metamask/design-system-react';
<TextButton size={TextButtonSize.BodySm}>Learn more</TextButton>

// After (0.26.0)
import { TextButton } from '@metamask/design-system-react';
import { TextVariant } from '@metamask/design-system-shared';
<TextButton variant={TextVariant.BodySm}>Learn more</TextButton>
```

See [React Migration
Guide](./packages/design-system-react/MIGRATION.md#from-version-0250-to-0260)

#### Severity vocabulary: `.Error` → `.Danger` (Both Platforms)

**What Changed:**

- `AvatarIconSeverity.Error` → `AvatarIconSeverity.Danger` (React +
React Native)
- `IconAlertSeverity.Error` → `IconAlertSeverity.Danger` (React Native)
- `TagSeverity.Error` → `TagSeverity.Danger` (React Native)

**Migration:**

```tsx
// Before
<AvatarIcon severity={AvatarIconSeverity.Error} />
<IconAlert severity={IconAlertSeverity.Error} />
<Tag severity={TagSeverity.Error}>High risk</Tag>

// After
<AvatarIcon severity={AvatarIconSeverity.Danger} />
<IconAlert severity={IconAlertSeverity.Danger} />
<Tag severity={TagSeverity.Danger}>High risk</Tag>
```

See migration guides for complete instructions:

- [React Migration
Guide](./packages/design-system-react/MIGRATION.md#from-version-0250-to-0260)
- [React Native Migration
Guide](./packages/design-system-react-native/MIGRATION.md#from-version-0280-to-0290)

### ✅ 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.21.0 → 0.22.0) - new shared types +
breaking severity rename
- [x] design-system-react: minor (0.25.0 → 0.26.0) - new components +
breaking API changes
- [x] design-system-react-native: minor (0.28.0 → 0.29.0) - new
components + breaking severity rename
- [x] Breaking changes documented with migration guidance
- [x] Migration guides updated with before/after examples
- [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 with examples
- [ ] All unreleased changes are accounted for in changelogs

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> The release documents multiple breaking consumer APIs (TextButton on
web, severity `.Error`→`.Danger`); upgrading without following
MIGRATION.md will cause compile/runtime mismatches, though this PR does
not change component implementation itself.
> 
> **Overview**
> **Release 44.0.0** cuts new versions of the design-system packages and
records what shipped since the last release: monorepo root **43.0.0 →
44.0.0**, `@metamask/design-system-shared` **0.22.0**,
`@metamask/design-system-react` **0.26.0**, and
`@metamask/design-system-react-native` **0.29.0**.
> 
> Changelogs document **React** additions (`Tag`,
`Toast`/`Toaster`/`toast()`), a **breaking** `TextButton` rewrite
(`size`/`TextButtonSize` → `variant`/`TextVariant`, dropped
inverse/disabled/icons, added `asChild`), and
**`AvatarIconSeverity.Error` → `.Danger`**. **React Native** adds
**`ListItem`** and the same **severity rename** on `AvatarIcon`,
`IconAlert`, and `Tag`. **Shared** adds cross-platform types
(`ListItem`, `Toast`, `TextButton`, `AvatarNetworkSize`) and the shared
**`.Error` → `.Danger`** severity vocabulary.
> 
> **MIGRATION.md** on React and React Native gains **0.25→0.26** and
**0.28→0.29** sections with before/after examples. The only non-release
code change in the diff is reordering the `react-native-worklets`
devDependency in `apps/storybook-react-native/package.json`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
9c3345f. 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.

2 participants