feat: TextField migration (extension)#1170
Conversation
📖 Storybook Preview |
📖 Storybook Preview |
brianacnguyen
left a comment
There was a problem hiding this comment.
Can you address Bugbot comments?
📖 Storybook Preview |
brianacnguyen
left a comment
There was a problem hiding this comment.
do you think you can extract TextField types out to shared like the other components we've been migrating?
a4daf39 to
5fda8a6
Compare
📖 Storybook Preview |
There was a problem hiding this comment.
The implementation and MIGRATION.md are solid, but the TextFieldPropsShared additions need to be addressed before merging — several props added to the shared type are either HTML-specific or were deliberately removed from the RN platform. See inline comments for the full breakdown.
One additional item not capturable as an inline comment: the focused border color differs between platforms. The React implementation uses border-primary-default (blue) while the RN TextField uses border-default (gray) — worth aligning
| * | ||
| * @default TextFieldSize.Md | ||
| */ | ||
| size?: TextFieldSize; |
There was a problem hiding this comment.
These props added to TextFieldPropsShared need to move to the React-only TextFieldProps. Cross-referencing against the RN TextField implementation:
size— removed from RN as a breaking change in v0.12.0 (PR refactor: updated Input and TextField to align with mobile fixes #1000); implementation hardcodesh-12type— HTMLinputattribute with no RN equivalent; RN consumers useinputProps.keyboardType/inputProps.secureTextEntryinstead; falls through toBoxvia...propstruncate— RN hardcodesnumberOfLines={1}; prop is not consumedname/id/required— HTML form attributes with no RN equivalent; fall through toBoxvia...propsmaxLength— RNTextInputsupports this natively but the RNTextFielddoesn't destructure or forward it to the innerInput, so it currently falls through toBoxinstead
The props that correctly belong in shared are: isError, startAccessory, endAccessory, and inputElement. Once the web-only props move to the React layer, TextFieldSize and TextFieldType const objects can also move to the React package since nothing in shared will reference them.
| placeholder: 'Sample placeholder', | ||
| value: '', | ||
| }, | ||
| render: (args) => <ControlledTextField {...args} />, |
There was a problem hiding this comment.
non-blocking: The Default story renders via <ControlledTextField>, so Storybook's "View Code" panel shows that wrapper name instead of <TextField>. Since that panel is intended to be a copy-pasteable example, consider inlining useState directly in the render function so <TextField> is the visible root element.
5fda8a6 to
27d5e9f
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 27d5e9f. Configure here.
📖 Storybook Preview |
There was a problem hiding this comment.
LGTM! The two blocking issues from round 1 are properly resolved: web-only props (TextFieldSize, TextFieldType, size, type, truncate, name, id, required, maxLength) correctly moved out of shared into the React package, and the TextFieldInputProps Omit list now covers all props that would silently collide with top-level ones. The Default story inline state fix and className control removal are also done. Nice work. Approved!
OOO and issues have been resolved
📖 Storybook Preview |
## Release 42.0.0 This release curates the changelogs for three published packages into consumer-facing Keep a Changelog entries. It adds the `FlashFilled` icon and `SelectButtonSize` across platforms, adds the `TextField` component to React web, and ships two React Native breaking changes: the `panGestureHandlerProps` removal (part of the `react-native-gesture-handler` v2 migration) and the removal of the variant-based title API from `HeaderBase`/`BottomSheetHeader`. ### 📦 Package Versions - `@metamask/design-system-shared`: **0.20.0** (was 0.19.0) - `@metamask/design-system-react`: **0.24.0** (was 0.23.1) - `@metamask/design-system-react-native`: **0.27.0** (was 0.26.0) > `@metamask/design-tokens`, `@metamask/design-system-tailwind-preset`, and `@metamask/design-system-twrnc-preset` are unchanged in this release. ### 🔄 Shared Type Updates (0.20.0) #### Component Type Additions (#1191, #1177, #1170) **What Changed:** - Added `FlashFilled` to the `IconName` const so the filled lightning bolt is available on both platforms. - Added `SelectButtonSize` so `SelectButton` exposes a semantic size type shared across platforms. - Added `TextFieldPropsShared` for the cross-platform text field input contract. **Impact:** - Additive only — no breaking changes to the shared package. - Continues the ADR-0003/0004 const-object + centralized-types pattern. ### 🌐 React Web Updates (0.24.0) #### Added - Added `TextField` for labeled text entry with optional helper and validation text, exposing `TextFieldSize` and `TextFieldType` (#1170) - Added `FlashFilled` icon (filled lightning bolt) to `IconName` (#1191) ### 📱 React Native Updates (0.27.0) #### Added - Added `FlashFilled` icon (filled lightning bolt) to `IconName` (#1191) - Added `SelectButtonSize` so `SelectButton` exposes a semantic size type (#1177) #### Changed - **BREAKING:** Removed `panGestureHandlerProps` from `BottomSheet` and `BottomSheetDialog` following the migration to the `react-native-gesture-handler` v2 `GestureDetector`/`Gesture.Pan()` API (#1165) - Migration: [From version 0.26.0 to 0.27.0](./packages/design-system-react-native/MIGRATION.md#from-version-0260-to-0270) - **BREAKING:** Removed the variant-based title API from `HeaderBase` and `BottomSheetHeader` — `variant`, `HeaderBaseVariant`, `BottomSheetHeaderVariant`, and `HeaderBase`'s `titleTestID` (#1103) - String titles now render with a centered `HeadingSm` treatment; pass custom `children` for bespoke title layouts and use `textProps.testID` in place of `titleTestID` - Migration: [From version 0.26.0 to 0.27.0](./packages/design-system-react-native/MIGRATION.md#from-version-0260-to-0270) - Reduced the default `SegmentGroup` segment spacing from `gap-3` to `gap-1` for tighter grouped segments (#1194) #### Fixed - Fixed a `HeaderStandardAnimated` runtime crash under React Native Reanimated 4 by inlining the scroll-handler worklet (#1185) - Fixed React Native Web rendering for `BottomSheet`, `BottomSheetOverlay`, `Icon`, and the animated `ButtonAnimated` and `Spinner` components (#1187) ###⚠️ Breaking Changes #### Removed `panGestureHandlerProps` from `BottomSheet` / `BottomSheetDialog` (React Native Only) **What Changed:** - Removed the `panGestureHandlerProps` prop. The components migrated from the deprecated RNGH v1 `PanGestureHandler` JSX component to the v2 `GestureDetector` + `Gesture.Pan()` API. - `simultaneousHandlers` (the only real-world use case) was never wired up under the old shim, so no working behavior is lost. **Migration:** ```tsx // Before (0.26.0) <BottomSheet goBack={goBack} panGestureHandlerProps={{ simultaneousHandlers: scrollViewRef }} > {children} </BottomSheet> // After (0.27.0) <BottomSheet goBack={goBack}>{children}</BottomSheet> ``` #### Removed variant-based title API from `HeaderBase` / `BottomSheetHeader` (React Native Only) **What Changed:** - Removed `variant`, `HeaderBaseVariant`, `BottomSheetHeaderVariant`, and `HeaderBase`'s `titleTestID`. - String titles now render with a centered `HeadingSm` treatment; custom layouts use `children`, and `titleTestID` is replaced by `textProps.testID`. **Migration:** ```tsx // Before (0.26.0) import { HeaderBase, HeaderBaseVariant } from '@metamask/design-system-react-native'; <HeaderBase variant={HeaderBaseVariant.Display} titleTestID="title"> Account details </HeaderBase> // After (0.27.0) import { HeaderBase } from '@metamask/design-system-react-native'; <HeaderBase textProps={{ testID: 'title' }}>Account details</HeaderBase> ``` See migration guide for complete instructions: - [React Native Migration Guide — 0.26.0 to 0.27.0](./packages/design-system-react-native/MIGRATION.md#from-version-0260-to-0270) ### 🔗 Consumer note: MetaMask Mobile MetaMask Mobile currently consumes `@metamask/design-system-react-native@0.20.0` and applies a local yarn patch — `.yarn/patches/@metamask-design-system-react-native-npm-0.20.0-2ae4d6f1dd.patch` — to migrate `BottomSheetDialog` from `PanGestureHandler` to `GestureDetector` for its React Native Reanimated 4 upgrade ([MetaMask/metamask-mobile#29470](MetaMask/metamask-mobile#29470)). This release **upstreams that exact migration natively** (#1165). Once mobile bumps to `0.27.0`, it can **drop that yarn patch** — the package now uses the RNGH v2 `GestureDetector`/`Gesture.Pan()` API on its own. Compatibility note: the package keeps `react-native-reanimated` at `peerDependencies: >=3.17.0` (unchanged). It was validated against mobile's current Reanimated 3.19 and is forward-compatible with the incoming Reanimated 4.1.x (the #1185 worklet fix works on both), so no peer-dependency bump is required. ### ✅ 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.19.0 → 0.20.0) - additive type exports - [x] design-system-react: minor (0.23.1 → 0.24.0) - new `TextField` component + icon - [x] design-system-react-native: minor (0.26.0 → 0.27.0) - pre-1.0 minor with breaking changes - [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** - [ ] 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** > No runtime code in the diff, but the published React Native 0.27.0 changelog documents breaking BottomSheet and Header API changes that require consumer migrations. > > **Overview** > **Release 42.0.0** bumps the monorepo to **42.0.0** and publishes **@metamask/design-system-shared@0.20.0**, **@metamask/design-system-react@0.24.0**, and **@metamask/design-system-react-native@0.27.0** with finalized Keep a Changelog entries and compare links. > > The diff is mostly **release packaging**: version fields in root and package `package.json` files, new changelog sections for those versions, and doc updates. **React Native** docs drop **`panGestureHandlerProps`** from `BottomSheet` / `BottomSheetDialog` READMEs; **`MIGRATION.md`** adds a **0.26.0 → 0.27.0** section (bottom-sheet gesture prop removal, header title API) and moves **BannerBase** guidance under **0.24.0 → 0.25.0**. > > What consumers get in this release (documented in changelogs, not new code in this PR): shared **`FlashFilled`**, **`SelectButtonSize`**, **`TextFieldPropsShared`**; web **`TextField`** and **`FlashFilled`**; native **`FlashFilled`**, **`SelectButtonSize`**, two **breaking** API removals (`panGestureHandlerProps`, header **`variant`** / **`titleTestID`**), tighter **`SegmentGroup`** spacing, Reanimated 4 / RN Web fixes. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6710621. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->

Description
Added
TextFieldcomponent to DSR.Related issues
Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-316
Manual testing steps
TextFieldexampleScreenshots/Recordings
Before
After
Pre-merge author checklist
Pre-merge reviewer checklist
Note
Low Risk
New UI component with tests and documentation only; no changes to auth, data handling, or existing consumer runtime behavior until extensions adopt the new import.
Overview
Adds
TextFieldto@metamask/design-system-reactas the web implementation of the extension migration (DSYS-316): aforwardRefroot<div>that wraps design-systemInput, with Tailwind-based chrome (sizes, focus/error/disabled borders), optional start/end accessories, andinputElement/inputRef/inputPropsfor customization.Exports
TextField,TextFieldSize,TextFieldType, andTextFieldPropsfrom the package barrel; web-only size/type const objects extend sharedTextFieldPropsShared. Includes Storybook docs, stories, and unit tests.MIGRATION.mddocuments extension → design-system moves (disabled/readOnly/error→is*,InputComponent→inputElement, controlled-only, no polymorphic Box).Shared package: comment tweak on
TextFieldPropsSharedandexport { type ... }on the TextField types index.Reviewed by Cursor Bugbot for commit cbe0b8a. Bugbot is set up for automated code reviews on this repo. Configure here.