Fix Resources accessibility keyboard and reflow paths#17926
Merged
adamint merged 35 commits intoJul 9, 2026
Conversation
This was referenced Jun 4, 2026
Contributor
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17926Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17926" |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR consolidates multiple Aspire Dashboard Resources page accessibility fixes, improving keyboard/screen reader behavior for menu expanded state, focus restoration, tab reflow at narrow widths, and predictable Tab/Escape navigation in popups/menus.
Changes:
- Adds opt-in popup/menu keyboard focus navigation (Tab/Shift+Tab/Escape) via new JS handlers + a small Blazor wrapper component.
- Fixes Resources page keyboard interaction issues (View options focus restoration, preventing nested row controls from also triggering row activation) and improves tab header reflow/visibility at narrow widths.
- Expands automated coverage with new bUnit tests, a Node-based JS test for the Resources grid keyboard module, and a Playwright integration test for focus order.
Show a summary per file
| File | Description |
|---|---|
| tests/Aspire.Dashboard.Tests/Integration/Playwright/ResourcesTests.cs | Adds a Playwright regression test validating Tab focus after closing the View options menu. |
| tests/Aspire.Dashboard.Tests/Integration/Playwright/Infrastructure/MockDashboardClient.cs | Allows injecting a custom resources list for integration scenarios. |
| tests/Aspire.Dashboard.Tests/Integration/Playwright/Infrastructure/DashboardServerFixture.cs | Adds fixture extensibility to provide custom resource data via the mock dashboard client. |
| tests/Aspire.Dashboard.Components.Tests/Shared/ResourceSetupHelpers.cs | Stubs the new Resources page JS module initialization/disposal for component tests. |
| tests/Aspire.Dashboard.Components.Tests/Shared/FluentUISetupHelpers.cs | Adds global JSInterop stubs for popup keyboard navigation used by new/updated components. |
| tests/Aspire.Dashboard.Components.Tests/Pages/ResourcesTests.cs | Adds tests for ultra-low-width tab orientation, JS module behavior, and focus restoration wiring. |
| tests/Aspire.Dashboard.Components.Tests/Pages/ConsoleLogsTests.cs | Updates menu-item activation tests to invoke menu-item models directly (async) rather than clicking DOM elements. |
| tests/Aspire.Dashboard.Components.Tests/Controls/ResourceDetailsTests.cs | Updates masking toggle tests to invoke Aspire menu item models directly. |
| tests/Aspire.Dashboard.Components.Tests/Controls/AspirePopupFocusNavigationTests.cs | Adds tests for initializing/closing popup keyboard navigation. |
| tests/Aspire.Dashboard.Components.Tests/Controls/AspireMenuTests.cs | Adds tests covering menu keyboard navigation init/dispose and focus restoration behavior. |
| tests/Aspire.Dashboard.Components.Tests/Controls/AspireMenuButtonTests.cs | Adds a regression test ensuring aria-expanded is reliably true/false. |
| src/Aspire.Dashboard/wwwroot/js/app.js | Introduces initializeAspirePopupKeyboardNavigation / disposeAspirePopupKeyboardNavigation and focus traversal helpers. |
| src/Aspire.Dashboard/Components/ResourcesGridColumns/UrlsColumnDisplay.razor | Wraps overflow URL popover content in popup focus navigation to fix Tab order. |
| src/Aspire.Dashboard/Components/Pages/Resources.razor.js | Adds a Resources-scoped JS module to stop row activation when Enter originates from interactive descendants. |
| src/Aspire.Dashboard/Components/Pages/Resources.razor.css | Improves tab header overflow behavior so focused/selected tabs remain reachable/visible at narrow widths. |
| src/Aspire.Dashboard/Components/Pages/Resources.razor.cs | Imports/initializes/disposes the new Resources grid keyboard activation JS module. |
| src/Aspire.Dashboard/Components/Pages/Resources.razor | Enables focus restoration on View options; adds popup focus navigation wrapper; makes tabs vertical at ultra-low width; captures grid container element reference. |
| src/Aspire.Dashboard/Components/Controls/Chart/ChartFilters.razor | Wraps chart filter popover content in popup focus navigation for predictable Tab behavior. |
| src/Aspire.Dashboard/Components/Controls/AspirePopupFocusNavigation.razor.cs | New wrapper component that wires popup open/close state to JS keyboard navigation logic. |
| src/Aspire.Dashboard/Components/Controls/AspirePopupFocusNavigation.razor | New markup wrapper providing a stable popup root element id. |
| src/Aspire.Dashboard/Components/Controls/AspireMenuButton.razor.cs | Adds RestoreFocusOnItemClick parameter (documented) to enable opt-in focus restoration. |
| src/Aspire.Dashboard/Components/Controls/AspireMenuButton.razor | Ensures aria-expanded is always "true"/"false" and forwards focus-restore option to AspireMenu. |
| src/Aspire.Dashboard/Components/Controls/AspireMenu.razor.cs | Adds JS-driven popup keyboard navigation and opt-in focus restoration after item click; manages disposal. |
| src/Aspire.Dashboard/Components/Controls/AspireMenu.razor | Assigns an id to the underlying FluentMenu to support JS focus navigation targeting. |
Copilot's findings
- Files reviewed: 24/24 changed files
- Comments generated: 4
adamint
commented
Jun 5, 2026
adamint
left a comment
Member
Author
There was a problem hiding this comment.
Reviewed the Resources accessibility changes with multiple passes and ran the targeted dashboard component validation. I did not find any blocking issues.
JamesNK
reviewed
Jun 8, 2026
JamesNK
reviewed
Jun 8, 2026
JamesNK
reviewed
Jun 8, 2026
adamint
marked this pull request as draft
June 11, 2026 19:55
adamint
marked this pull request as ready for review
June 11, 2026 20:02
adamint
marked this pull request as draft
June 12, 2026 16:15
adamint
marked this pull request as ready for review
June 12, 2026 17:45
adamint
enabled auto-merge (squash)
July 9, 2026 02:48
…ces-keyboard-focus
chaiphet6669-afk
approved these changes
Jul 17, 2026
adamint
pushed a commit
to adamint/aspire
that referenced
this pull request
Jul 22, 2026
Resolves merge conflicts introduced by upstream's Resources accessibility fixes (microsoft#17926), which landed after this PR's keyboard-accessible tooltip work: - AspireMenuButton.razor: kept this PR's AspireTooltip wrapper around the menu button while wiring through upstream's new RestoreFocusOnItemClick parameter on the nested <AspireMenu>. - tests/.../Playwright/ResourcesTests.cs: this file was added independently on both branches (add/add conflict). Combined this PR's ResourceToolbarTooltip_ShowsOnKeyboardFocusAndHidesOnEscape test with upstream's four new tests (ViewOptionsMenu_ReportsExpandedState, UrlLink_EnterDoesNotOpenResourceDetails, ResourceViewTabs_RemainVisibleAtNarrowViewport, ResourceViewTabs_RemainVisibleAtNarrowHorizontalViewport), keeping the shared ResourcesDashboardServerFixture and AssertTabVisibleWithinViewportAsync helper from upstream since the filter button under test is independent of loaded resources. GridValue.razor auto-merged cleanly (upstream added @onkeydown:stopPropagation, this PR added the per-button tooltip wiring, in non-overlapping regions). AspireTooltip.razor(.js), ResourceActions.razor(.cs), ExceptionDetails.razor, DetailView.razor and ResourceDetails.razor were untouched by upstream/main since the merge base, so this PR's independent focus/hover tooltip state and the CSS.escape anchor selector are unchanged. Validation: - ./restore.sh - dotnet build src/Aspire.Dashboard/Aspire.Dashboard.csproj: 0 errors - dotnet test tests/Aspire.Dashboard.Components.Tests (full suite): 193/193 passed - dotnet test tests/Aspire.Dashboard.Tests -- --filter-class "*.ResourcesTests" (live Chromium): 5/5 Playwright tests passed, including ResourceToolbarTooltip_ShowsOnKeyboardFocusAndHidesOnEscape - git diff --check: clean, no conflict markers Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c0833666-e36b-4435-a085-97eb64deb98f
14 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #17466
Fixes #17656
Fixes #17651
Fixes #17654
Fixes #17469
Condenses the Resources-page accessibility fixes into one related PR. This keeps the keyboard/menu work together: View options now announces expanded/collapsed state, restores focus after item selection, nested row controls no longer also activate the parent row, and narrow Resources tab strips keep the active tab visible and keyboard-reachable.
This PR intentionally does not include the temporary Aspire-side popup Tab-navigation workaround from the earlier draft. Per review feedback, that path should be fixed in FluentUI and picked up by the dashboard through the library.
Supersedes the smaller draft PRs #17774, #17776, #17789, and #17791.
User-facing usage
Keyboard and screen reader users get predictable Resources-page navigation:
Preserved scenarios and proof
Validation
Checklist
<remarks />and<code />elements on your triple slash comments?