Skip to content

feat(predict): Bottom Sheet Keyboard Fix cp-7.78.0#30483

Merged
matallui merged 2 commits into
mainfrom
predict/bottom-sheet-keyboard
May 21, 2026
Merged

feat(predict): Bottom Sheet Keyboard Fix cp-7.78.0#30483
matallui merged 2 commits into
mainfrom
predict/bottom-sheet-keyboard

Conversation

@MarioAslau

@MarioAslau MarioAslau commented May 20, 2026

Copy link
Copy Markdown
Contributor

Description

The Predict Buy bottom-sheet introduced in #28779 opened with the custom keypad already rendered behind the rest of the sheet content. The root cause was a single isInputFocused boolean inside usePredictBuyInputState that was hard-coded to true on first render and overloaded across five unrelated behaviours:

  1. Mounting PredictKeypad.
  2. Highlighting the amount-display "active" state.
  3. Hiding PredictBuyBottomContent while the keypad is up.
  4. Disabling PredictFeeSummary.
  5. Deferring the mm_pay relay-config side effects (updatePendingAmount / setPayToken) inside PredictPayWithAnyTokenInfo.

Because the only "off switch" was setIsInputFocused(false) (driven from a Done button that doesn't exist in sheet mode) the previous PR worked around the issue with three isSheetMode ? false : isInputFocused ternaries — Bugbot flagged this on #28779. The workarounds also produced a confusing situation where bottom content and keypad rendered simultaneously on first sheet open.

This PR separates the conflated meanings, parameterises the initial state, and removes the workarounds. No behaviour change for the legacy full-screen flow.

What changed

usePredictBuyInputState (hooks/usePredictBuyInputState.ts)

  • Accepts an options object: { initialKeypadOpen = true }.
  • Renamed state + setter: isInputFocusedisKeypadOpen, setIsInputFocusedsetIsKeypadOpen.
  • Default value preserves legacy behaviour; sheet mode opts out.

PredictBuyWithAnyToken (PredictBuyWithAnyToken.tsx)

  • Calls the hook as usePredictBuyInputState({ initialKeypadOpen: !isSheetMode }) so the sheet opens with the keypad collapsed.
  • Removed the three isSheetMode ? false : isInputFocused patches.
  • Renders PredictBuyBottomContent at the call site via {(isSheetMode || !isKeypadOpen) && <PredictBuyBottomContent ... />} instead of relying on the component to bail internally. Keeps the legacy "hide while typing" behaviour while letting the sheet show the bottom content (and Confirm) at all times.
  • Passes the new self-documenting shouldDeferRelaySetup={!isSheetMode && isKeypadOpen} prop to PredictPayWithAnyTokenInfo. Same effective value as before, but the prop name now describes its actual purpose.

PredictPayWithAnyTokenInfo (components/PredictPayWithAnyTokenInfo)

  • Renamed prop: isInputFocusedshouldDeferRelaySetup. This is the genuine separation: the prop is not about UI keypad state, it's about pausing updatePendingAmount / setPayToken calls. Legacy mode still defers until the user taps Done; sheet mode never defers (relay must update on every keystroke since there's no Done and the user can tap Confirm with the keypad still open — preventing underfunded deposits).
  • Added a JSDoc comment explaining the contract.

PredictBuyBottomContent (components/PredictBuyBottomContent)

  • Removed the isInputFocused prop and the if (isInputFocused) return null early return. Component is now purely structural; visibility is the parent's responsibility.

PredictKeypad and PredictBuyAmountSection

  • Mechanical prop renames: isInputFocusedisKeypadOpen, setIsInputFocusedsetIsKeypadOpen.

Legacy PredictBuyPreview (views/PredictBuyPreview)

  • Local useState(true) renamed to isKeypadOpen for consistency with the rest of the tree. No behaviour change (still initialises true, still gates renderBottomContent).

Tests

  • All prop/state references renamed.
  • New coverage on usePredictBuyInputState for initialKeypadOpen: false and initialKeypadOpen: true.
  • New assertions in PredictBuyWithAnyToken.test.tsx that the hook is called with initialKeypadOpen: false in sheet mode and initialKeypadOpen: true in non-sheet mode.
  • PredictBuyBottomContent.test.tsx: removed the now-irrelevant isInputFocused is true / false describe blocks since visibility is caller-controlled.
  • PredictPayWithAnyTokenInfo.test.tsx: updated 43 prop references and renamed two test descriptions to reflect the new "relay deferral" intent.
  • PredictBuyPreview.test.tsx: updated renderBottomContent describe block descriptions.

Net behavioural effect (sheet mode)

  • Sheet opens → keypad hidden, amount display shows $0 (inactive), quick amounts + pay-with row + fee summary + Confirm button visible (Confirm disabled until amount > 0).
  • Tap amount display → keypad opens at the bottom of the sheet, stacked below the Confirm button (does not overlap).
  • Tap a quick amount → value set, keypad closes.
  • Tap Confirm with keypad still open → places order (relay setup is up-to-date because shouldDeferRelaySetup is false in sheet mode).
  • Auto-blur on banner display still works.

Legacy full-screen flow: unchanged.

Changelog

CHANGELOG entry: null

Related issues

Refs: PRED-707 (follow-up to #28779)

Manual testing steps

Feature: Predict buy bottom-sheet keypad initial state

  Scenario: Sheet opens with keypad collapsed (flag ON)
    Given the predictBottomSheet feature flag is enabled
    And the user is on a prediction market details page

    When user taps a "Yes" or "No" outcome button
    Then a bottom sheet opens with the buy preview content
    And the custom numeric keypad is NOT visible
    And the amount display shows "$0"
    And the quick amount buttons ($20 / $50 / $100 / $250) are visible
    And the Pay with row, fee summary and Confirm button are visible
    And the Confirm button is disabled

  Scenario: Tapping the amount opens the keypad
    Given the buy bottom sheet is open with no amount entered
    And the keypad is hidden

    When user taps the amount display
    Then the custom keypad becomes visible at the bottom of the sheet
    And the keypad does NOT cover the Confirm button
    And the amount display shows the active highlight

  Scenario: Tapping a quick amount sets value and closes the keypad
    Given the keypad is open
    And the user has typed "$73"

    When user taps the "$50" quick amount button
    Then the amount becomes "$50"
    And the keypad closes
    And haptic feedback fires (Light impact)
    And the Confirm button is enabled

  Scenario: Confirming with keypad still open
    Given the keypad is open
    And the user has typed "$25"

    When user taps the Confirm button
    Then the order is placed successfully
    And the relay was configured for $25 (no underfunded deposit)
    And the sheet closes

  Scenario: Banner display auto-blurs the keypad in sheet mode
    Given the buy bottom sheet is open
    And the keypad is open

    When an order_failed or price_changed banner appears
    Then the keypad auto-closes
    And the banner + Retry CTA are visible without needing to tap Done

  Scenario: Legacy full-screen flow is unchanged (flag OFF)
    Given the predictBottomSheet feature flag is disabled
    And the user navigates to the BuyPreview screen

    When the screen mounts
    Then the keypad is open by default (matching previous behaviour)
    And tapping Done closes the keypad and reveals the bottom content
    And the relay is configured once on Done (deferred during typing)

Screenshots/Recordings

Before

Sheet opens with the keypad rendered behind the bottom content; bottom content and keypad are both visible simultaneously on first paint. (See screenshot in PR comments — keypad sits below Confirm even though the user has not yet tapped the amount display.)

After

Sheet opens with the keypad hidden; bottom content (quick amounts, pay with row, fee summary, Confirm) is the only thing visible. Tapping the amount display reveals the keypad; tapping a quick amount or Confirm collapses it.

bottomSheetKeyboardFix.mov

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

N/A — pure refactor of UI state semantics, no new code paths.

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
Changes how the Predict buy keypad state is tracked and used to gate bottom content and mm_pay relay setup; mistakes could surface as incorrect UI visibility or misconfigured deposit/payment amounts during checkout. Scope is mostly contained to Predict buy views and covered by updated tests.

Overview
Fixes the Predict buy bottom-sheet keypad initial state by splitting the previously overloaded isInputFocused flag into a dedicated isKeypadOpen state, including a new initialKeypadOpen option in usePredictBuyInputState so sheet mode can start closed.

Updates PredictBuyWithAnyToken/PredictKeypad/PredictBuyAmountSection to use isKeypadOpen for keypad mounting and active styling, moves bottom-content visibility control to the parent (removing PredictBuyBottomContent’s internal early-return), and introduces shouldDeferRelaySetup (replacing isInputFocused) to explicitly gate PredictPayWithAnyTokenInfo’s relay-configuration side effects.

Refactors legacy PredictBuyPreview to the same isKeypadOpen naming and updates/adds tests to assert the new initialization, visibility behavior, and relay deferral propagation.

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

@MarioAslau MarioAslau requested a review from matallui May 20, 2026 23:30
@MarioAslau MarioAslau self-assigned this May 20, 2026
@MarioAslau MarioAslau added the team-predict Predict team label May 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@MarioAslau MarioAslau changed the title feat(predict): Bottom Sheet Keyboard Fix feat(predict): Bottom Sheet Keyboard Fix cp-7.78.0 May 20, 2026
@MarioAslau MarioAslau marked this pull request as ready for review May 20, 2026 23:40
@MarioAslau MarioAslau requested a review from a team as a code owner May 20, 2026 23:40

@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 85e0591. Configure here.

Comment thread app/components/UI/Predict/views/PredictBuyWithAnyToken/PredictBuyWithAnyToken.tsx Outdated
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

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

E2E Test Selection:
All 14 changed files are within app/components/UI/Predict/ and represent a focused refactoring of the Predictions buy flow UI state management:

  1. Core change: Renamed isInputFocused/setIsInputFocusedisKeypadOpen/setIsKeypadOpen across the entire Predict buy flow. This is a semantic rename that better describes the state (keypad visibility vs. input focus).

  2. Behavioral change in usePredictBuyInputState: Added initialKeypadOpen option. In non-sheet (full-screen) mode, initialKeypadOpen: !isSheetMode means the keypad starts open in full-screen mode (true) and closed in sheet mode (false). This is a meaningful UX change.

  3. PredictBuyBottomContent: Removed the isInputFocused prop and its internal visibility guard. Visibility is now controlled by the parent (PredictBuyWithAnyToken) via (isSheetMode || !isKeypadOpen) conditional rendering. This changes the rendering architecture.

  4. PredictPayWithAnyTokenInfo: Prop renamed to shouldDeferRelaySetup with clearer semantics - defers relay config side effects while keypad is open in legacy full-screen mode.

  5. PredictBuyPreview: Same rename pattern applied independently.

Risk: Medium - these are UI behavior changes to the Predictions buy flow that could affect how the keypad opens/closes and when bottom content (fee summary, action button) is visible. The refactoring touches the core interaction model of the buy flow.

Tag rationale:

  • SmokePredictions: Directly tests the Predict buy flow that was modified
  • SmokeWalletPlatform: Required per SmokePredictions description (Predictions is a section inside Trending tab)
  • SmokeConfirmations: Required per SmokePredictions description (opening/closing positions are on-chain transactions)

Performance Test Selection:
The changes are a UI state management refactoring (renaming isInputFocused to isKeypadOpen and moving conditional rendering logic from child to parent). While there is a minor architectural change in how PredictBuyBottomContent visibility is controlled, this does not introduce new rendering overhead or data loading patterns that would meaningfully impact performance metrics. No performance tests are warranted.

View GitHub Actions results

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.87097% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.14%. Comparing base (c9cb162) to head (98d3d4d).
⚠️ Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
.../PredictBuyWithAnyToken/PredictBuyWithAnyToken.tsx 81.25% 1 Missing and 2 partials ⚠️
...Predict/components/PredictKeypad/PredictKeypad.tsx 60.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #30483      +/-   ##
==========================================
- Coverage   82.14%   82.14%   -0.01%     
==========================================
  Files        5478     5478              
  Lines      147361   147362       +1     
  Branches    33883    33882       -1     
==========================================
- Hits       121054   121051       -3     
- Misses      18015    18018       +3     
- Partials     8292     8293       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sonarqubecloud

Copy link
Copy Markdown

@matallui matallui enabled auto-merge May 21, 2026 00:22
@matallui matallui added this pull request to the merge queue May 21, 2026
Merged via the queue into main with commit f2b07b6 May 21, 2026
200 of 202 checks passed
@matallui matallui deleted the predict/bottom-sheet-keyboard branch May 21, 2026 00:42
@github-actions github-actions Bot locked and limited conversation to collaborators May 21, 2026
@metamaskbotv2 metamaskbotv2 Bot added the release-7.79.0 Issue or pull request that will be included in release 7.79.0 label May 21, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.79.0 Issue or pull request that will be included in release 7.79.0 size-L team-predict Predict team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants