Skip to content

feat: add disabled loading state to MMPay fiat confirmation components#29906

Merged
OGPoyraz merged 4 commits into
mainfrom
ogp/mmpay-fiat-loading-state
May 11, 2026
Merged

feat: add disabled loading state to MMPay fiat confirmation components#29906
OGPoyraz merged 4 commits into
mainfrom
ogp/mmpay-fiat-loading-state

Conversation

@OGPoyraz

@OGPoyraz OGPoyraz commented May 8, 2026

Copy link
Copy Markdown
Member

Description

Adds a disabled/loading state to all interactive components on the MMPay fiat confirmation screen while startHeadlessBuy is in progress. This prevents user interaction during order preparation and provides clear visual feedback via muted styling and a native loading spinner on the CTA button.

Note that isHeadlessBuyInProgress is not currently used but it will be integrated on #28152

Changes

  • ConfirmationContext: Added isHeadlessBuyInProgress boolean + setter to shared context so all target components can read the state directly.
  • ConfirmButton: Uses the design system Button's built-in isLoading / loadingText props to show a spinner with "Preparing order" text.
  • CustomAmount: Disables the amount input keyboard when loading.
  • PayWithRow: Disables the token picker row; applies TextColor.Muted / IconColor.Muted for consistent dimming while preserving layout (arrow-down icon stays visible).
  • BridgeFeeRow: Disables the tooltip ⓘ button and applies muted text/icon colors.
  • TotalRow: Applies muted text colors to label and value.
  • Tooltip: Added disabled prop that guards handlePress and passes disabled to the underlying ButtonIcon for true non-interactivity.
  • InfoRow / AlertRow: Added tooltipDisabled prop forwarded to Tooltip; fixed AlertRow to only override label variant when an alert is active (respects caller's prop otherwise).
  • Locale: Added confirm.preparing_order string.

Changelog

CHANGELOG entry: null

Related issues

Fixes:

Manual testing steps

Feature: MMPay fiat loading state

  Scenario: Confirmation screen components are disabled during headless buy
    Given I am on the MMPay confirmation screen with a fiat payment method selected
    When I tap the confirm/add funds button to trigger startHeadlessBuy
    Then the CTA button shows a loading spinner with "Preparing order" text
    And the amount input keyboard is non-interactive
    And the "Pay with" row is dimmed and non-tappable
    And the "Transaction fee" row tooltip icon is dimmed and non-tappable
    And the "Total" row text is dimmed
    And no layout shifts occur on any row

Screenshots/Recordings

Before

After

fiat.loading.mov

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
  • I've tested with a power user scenario
  • I've instrumented key operations with Sentry traces for production performance metrics

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

Medium Risk
Touches confirmation-screen interaction/CTA enablement by introducing a new shared loading flag that disables inputs and shows a loading state; risk is mainly UX/flow regressions if the flag is set/cleared incorrectly.

Overview
Adds a new isHeadlessBuyInProgress flag (and setter) to ConfirmationContext and threads it through MM Pay fiat confirmation components to freeze user interaction during order preparation.

While this flag is true, the confirm CTA is disabled and shows a native loading spinner with new copy (confirm.preparing_order), and interactive rows/inputs (custom amount, pay-with picker, transaction-fee tooltip) are disabled with muted styling. Also fixes AlertRow to only override the variant color when an alert is present, and extends Tooltip/InfoRow with a disabled/tooltipDisabled path to prevent opening tooltips.

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

@OGPoyraz OGPoyraz requested a review from a team as a code owner May 8, 2026 10:49
@metamaskbotv2 metamaskbotv2 Bot added the team-confirmations Push issues to confirmations team label May 8, 2026
@github-actions github-actions Bot added the size-M label May 8, 2026
tooltipDisabled={tooltipDisabled}
tooltipColor={isDisabled ? IconColor.Muted : undefined}
rowVariant={InfoRowVariant.Small}
variant={labelColor}

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.

Label color not muted when alert overrides disabled state

Low Severity

When isDisabled is true AND an alert is active on PayWithFee, the label's muted color (variant={TextColor.Muted}) is silently overridden by AlertRow, which unconditionally replaces variant with the alert severity color (e.g., TextColor.Error) when alertSelected is truthy. Meanwhile, valueColor correctly resolves to TextColor.Muted. This creates a visual inconsistency — label in red, value in gray — during the loading state that is meant to mute everything.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 75601ae. Configure here.

@OGPoyraz OGPoyraz force-pushed the ogp/mmpay-fiat-loading-state branch from 75601ae to ff3c3d8 Compare May 8, 2026 12:47

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

There are 2 total unresolved issues (including 1 from previous review).

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 723c43c. Configure here.

name={IconName.ArrowDown}
size={IconSize.Sm}
color={IconColor.Alternative}
color={isDisabled ? IconColor.Muted : IconColor.Alternative}

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.

Arrow icon now visible for hardware accounts unintentionally

Medium Severity

The arrow-down icon visibility condition was broadened beyond the PR's intent. Previously, the icon was hidden when !canEdit (hardware accounts) via {!isDisabled && from && ...}. Now the condition is just {from && ...}, always rendering the icon (muted when disabled). This means hardware account users now see a muted dropdown arrow suggesting editability, when they could never edit. The same regression applies in PayWithFiatPaymentMethodRow where {canEdit && hasFrom && ...} became {hasFrom && ...}. The condition needs to distinguish "permanently non-editable" (hardware account) from "temporarily disabled" (headless buy in progress).

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 723c43c. Configure here.

@OGPoyraz OGPoyraz added the skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. label May 8, 2026
@github-actions

github-actions Bot commented May 8, 2026

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeConfirmations, SmokeMoney, SmokeSwap
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: medium
  • AI Confidence: 88%
click to see 🤖 AI reasoning details

E2E Test Selection:
The changes introduce a new isHeadlessBuyInProgress state to the confirmation context and propagate it through several confirmation UI components:

  1. confirmation-context.tsx: New isHeadlessBuyInProgress boolean state added to the shared confirmation context. This affects all components consuming this context.

  2. pay-with-row.tsx: Payment method selection row is now disabled during headless buy - directly affects the SmokeMoney card/fiat flows.

  3. bridge-fee-row.tsx: Bridge fee row is muted/disabled during headless buy - affects bridge/swap confirmation flows (SmokeSwap).

  4. total-row.tsx: Total row text is muted during headless buy - affects confirmation display.

  5. custom-amount-info.tsx: Confirm button is disabled and shows "Preparing order" loading state during headless buy - critical confirmation flow change.

  6. custom-amount.tsx: Custom amount input is disabled during headless buy.

  7. Tooltip.tsx / info-row.tsx / alert-row.tsx: UI component changes to support disabled state and fix alert variant logic.

  8. en.json: New "preparing_order" localization string.

Tag Selection Rationale:

  • SmokeConfirmations: Core confirmation UI components are modified (custom-amount, info-row, alert-row, tooltip, footer). The alert-row fix (only applying alert colors when alert is selected) could affect any confirmation with alerts. The confirm button loading state is a critical change.
  • SmokeMoney: The isHeadlessBuyInProgress concept is specifically for MetaMask Card/fiat flows. The pay-with-row and custom-amount changes directly affect the card deposit/buy flows.
  • SmokeSwap: The bridge-fee-row changes affect bridge/swap confirmation flows. Per tag descriptions, when selecting SmokeSwap, also select SmokeConfirmations (already included).

Dependent tags per descriptions:

  • SmokeSwap requires SmokeConfirmations ✓ (already included)
  • SmokeMoney for Card Add Funds flows that execute swaps requires SmokeSwap and SmokeConfirmations ✓ (already included)

Performance Test Selection:
The changes are UI state management additions (a new boolean flag in context) and visual styling changes (muted colors, disabled states). These are not performance-sensitive changes - they don't affect rendering performance, data loading, list rendering, or app startup. No performance tests are warranted.

View GitHub Actions results

@sonarqubecloud

sonarqubecloud Bot commented May 8, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
79.4% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@OGPoyraz OGPoyraz requested a review from dan437 May 11, 2026 07:26
@OGPoyraz OGPoyraz added this pull request to the merge queue May 11, 2026
Merged via the queue into main with commit 0e8493c May 11, 2026
97 of 98 checks passed
@OGPoyraz OGPoyraz deleted the ogp/mmpay-fiat-loading-state branch May 11, 2026 09:25
@github-actions github-actions Bot locked and limited conversation to collaborators May 11, 2026
@metamaskbotv2 metamaskbotv2 Bot added the release-7.78.0 Issue or pull request that will be included in release 7.78.0 label May 11, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.78.0 Issue or pull request that will be included in release 7.78.0 size-M skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. team-confirmations Push issues to confirmations team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants