docs: add TextButton migration (extension)#1098
Conversation
📖 Storybook Preview |
georgewrmarshall
left a comment
There was a problem hiding this comment.
Compared the new TextButton migration docs against extension button-link / Button variant={ButtonVariant.Link} and the current MMDS TextButton implementation. I left a couple of inline comments where the migration guide overstates or misstates the supported API.
| | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | | ||
| | `ellipsis` | Removed — use `className="truncate"` or `textProps` with truncation classes | | ||
| | `textDirection` | Removed — set the standard HTML `dir` attribute directly | | ||
| | `block` (inherited from `ButtonBase`) | Removed — `TextButton` is inline-styled; wrap with `asChild` and a block element if needed | |
There was a problem hiding this comment.
suggestion: I don't think block is removed here. TextButton still inherits isFullWidth from ButtonBaseProps because TextButtonProps only omits className, disabled/loading props, style, and size before reintroducing its own fields: TextButton.types.ts#L4-L14. The component then forwards the remaining props to ButtonBase: TextButton.tsx#L46-L56. I think the migration should map extension block to isFullWidth rather than calling it unsupported.
|
|
||
| `TextButton` adds props not available in the extension `ButtonLink`: | ||
|
|
||
| - `isInverse` — inverse coloring for use on dark or colored backgrounds |
There was a problem hiding this comment.
non-blocking: This "new props" list looks broader than the actual delta. On the extension side, ButtonLink already inherited textProps from ButtonBaseStyleUtilityProps: button-link.types.ts#L19-L20, button-base.types.ts#L83-L86. It also already inherited DOM/ARIA props through PolymorphicComponentPropWithRef: button-link.types.ts#L42-L43, box.types.ts#L218-L231. className was also already part of the extension surface: button-link.tsx#L30-L31. The genuinely new pieces here seem more like isInverse and asChild.
📖 Storybook Preview |
📖 Storybook Preview |
georgewrmarshall
left a comment
There was a problem hiding this comment.
non-blocking: In the ellipsis migration row, could we call out textProps={{ ellipsis: true }} explicitly for string children? TextButton forwards textProps through ButtonBase to the inner Text, so that reads closer to the legacy ButtonLink behavior than only mentioning truncation classes. For non-string children, a custom truncating wrapper or classes still makes sense.
eb97b6c to
f997553
Compare
📖 Storybook Preview |
georgewrmarshall
left a comment
There was a problem hiding this comment.
I re-checked the current extension ButtonLink migration text against the React Native guidance. I only found one docs consistency point worth calling out.
| The legacy `ButtonLink` (and `Button` with `variant={ButtonVariant.Link}`) is replaced by **two** design system components depending on the use case: | ||
|
|
||
| - **`TextButton`** — for inline text-styled links within content flows (the primary replacement) | ||
| - **`Button` with `variant={ButtonVariant.Tertiary}`** — for standalone link-styled buttons that still need `isDanger`, `isLoading`, or full button affordances |
There was a problem hiding this comment.
non-blocking: The Button tertiary fallback guidance could be framed more consistently with the React Native migration docs. The important migration rule across both packages is that TextButton is the inline-link replacement, while Button with variant={ButtonVariant.Tertiary} is the path when the legacy link needed more button-like affordances such as isFullWidth or danger/loading/custom visual treatment. The current docs already say this in places, but tightening that framing here would make the migration story more consistent across packages.
f997553 to
3a530b2
Compare
📖 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 3a530b2. Configure here.
|
|
||
| | Extension Prop | Design System Migration | | ||
| | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | ||
| | `ellipsis` | Removed — use `className="truncate"` or `textProps` with truncation classes | |
There was a problem hiding this comment.
Migration recommends CSS over component API for ellipsis
Low Severity
The ellipsis migration guidance suggests className="truncate" as the primary approach, but the Text component exposes a dedicated ellipsis boolean prop, and textProps accepts Partial<TextProps>. The recommended migration path is textProps={{ ellipsis: true }}, which uses the component's own API rather than a generic Tailwind class. This violates the rule requiring migration guides to prefer the component API over generic CSS when the component supports it.
Triggered by learned rule: Migration guides must only reference public API
Reviewed by Cursor Bugbot for commit 3a530b2. Configure here.
📖 Storybook Preview |
## 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 -->


Description
Added migration for
TextButton(extension part).Related issues
Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-637
Manual testing steps
MIGRATION.MDfileTextButtonmigration is in placeScreenshots/Recordings
Before
N/A
After
Pre-merge author checklist
Pre-merge reviewer checklist
Note
Low Risk
Documentation-only changes that add migration guidance; no runtime code paths are modified.
Overview
Adds a new
TextButtonmigration section toMIGRATION.md, documenting how to replace extensionButtonLinkandButtonvariant={ButtonVariant.Link}with design-systemTextButton(and when to useButtonvariant={ButtonVariant.Tertiary}forisDanger/isLoading/button-like behaviors).Includes detailed prop/enum mappings (notably
TextButtonSizeas typography), removed/renamed prop guidance (disabled→isDisabled,block→isFullWidth,as/href→asChild), and before/after code examples; also links this guide from theTextButtondocs (README.mdx).Reviewed by Cursor Bugbot for commit 4e66515. Bugbot is set up for automated code reviews on this repo. Configure here.