Skip to content

feat: TextFieldSearch migration (extension)#1171

Merged
kirillzyusko merged 7 commits into
mainfrom
fix/text-field-search-migration
Jun 3, 2026
Merged

feat: TextFieldSearch migration (extension)#1171
kirillzyusko merged 7 commits into
mainfrom
fix/text-field-search-migration

Conversation

@kirillzyusko

@kirillzyusko kirillzyusko commented May 12, 2026

Copy link
Copy Markdown
Collaborator

Description

Added TextFieldSearch component.

Related issues

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

Manual testing steps

  1. Open Storybook
  2. Check TextFieldSearch component

Screenshots/Recordings

Before

image

After

image

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 UI component and documentation with test coverage; no auth, data, or core runtime path changes.

Overview
Adds TextFieldSearch to @metamask/design-system-react: a controlled search field on top of TextField with a default search icon, fixed type="search", pill styling, and a trailing clear ButtonIcon when value is set. clearButtonOnClick is required; clear label defaults to 'Clear' and can be localized via clearButtonProps.ariaLabel (replacing extension useI18nContext). The package exports the component and documents extension migration in MIGRATION.md (TextFieldSearchSizeTextFieldSize, is* state props, removed polymorphic as / configurable type).

Ships Storybook (README.mdx, stories) and unit tests for rendering, clear-button behavior, and TextField forwarding.

FormTextField docs/tests/stories are adjusted only: stories use inline state / Box instead of a shared controlled helper; tests drop size-class assertions and assert textFieldProps on the inner field via title.

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

@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@kirillzyusko kirillzyusko marked this pull request as ready for review May 12, 2026 12:17
@kirillzyusko kirillzyusko requested a review from a team as a code owner May 12, 2026 12:17
Comment thread packages/design-system-react/src/components/TextFieldSearch/TextFieldSearch.tsx Outdated
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@brianacnguyen brianacnguyen 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.

can you extract the types out to design-system-shared?

@kirillzyusko kirillzyusko force-pushed the feat/text-field-migration-extension branch from a4daf39 to 5fda8a6 Compare May 13, 2026 16:05
@kirillzyusko kirillzyusko force-pushed the feat/text-field-migration-extension branch from 5fda8a6 to 27d5e9f Compare May 22, 2026 14:42
Base automatically changed from feat/text-field-migration-extension to main May 25, 2026 22:45
@kirillzyusko kirillzyusko force-pushed the fix/text-field-search-migration branch from a5e798a to 226ff9b Compare June 1, 2026 09:53
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@github-actions

github-actions Bot commented Jun 1, 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.

Solid work bringing TextFieldSearch into the design system react! ADR-0003/0004 architecture is correct, the shared type is appropriately minimal, migration docs cover the main breaking changes well, and test coverage is thorough 🔥

I've approved incase you want to merge and address the comments below in a follow up PR.

import React, { forwardRef } from 'react';

import { ButtonIcon } from '../ButtonIcon';
import { ButtonIconSize } from '../ButtonIcon';

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.

suggestion: Merge into a single import:

import { ButtonIcon, ButtonIconSize } from '../ButtonIcon';

import { ButtonIconSize } from '../ButtonIcon';
import { Icon, IconName, IconSize } from '../Icon';
import { TextField } from '../TextField';
import { TextFieldType } from '../TextField/TextField.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.

suggestion: Prefer the module index over internal type file paths:

import { TextField, TextFieldType } from '../TextField';

Same pattern applies in TextFieldSearch.types.ts (line 3, '../ButtonIcon/ButtonIcon.types''../ButtonIcon') and TextFieldSearch.stories.tsx (line 4, '../TextField/TextField.types''../TextField').

<ButtonIcon
data-testid="text-field-search-clear-button"
ariaLabel="Clear"
iconName={IconName.Close}

@georgewrmarshall georgewrmarshall Jun 2, 2026

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.

suggestion: A few visual details differ from the RN implementation. I've reached out in slack to confirm but I think we want to align to the RN version

  • iconName={IconName.CircleX} on the clear button (vs Close here)
  • size={ButtonIconSize.Md} on the clear button (vs Sm here)
  • iconProps={{ color: IconColor.IconAlternative }} on the clear button icon
  • IconSize.Md + IconColor.IconAlternative on the search icon (vs IconSize.Sm with no explicit color here)
  • rounded-full container style for the pill shape

*
* @default true
*/
showClearButton?: boolean;

@georgewrmarshall georgewrmarshall Jun 2, 2026

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.

suggestion: An audit of the extension usages shows all instances either pass showClearButton={true} explicitly or rely on the default — no caller ever sets it to false. The RN implementation also has no equivalent prop; the clear button always appears when value is truthy. Worth removing showClearButton entirely to keep both platforms aligned and simplify the API.

/**
* Click handler for the clear button. Use it to reset the controlled `value`.
*/
clearButtonOnClick?: React.MouseEventHandler<HTMLButtonElement>;

@georgewrmarshall georgewrmarshall Jun 2, 2026

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.

suggestion: clearButtonOnClick is optional, so a visible clear button can render with no handler — clicking it silently does nothing. The RN equivalent (onPressClearButton) is required. Aligns with the showClearButton removal suggestion: if the button always shows when value is truthy, the handler should be required to match consumer expectations and the RN API.

<ControlledTextFieldSearch
placeholder="Without clear button"
value="hello"
showClearButton={false}

@georgewrmarshall georgewrmarshall Jun 2, 2026

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.

suggestion: When showClearButton={false}, the browser still renders its own native clear button for type="search" inputs on hover (see screen recording). If we remove showClearButton altogether and make the default always true this should no longer be an issue

textfieldsearch.clearbutton.mov

@kirillzyusko kirillzyusko enabled auto-merge (squash) June 3, 2026 07:44
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

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

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@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 173711f. Configure here.

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@kirillzyusko kirillzyusko merged commit de77eff into main Jun 3, 2026
36 checks passed
@kirillzyusko kirillzyusko deleted the fix/text-field-search-migration branch June 3, 2026 15:10
@georgewrmarshall georgewrmarshall mentioned this pull request Jun 4, 2026
18 tasks
georgewrmarshall added a commit that referenced this pull request Jun 4, 2026
## Release 43.0.0

This release drops Node.js 18 support across the release line, adds
several new components, and includes a small set of breaking API changes
that are documented in the migration guides.

### 📦 Package Versions

- `@metamask/design-system-shared`: **0.21.0**
- `@metamask/design-system-react`: **0.25.0**
- `@metamask/design-system-react-native`: **0.28.0**
- `@metamask/design-tokens`: **8.5.0**
- `@metamask/design-system-tailwind-preset`: **0.9.0**
- `@metamask/design-system-twrnc-preset`: **0.5.0**

### 🔄 Shared Type Updates (0.21.0)

#### Added

- Added `ContentPropsShared` and `ContentVerticalAlignment` for React
Native list-style rows and related layout patterns
([#1192](#1192))

#### Changed

- **BREAKING:** Dropped Node.js 18 support for the release line;
consumers must run Node 20 or newer
([#1206](#1206))
- **BREAKING:** Updated `TextAreaPropsShared` to remove `inputElement`
so React Native `TextArea` can render the root `TextInput` directly
([#1205](#1205))

### 🌐 React Web Updates (0.25.0)

#### Added

- Added `Popover` for anchored overlays such as menus, tooltips, and
dialogs
([#1153](#1153))
- Added `TextArea` for controlled multiline text entry
([#1036](#1036))
- Added `TextFieldSearch` for controlled search-field flows on top of
`TextField`
([#1171](#1171))
- Added `FormTextField` for labeled form controls built from `Label`,
`TextField`, and `HelpText`
([#1197](#1197))

#### Changed

- **BREAKING:** Dropped Node.js 18 support for the release line;
consumers must run Node 20 or newer
([#1206](#1206))
- Updated avatar fallback handling so `AvatarToken`, `AvatarNetwork`,
and `AvatarFavicon` resolve consistently when the requested image is
unavailable
([#1212](#1212))

### 📱 React Native Updates (0.28.0)

#### Added

- Added `Content` for composing scrollable and padded content sections
on React Native screens; it is closely related to the upcoming
`ListItem` work
([#1192](#1192))

#### Changed

- **BREAKING:** Dropped Node.js 18 support for the release line;
consumers must run Node 20 or newer
([#1206](#1206))
- Added default padding and `isInteractive` support to `SectionHeader`
so section rows match the new mobile layout patterns
([#1210](#1210))
- **BREAKING:** Flattened `TextArea` so it renders the root `TextInput`
directly; pass `TextInput` props on `TextArea`, use the component `ref`
for the input, and stop relying on `inputProps` or `inputElement`
([#1205](#1205))
- Updated avatar fallback handling so `AvatarToken`, `AvatarNetwork`,
and `AvatarFavicon` resolve consistently when the requested image is
unavailable
([#1212](#1212))

### ⚠️ Breaking Changes

#### Node.js 18 support removed

**What Changed:**

- The release line now requires Node 20 or newer.
- This applies across the monorepo, including the shared package, web
package, React Native package, tokens, and both preset packages.

**Impact:**

- Consumers still on Node 18 must upgrade their runtime before
installing or developing against this release line.
- Node 18 is end-of-life, so this change aligns the repo with the
supported app runtimes.

#### React Native `TextArea` flattening

**What Changed:**

- `TextArea` now renders the root `TextInput` directly.
- `inputProps` and `inputElement` are removed.
- `inputRef` is replaced by the component `ref`.

**Migration:**

```tsx
// Before (0.27.0)
<TextArea
  inputProps={{ placeholder: 'Message' }}
  inputElement={<CustomInput />}
/>

// After (0.28.0)
<TextArea placeholder="Message" ref={inputRef} />
```

**Impact:**

- Affects React Native consumers using `TextArea`.
- Call sites that depended on the wrapper/input split need to be
updated.

See migration guides for complete instructions:

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

### ✅ 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.20.0 → 0.21.0) - shared type
additions and breaking TextArea/shared runtime baseline
- [x] design-system-react: minor (0.24.0 → 0.25.0) - new components and
release-line update
- [x] design-system-react-native: minor (0.27.0 → 0.28.0) - new
component, SectionHeader update, and breaking TextArea change
- [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**

- [x] I've reviewed the [Reviewing Release
PRs](./docs/reviewing-release-prs.md) guide
- [x] Package versions follow semantic versioning
- [x] Changelog entries are consumer-facing (not commit message
regurgitation)
- [x] Breaking changes are documented in MIGRATION.md with examples
- [x] All unreleased changes are accounted for in changelogs

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Breaking React Native TextArea and Node 18 removal affect consumer
upgrades; most diff is release metadata with coordinated peer dependency
bumps.
> 
> **Overview**
> **Release 43.0.0** bumps the monorepo root to **43.0.0** and publishes
coordinated semver bumps across design-system packages, with
**yarn.lock** peer ranges updated for
`@metamask/design-system-tailwind-preset` **^0.9.0** and
`@metamask/design-system-twrnc-preset` **^0.5.0**.
> 
> Across the release line, changelogs record **Node.js 18 dropped**
(Node **20+** required). **@metamask/design-system-react** **0.25.0**
documents new **`Popover`**, **`TextArea`**, **`TextFieldSearch`**, and
**`FormTextField`**, plus avatar fallback fixes.
**@metamask/design-system-react-native** **0.28.0** adds **`Content`**,
updates **`SectionHeader`** (default padding, **`isInteractive`**), and
includes a **breaking** **`TextArea`** flattening (`inputProps` /
`inputElement` / `inputRef` removed; props and **`ref`** target the root
**`TextInput`**). **@metamask/design-system-shared** **0.21.0** adds
**`ContentPropsShared`** / **`ContentVerticalAlignment`** and removes
**`inputElement`** from shared **`TextArea`** props.
> 
> Migration guide edits in this diff: React Native **0.27.0 → 0.28.0**
**`TextArea`** guidance; React version heading **0.22.0 → 0.23.0** for
**`BannerBase`** (changelog-driven **0.25.0** items are not new
migration sections here).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
23b0cda. 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