Skip to content

fix: make draw-credit ? shortcut cooperative so only one overlay opens (#1173) - #1329

Merged
greatest0fallt1me merged 2 commits into
Creditra:mainfrom
EmannuellaO:fix/draw-help-shortcut-conflict
Oct 24, 2026
Merged

greatest0fallt1me merged 2 commits into
Creditra:mainfrom
EmannuellaO:fix/draw-help-shortcut-conflict

Conversation

@EmannuellaO

Copy link
Copy Markdown
Contributor

Fixes #1173

Problem

Pressing ? on /draw-credit opened two overlays: App's document-level bubble listener (App.tsx) opened ShortcutHelpOverlay, then the draw wizard's window-level listener (DrawCreditPage.tsx) opened its own InlineHelpOverlay — two stacked modals, double-inerted backdrop, broken focus management.

Fix

  • src/pages/DrawCreditPage.tsx — the wizard's shortcut handler now binds in the capture phase on document and always consumes ? (preventDefault() + stopPropagation()), so App's handler — which bails on event.defaultPrevented — never runs on this route. The wizard opens its contextual help only when no other modal is open; while an input is focused the key is ignored entirely (character insertion wins). Escape/arrows are gated behind any open [role="dialog"][aria-modal="true"] (scoped so the always-mounted, closed notification-center panel doesn't block shortcuts).
  • docs/ACCESSIBILITY.md — new "Shortcut precedence" section documenting the page-level ? vs global ? contract.

Also included (needed for green acceptance + CI)

  • Learn-mode regression fix: e3cb4ee dropped the ?learn=1 branch from handleRiskModalAcknowledge, so acknowledging in learn mode started writing the ack key; restored (verified against original 21ebc97 implementation). Same commit also introduced a TDZ error (handleRiskModalAcknowledgeAndFocus deps referencing a const declared below it) — fixed by reordering the callbacks (pre-existing in the worktree, load-bearing for any render of the page).
  • Stale test expectations updated to current intended behavior: the risk gate is now a primer banner → modal flow (per e3cb4ee), and a failed draw's reset CTA is "Start over" (per #1179/a250566).
  • Test-router stub (src/test/__mocks__/react-router-dom.tsx): real Routes/Route matching, BrowserRouter reads window.location, syncHistory() keeps jsdom's URL in sync — required for App-level routing tests. (Overlaps with the stub upgrade in fix: revalidate restored repay drafts and scope them to the wallet (#1188) #1323 — whichever merges second rebases.)
  • useWalletIdentityKey mock in DrawCreditPage.test.tsx: 10 confirm-step tests were failing on main with "useWallet must be used within WalletProvider" (masked by a collection error until the @stellar/stellar-sdk dep below was added).
  • @stellar/stellar-sdk dependency: without it no test file collects — npm run build/CI on main was red. Added to fix that pre-existing breakage.
  • src/App.test.tsx: /help is a code-split route, so the input-focus test now awaits findByPlaceholderText instead of getBy… synchronously.

Test plan

New src/App.shortcuts.test.tsx (6 rows):

# Assertion
1 /draw-credit + ? → exactly one dialog, and it is the wizard's Help Center (not "Move around faster")
2 ? pressed again with help open → still exactly one dialog
3 / + ? → global ShortcutHelpOverlay still opens (no behavior loss)
4 Risk primer modal open + ? → no second dialog stacked (WhyApr has no UI trigger in the current build, so the reachable DefaultRiskModal stands in for the "dialog already open" case)
5 ? typed into the amount input → no overlay, still on the amount step, focus retained
6 Escape closes the wizard help → focus returns to the "Contact support" trigger

Verification

  • npx vitest run src/pages/DrawCreditPage.test.tsx src/components/ShortcutHelpOverlay.test.tsx src/App.test.tsx src/App.shortcuts.test.tsx → 70 passed, 0 failed (5 pre-existing skips).
  • Regression proof: with the pre-fix handler restored in isolation, 4/6 new tests fail — the old code stacks both overlays and double-inerts the app (aria-hidden on the entire tree).
  • Full suite vs clean main baseline (both runs with the stellar-sdk dep): 374 → 317 failures, 0 new failures (58 fixed by this PR; the single diff — ConfirmDialog focus trap — passes in isolation 2×, a full-suite timing flake).
  • npm run build → succeeds (CI's only job); tsc --noEmit → 334 errors, unchanged from baseline (repo-wide pre-existing debt; lint has no eslint config on main, pre-existing).

Creditra#1173)

Move the draw wizard's keyboard handler to a capture-phase document
listener that always consumes ? (preventDefault + stopPropagation), so
App's bubble-phase handler skips it and the global ShortcutHelpOverlay
can no longer stack with the wizard's InlineHelpOverlay. Wizard
shortcuts stay inert while any aria-modal dialog is open, and ? in a
focused input is left alone.

Also: restore the learn-mode branch so acknowledging ?learn=1 no longer
writes the ack key (regressed in e3cb4ee), fix the stale risk-gate and
Start-over test expectations, upgrade the test router stub with route
matching + window.location support, mock useWalletIdentityKey for the
confirm step, and add the App-level integration suite.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	package-lock.json
#	package.json
#	src/components/TransactionStatus.tsx
#	src/pages/DrawCreditPage.test.tsx
#	src/test/__mocks__/react-router-dom.tsx
@greatest0fallt1me
greatest0fallt1me merged commit 99496ad into Creditra:main Oct 24, 2026
1 check passed
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.

Draw wizard: pressing '?' opens both the wizard help overlay and the global shortcut overlay

3 participants