fix: problematic dismissable ref#31658
Conversation
PR template — items to address before "Ready for review"Blocking — these items fail the workflow until fixed:
Warnings — informational, address before merging:
See docs/readme/ready-for-review.md for the full Definition of Ready for Review. |
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection:
Tag Selection Rationale:
Tags NOT selected:
Risk Assessment: Medium — the changes fix a real iOS-specific bug in focus/blur handling that could affect user input behavior on iOS devices. The fix is well-scoped and accompanied by unit tests, but the iOS focus/blur race condition is subtle and worth E2E validation. Performance Test Selection: |
Description
Problem
When editing a position's TP/SL and tapping directly from the price field to the % gain/loss field, typing a percentage did not auto-fill the trigger price and the Set button stayed disabled. iOS-only bug.
Root cause
The iOS keyboard-dismiss fix introduced a boolean guard (
isProgrammaticDismissRef) that was set synchronously on every input focus. On iOS, the new field'sonFocusfires before the old field'sonBlur, so the guard was active when the price field's blur arrived — suppressing it and leavingtpPriceInputFocusedstucktrue. The percentage→price auto-fill was gated on!tpPriceInputFocused, so it never ran.Fix
Scoped the guard to a specific input — replaced the boolean ref with a string | null ref that stores the id of the field being dismissed. Only that field's programmatic blur is suppressed; all other fields' genuine blurs (including the previously-focused price field) are delivered normally and correctly clear focus state.
Hardened the hook — removed the
!tpPriceInputFocused/!slPriceInputFocusedgate from the percentage change handlers entirely. When the user is typing a percentage, that field is by definition the active source of truth and the trigger price must always be computed, regardless of stale focus flags.Tests
Added a regression test for the iOS focus/blur race (focus % before blur on price, no timer flush) verifying the price field's blur handler still fires.
Updated and added hook-level tests confirming percentage→price auto-fill works even when a price field's focus flag is stale.
Changelog
CHANGELOG entry:
Related issues
Fixes:
Manual testing steps
Screenshots/Recordings
Android:
Screen.Recording.2026-06-12.at.11.02.36.AM.mov
iOS:
https://github.com/user-attachments/assets/20902575-80bf-4a70-bf9b-d5c8a2d10bb1
Pre-merge author checklist
Performance checks (if applicable)
trace()for usage andaddTokenfor an exampleFor performance guidelines and tooling, see the Performance Guide.
Pre-merge reviewer checklist