Skip to content

fix(wallet): reset failed kit init cache; feat(a11y): accessible trading components - #159

Merged
akargi merged 3 commits into
Chulilee:mainfrom
akargi:feature/wallet-and-a11y
Nov 6, 2026
Merged

akargi merged 3 commits into
Chulilee:mainfrom
akargi:feature/wallet-and-a11y

Conversation

@akargi

@akargi akargi commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Bundles the two issues assigned to @akargi.

1. Wallet kit initialization caches failed promises — closes #64

getKit() cached the kit initialization promise unconditionally, so one failed init poisoned every later call with the same rejection (no recovery without a page reload).

  • The rejected initialization promise now resets the module-level cache before rejecting, so the next getKit() retries from scratch.
  • Initialization runs with exponential backoff (retryWithBackoff, exported, default 3 attempts, doubling delay from 250 ms).
  • Terminal failures surface as WalletInitializationError carrying the underlying cause and the attempt count, and the message names the stage and count.
  • src/lib/stellar/__tests__/wallet.test.ts covers: success caching (init called once), failed-promise cache reset (a later call succeeds after a fully failed one), the attempt count/cause on terminal failure, backoff delay growth, and option clamping. Kit modules are virtual mocks.

2. Trading components lack accessibility attributes — closes #63

  • TradePanel: sr-only heading, aria-labelled form, order-side toggle group with aria-pressed + arrow-key navigation (focus follows selection), explicit label/input association, aria-describedby on the amount input, aria-live="polite" estimated-total row, role="status" for the success message and role="alert" for errors.
  • OrderEntry: header as h2 + aria-labelled form, role="group" wrappers for the order-type and order-side toggles with aria-pressed and a shared rovingKeyDown helper (ArrowLeft/Right move selection and focus, roving tabIndex), aria-labels on the 25/50/75/100% shortcut buttons ("Set size to X% of available balance"), aria-live="polite" regions for available balance and order value.
  • OrderBook: section role="region" with aria-label, h2 heading, bids/asks as role="list" with one aria-label per row ("Bid 0.5000 at 40000.00, total depth 0.5000" style), role="status"/aria-live="polite" on the mid-market price so updates are announced.
  • Existing jest tests (getByRole/getByTestId) and the Playwright e2e selectors are untouched and should keep passing.

Notes for reviewers

  • role="tablist"/tab semantics were deliberately avoided for the toggle groups: the repo tests query these controls as buttons, and a single-panel toggle is equally well served by aria-pressed + roving tabindex. Accessible names and state are still announced.
  • Keyboard navigation was added for both toggle groups in OrderEntry (shared helper) and the side toggle in TradePanel; no other interactive elements in these components were missing names.
  • WCAG checks here are manual/best-effort (labels, roles, focus, live regions); a full automated axe pass is out of scope.
  • npm ci/npm test/build were not run locally by the submitting agent; CI is expected to verify lint, type-check, tests and build.

Closes #64
Closes #63

getKit() cached the kit initialization promise unconditionally, so one
failed init (wallet module load, init() throw) poisoned every later call
with the same rejection until a page reload. Now the failed promise resets
the module-level cache before rejecting (the next call retries from
scratch), initialization runs with exponential backoff via the exported
retryWithBackoff helper, and terminal failures surface as
WalletInitializationError carrying the underlying cause and attempt count.

Tests: src/lib/stellar/__tests__/wallet.test.ts covers success caching,
failed-promise cache reset (retry after failure succeeds), the attempts and
the underlying cause on terminal failure, backoff delay growth, and option
clamping. Kit modules are virtual mocks; no real wallet is loaded.

Closes Chulilee#64
…r trading components

TradePanel: sr-only heading, aria-labelled form, order-side toggle group
with aria-pressed and arrow-key navigation (focus follows selection),
explicit label/input association, aria-describedby on the amount input,
aria-live estimated-total row, role=status/role=alert for order feedback.

OrderEntry: section header as h2 with an aria-labelled form, order-type and
order-side toggle groups with aria-pressed and roving-tabindex arrow-key
navigation shared by both groups, aria-labels on the 25/50/75/100% shortcut
buttons, aria-live regions for available balance and order value.

OrderBook: section as role=region with aria-label, h2 heading, bids/asks as
role=list with per-row aria-labels, role=status/aria-live on the mid-market
price so updates are announced. Existing getByRole/getByTestId tests and
e2e selectors are unchanged.

Closes Chulilee#63
@vercel

vercel Bot commented Nov 6, 2026

Copy link
Copy Markdown

@akargi is attempting to deploy a commit to the Akargi Team on Vercel.

A member of the Team first needs to authorize it.

aria-label on the 25/50/75/100% buttons replaced their visible accessible
name and broke the existing queries; use a shared aria-describedby
description instead so the name stays "25%" .. "100%" and screen readers
still get the context.

Closes Chulilee#63
@vercel

vercel Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
inter-changabletrade-fricks Ready Ready Preview Nov 6, 2026 2:07am UTC

@akargi
akargi merged commit d3aeecd into Chulilee:main Nov 6, 2026
3 checks passed

This branch was successfully deployed

1 active deployment
Preview — ad90225b Deployed Nov 6, 2026 by vercel[bot]
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.

Fix: Wallet kit initialization caches failed promises permanently Fix: Trading components lack accessibility attributes

1 participant