Blog: Fixing the Add Transaction Modal for Keyboard & Screen-Reader Users
Fixing the Add Transaction Modal for Keyboard & Screen-Reader Users
Release v1.0.147 · Accessibility · transaction-ledger.tsx
Landlords managing their property finances through the transaction ledger rely on the Add Transaction modal dozens of times a month. In v1.0.147 we've addressed a cluster of accessibility issues that made this modal effectively unusable for keyboard-only users and assistive technology.
What was wrong
The ManualTransactionForm component rendered conditionally inside the transaction ledger page, but it was missing several fundamental modal behaviours:
| Problem | Impact |
|---|---|
| No focus trap | Keyboard focus stayed on the background page when the modal opened |
| No ESC handler | The modal could not be closed without a mouse click |
| No backdrop-click-to-close | Only the explicit close button worked, reducing discoverability |
Missing aria-modal / role="dialog" | Screen readers did not announce the overlay as a modal layer |
| No entrance animation | The modal appeared abruptly with no visual transition |
For a keyboard-only user, opening the modal and tabbing through it would cycle focus through the entire page behind it — a WCAG 2.1 failure under Success Criterion 2.1.2 (No Keyboard Trap) and related focus-management guidelines.
What changed
Focus trap on open
When the modal opens, focus is now programmatically moved to the first interactive element inside the form (typically the transaction amount or description field). Tab and Shift+Tab cycle only within the modal's interactive elements until it is closed.
ESC key to close
An onKeyDown handler wired in the ledger component's invocation of ManualTransactionForm now listens for the <kbd>Escape</kbd> key and closes the modal, consistent with every other overlay surface in the application.
Backdrop click to close
Clicking outside the modal (on the dimmed backdrop) dismisses it, matching the standard mental model users have for modal dialogs.
Correct ARIA attributes
The modal root element now carries role="dialog" and aria-modal="true", ensuring screen readers (NVDA, JAWS, VoiceOver) switch to their modal-reading mode and do not allow virtual cursor navigation outside the dialog.
Fade-in animation
A short CSS fade-in transition now accompanies the modal opening, providing a smooth, non-jarring entrance that matches the rest of the dashboard UI.
Implementation approach
Rather than building a bespoke solution, the fix aligns ManualTransactionForm with the existing ConfirmDialog pattern already present in the codebase. ConfirmDialog already implements most of this behaviour correctly. The shared logic has been extended (or a new shared Modal primitive extracted) so future dialogs benefit automatically.
Testing your transactions workflow
- Navigate to Dashboard → Transactions.
- Click Add Transaction to open the modal.
- Confirm that keyboard focus moves immediately to the first form field.
- Tab through all fields — focus should not escape the modal.
- Press <kbd>Escape</kbd> — the modal should close.
- Click the backdrop — the modal should close.
- Run a screen reader (e.g. macOS VoiceOver with <kbd>⌘F5</kbd>) and verify it announces the dialog role on open.
This fix is part of our ongoing commitment to making the platform fully accessible to all landlords, including those who rely on keyboard navigation or assistive technology to manage their Making Tax Digital obligations.