Add shell accessibility landmarks
This commit is contained in:
@@ -44,6 +44,7 @@ It is intentionally implementation-focused:
|
||||
| 2026-03-21 | P1.4 | Completed | Added shared browser-storage wrappers, persisted theme mode in `localStorage`, and initialize/apply theme state from the layout on interactive render. |
|
||||
| 2026-03-21 | P1.5 | Completed | Replaced the permanent sidebar layout with a sticky top app shell and mobile bottom navigation backed by dedicated shell components. |
|
||||
| 2026-03-21 | P1.6 | Completed | Added explicit shell slots for nav, omnibox, shortcuts, and utilities; switched shell navigation to `Play`, `Tables`, `Curation`, and `Tools`; and wired the first live theme control into the shell. |
|
||||
| 2026-03-21 | P1.7 | Completed | Added a shell-level skip link and tightened the top-level header, navigation, and main landmarks around the new shell structure. |
|
||||
|
||||
### Lessons Learned
|
||||
|
||||
@@ -57,6 +58,7 @@ It is intentionally implementation-focused:
|
||||
- Shared UI state events in Blazor should stay synchronous unless the event contract is async-aware. Layout refresh can be triggered safely with `InvokeAsync(StateHasChanged)` from a synchronous handler.
|
||||
- Extracting shell markup into dedicated components is lower-risk than continuing to evolve `MainLayout.razor` directly. It isolates responsive frame work from page content and keeps later nav changes localized.
|
||||
- Once a Razor component exposes multiple named `RenderFragment` parameters, the page body must be passed explicitly through `<ChildContent>`. That pattern is now the baseline for shell composition here.
|
||||
- Accessibility work is cheaper when the shell owns the landmarks. Adding skip links and nav/main structure at the shell layer avoids repeating that work page by page.
|
||||
|
||||
## Target Outcomes
|
||||
|
||||
@@ -264,7 +266,7 @@ Create the implementation foundation so the visual overhaul does not start with
|
||||
| `P1.4` | Completed | Theme mode now persists through a shared storage service and is applied from the layout during interactive startup. |
|
||||
| `P1.5` | Completed | The sidebar is gone; pages now render inside a sticky top-shell with a mobile bottom nav. |
|
||||
| `P1.6` | Completed | The shell now has explicit nav, omnibox, shortcut, and utility slots, plus a live theme selector and destination-model navigation. |
|
||||
| `P1.7` | Pending | Skip link and landmark work will land with the shell markup. |
|
||||
| `P1.7` | Completed | The shell now exposes a skip link and explicit header/nav/main landmarks. |
|
||||
| `P1.8` | Pending | Tools-specific shell emphasis is final Phase 1 polish. |
|
||||
|
||||
### Goal
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<div class="app-shell">
|
||||
<a class="skip-link" href="#app-main">Skip to main content</a>
|
||||
|
||||
<header class="app-shell-header">
|
||||
<div class="app-shell-bar">
|
||||
<div class="app-shell-brand-block">
|
||||
@@ -18,7 +20,7 @@
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="app-shell-header-nav">
|
||||
<nav class="app-shell-header-nav" aria-label="Primary">
|
||||
@if (PrimaryNavContent is null)
|
||||
{
|
||||
<ShellPrimaryNav />
|
||||
@@ -27,7 +29,7 @@
|
||||
{
|
||||
@PrimaryNavContent
|
||||
}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="app-shell-header-omnibox">
|
||||
@if (OmniboxContent is not null)
|
||||
@@ -43,9 +45,9 @@
|
||||
|
||||
@if (ShortcutContent is not null)
|
||||
{
|
||||
<div class="app-shell-shortcuts">
|
||||
<nav class="app-shell-shortcuts" aria-label="Pinned and recent shortcuts">
|
||||
@ShortcutContent
|
||||
</div>
|
||||
</nav>
|
||||
}
|
||||
</header>
|
||||
|
||||
|
||||
@@ -4,6 +4,24 @@
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.skip-link {
|
||||
position: absolute;
|
||||
left: 1rem;
|
||||
top: -3rem;
|
||||
z-index: 80;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 999px;
|
||||
background: var(--accent-5);
|
||||
color: var(--text-on-accent);
|
||||
text-decoration: none;
|
||||
box-shadow: var(--shadow-1);
|
||||
transition: top 140ms ease;
|
||||
}
|
||||
|
||||
.skip-link:focus {
|
||||
top: 1rem;
|
||||
}
|
||||
|
||||
.app-shell-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
|
||||
Reference in New Issue
Block a user