Skip to content

fix: keyboard focus and space handling from accessibility audit - #3824

Merged
AlexAndBear merged 7 commits into
mainfrom
fix/a11y-keyboard-findings
Oct 21, 2026
Merged

AlexAndBear merged 7 commits into
mainfrom
fix/a11y-keyboard-findings

Conversation

@AlexAndBear

@AlexAndBear AlexAndBear commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Description

Fix four keyboard findings from the accessibility audit. Nothing changes visually; only keyboard and focus behavior changes where the audit asks for it:

  • Audit 7 — Space on a focused control: in the files list (table and tiles) and the admin-settings tables, Space on a focused row checkbox, button or link toggled the last-selected row instead of the focused control. A new isControlKeyEvent helper in useKeyboardActions lets focused controls keep their native Space behavior; the list bindings only toggle the last-selected row when focus is not on a control. During arrow-key navigation focus sits on the row checkbox, so Space still toggles exactly that row.
  • Audit 9 — mobile navigation drawer: opening the drawer moves focus into it, Tab and Shift+Tab stay inside, Escape closes it and focus returns to the menu button. The dialog is aria-modal (which also pauses the list key bindings while it is open) and labelled by its "Menu" heading, and the bogus aria-current="page" on the menu button is gone. It stays a non-modal <dialog>, so tooltips and drawers opened from it keep working.
  • Audit 11 — focus after a modal from a menu: closing a modal opened from a context-menu item or the "+ New" menu dropped focus to <body>, because focus-trap returns focus to the menu item, which is gone by then (focus-trap-vue also doesn't forward setReturnFocus). The drop registry now remembers each drop's anchor when it opens, and OcModal focuses that anchor on unmount if focus was lost. Menus opened with a right click have no focusable anchor, so they are not covered.
  • Audit 26 — back to the App Store list: returning from an app's detail page (back link or browser back) focuses the title link of the app that was opened instead of <body>.

Related Issue

How Has This Been Tested?

  • test environment: macOS, local Docker OpenCloud backend (production build for e2e, vite dev server for manual checks), Playwright Chromium.
  • test case 1: pnpm check:types, pnpm lint and pnpm format:check passed.
  • test case 2: pnpm test:unit --run passed. Added unit tests that Space on a focused checkbox is not prevented and leaves the admin table selection alone, and for the drop registry's anchor lookup.
  • test case 3: ran the keyboard scenarios from test(e2e): extend a11y coverage and add keyboard checks #3795 against main and this branch. Space toggling the focused row checkbox and the mobile drawer (focus trap, Escape, focus return) failed on main and pass here. "Focus is kept after closing a modal or deleting a resource" still fails, because it opens the modal from a right-click menu (out of scope).
  • test case 4: browser checks of focus after closing a modal with Escape: ⋮ rename (focus on ⋮), "+ New" folder (focus on "+ New") and admin users ⋮ delete (focus on ⋮). Right-click menus still close on a left click.
  • test case 5: App Store: focus lands on the opened app after the back link and after browser back; it stays on the body after a reload and after leaving the App Store from a detail page.
  • test case 6: compared screenshots of the right-click context menu, App Store list, rename modal and the mobile top bar with the drawer closed and open before and after: all are byte-identical.

Types of changes

  • Bugfix
  • Enhancement (a change that doesn't break existing code or deployments)
  • Breaking change (a modification that affects current functionality)
  • Technical debt (addressing code that needs refactoring or improvements)
  • Tests (adding or improving tests)
  • Documentation (updates or additions to documentation)
  • Maintenance (like dependency updates or tooling adjustments)

@AlexAndBear AlexAndBear self-assigned this Oct 15, 2026
@AlexAndBear
AlexAndBear force-pushed the fix/a11y-keyboard-findings branch 2 times, most recently from 5164a13 to 2838ca2 Compare October 15, 2026 20:26
@AlexAndBear
AlexAndBear force-pushed the fix/a11y-keyboard-findings branch from 2838ca2 to 5f64097 Compare October 21, 2026 11:08

@JammingBen JammingBen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My agent only complains about missing unit tests for AppList, AppDetails and the new unmount logic in OcModal - I leave it up to you if you want to add them. The rest LGTM.

@AlexAndBear

Copy link
Copy Markdown
Member Author

My agent only complains about missing unit tests for AppList, AppDetails and the new unmount logic in OcModal - I leave it up to you if you want to add them. The rest LGTM.

Oh yeah, at least for OcModal thats critical to me, thanks

@AlexAndBear

Copy link
Copy Markdown
Member Author

Added the unit tests, and unskipped one of the e2e tests I missed.

@AlexAndBear
AlexAndBear merged commit 89bfdfb into main Oct 21, 2026
27 checks passed
@AlexAndBear
AlexAndBear deleted the fix/a11y-keyboard-findings branch October 21, 2026 16:34
openclouders pushed a commit that referenced this pull request Oct 21, 2026
* fix: keyboard focus and space handling from accessibility audit

* fix: simplify keyboard focus fixes after review

* fix: keep mobile navigation focus and centralize space handling

* test: cover the focus return of modals and app store details

* test(e2e): run the fixed mobile navigation keyboard scenario

* chore: trigger CI

* chore: trigger CI
@openclouders openclouders mentioned this pull request Oct 21, 2026
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants