diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dc1b4b..764ec5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Install generator — `rails generate solid_stack_web:install` creates `config/initializers/solid_stack_web.rb` with every config option documented inline and injects the mount line into `config/routes.rb` - `SolidStackWeb.mount_path` — returns the path at which the engine is mounted in the host app, derived automatically from routes; use `link_to "Dashboard", SolidStackWeb.mount_path` to link to the dashboard without hardcoding the path +- Accessibility pass — skip-to-content link; ARIA labels on all navigation elements; `scope="col"` on every table header; visually-hidden "Actions" label on empty action-column headers; `aria-sort` on active sort columns in stats and cache entries; `aria_label: "Pagination"` on all pagination navs; `.sqw-sr-only` and `.sqw-skip-link` CSS utilities added to base stylesheet ## [0.8.0] - 2026-05-26 diff --git a/ROADMAP.md b/ROADMAP.md index 375ad20..b952fb5 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -11,7 +11,6 @@ The path to v1.0.0 is staged: first achieve feature parity with `solid_queue_das > _Make it easy to adopt and easy to contribute to._ ### Remaining -- **Accessibility pass** — keyboard navigation, ARIA labels on interactive elements, sufficient colour contrast in both themes - **Query optimisation** — eliminate N+1 queries across all list views; add covering indexes to the dummy app schema - **Error pages** — engine-scoped 404/500 views so errors stay within the dashboard chrome - **Changelog-driven upgrade notes** — `UPGRADING.md` for any breaking configuration changes diff --git a/app/assets/stylesheets/solid_stack_web/_01_base.css b/app/assets/stylesheets/solid_stack_web/_01_base.css index 2742876..15b93a6 100644 --- a/app/assets/stylesheets/solid_stack_web/_01_base.css +++ b/app/assets/stylesheets/solid_stack_web/_01_base.css @@ -31,3 +31,15 @@ a:hover { text-decoration: underline; } .sqw-monospace { font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: 13px; } .sqw-muted { color: var(--muted); } .sqw-truncate { max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } + +.sqw-sr-only { + position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; + overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; +} + +.sqw-skip-link { + position: absolute; top: -100%; left: 0; z-index: 9999; + padding: 0.5rem 1rem; background: var(--accent); color: #fff; + font-weight: 600; text-decoration: none; border-radius: 0 0 4px 0; +} +.sqw-skip-link:focus { top: 0; } diff --git a/app/views/layouts/solid_stack_web/application.html.erb b/app/views/layouts/solid_stack_web/application.html.erb index 49525ac..6b2a469 100644 --- a/app/views/layouts/solid_stack_web/application.html.erb +++ b/app/views/layouts/solid_stack_web/application.html.erb @@ -11,10 +11,11 @@ <%= javascript_importmap_tags "solid_stack_web" %> + Skip to main content
<%= link_to "Solid Stack", root_path, class: "sqw-header__logo" %> -
<% if current_section == :cache %> -