mirror of
https://github.com/we-promise/sure.git
synced 2026-05-29 15:34:58 +00:00
fix(a11y): add skip-link and aria-current="page" to application layout (#1781)
* fix(a11y): add skip-link and aria-current="page" to application layout * test(a11y): cover application layout skip-link and #main anchor * fix(a11y): extend skip-link and #main anchor to settings layout
This commit is contained in:
@@ -26,6 +26,9 @@ end %>
|
||||
data-app-layout-expanded-sidebar-class="<%= expanded_sidebar_class %>"
|
||||
data-app-layout-collapsed-sidebar-class="<%= collapsed_sidebar_class %>"
|
||||
data-app-layout-user-id-value="<%= Current.user.id %>">
|
||||
<%= link_to t("layouts.application.skip_to_main"), "#main",
|
||||
class: "sr-only focus:not-sr-only focus:fixed focus:top-2 focus:left-2 focus:z-50 focus:px-3 focus:py-2 focus:rounded-lg focus:bg-container focus:text-primary focus:shadow-border-xs" %>
|
||||
|
||||
<div
|
||||
class="hidden fixed inset-0 bg-surface z-20 h-full w-full pt-[calc(env(safe-area-inset-top)+0.75rem)] pr-3 pb-[calc(env(safe-area-inset-bottom)+0.75rem)] pl-3 overflow-y-auto transition-all duration-300"
|
||||
data-app-layout-target="mobileSidebar">
|
||||
@@ -139,7 +142,7 @@ end %>
|
||||
<% end %>
|
||||
|
||||
<%# SHARED - Main content %>
|
||||
<%= tag.main class: class_names("grow overflow-y-auto px-3 lg:px-10 w-full mx-auto pb-[calc(5rem+env(safe-area-inset-bottom))] lg:pb-0"), data: { app_layout_target: "content", viewport_target: "content" } do %>
|
||||
<%= tag.main id: "main", class: class_names("grow overflow-y-auto px-3 lg:px-10 w-full mx-auto pb-[calc(5rem+env(safe-area-inset-bottom))] lg:pb-0"), data: { app_layout_target: "content", viewport_target: "content" } do %>
|
||||
<% unless intro_mode %>
|
||||
<div class="hidden lg:flex gap-2 items-center justify-between mb-6 sticky top-0 z-10 -mx-3 lg:-mx-10 px-3 lg:px-10 py-4 bg-surface border-b border-tertiary">
|
||||
<div class="flex items-center gap-2">
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<%= render "layouts/shared/htmldoc" do %>
|
||||
<div class="flex flex-col md:flex-row h-full bg-surface pt-[env(safe-area-inset-top)]">
|
||||
<%= link_to t("layouts.application.skip_to_main"), "#main",
|
||||
class: "sr-only focus:not-sr-only focus:fixed focus:top-2 focus:left-2 focus:z-50 focus:px-3 focus:py-2 focus:rounded-lg focus:bg-container focus:text-primary focus:shadow-border-xs" %>
|
||||
|
||||
<div class="w-full md:w-auto md:min-w-64 shrink-0 md:h-full md:overflow-y-auto border-divider md:border-r">
|
||||
<div class="p-4">
|
||||
<%= render "settings/settings_nav" %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main class="grow flex h-full">
|
||||
<main id="main" class="grow flex h-full">
|
||||
<div class="relative max-w-4xl mx-auto flex flex-col w-full h-full">
|
||||
<div class="grow flex flex-col overflow-y-auto overflow-x-hidden overscroll-contain [-webkit-overflow-scrolling:touch]">
|
||||
<div class="sticky top-0 z-10 px-3 md:px-10 pt-1.5 md:pt-3 pb-3 bg-surface border-b border-tertiary shrink-0">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<%# locals:(name:, path:, icon:, icon_custom:, active:, mobile_only: false) %>
|
||||
|
||||
<%= link_to path, class: "space-y-1 group block relative pb-1" do %>
|
||||
<%= link_to path, class: "space-y-1 group block relative pb-1", aria: { current: ("page" if active) } do %>
|
||||
<div class="grow flex flex-col lg:flex-row gap-1 items-center">
|
||||
<%= tag.div class: class_names("w-4 h-1 lg:w-1 lg:h-4 rounded-bl-sm rounded-br-sm lg:rounded-tr-sm lg:rounded-br-sm lg:rounded-bl-none", "bg-nav-indicator" => active) %>
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ ca:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: Alternar mode de privadesa
|
||||
skip_to_main: Saltar al contingut principal
|
||||
nav:
|
||||
assistant: Assistent
|
||||
budgets: Pressupostos
|
||||
|
||||
@@ -3,6 +3,7 @@ de:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: Datenschutzmodus umschalten
|
||||
skip_to_main: Zum Hauptinhalt springen
|
||||
nav:
|
||||
assistant: Assistent
|
||||
budgets: Budgets
|
||||
|
||||
@@ -3,6 +3,7 @@ en:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: Toggle privacy mode
|
||||
skip_to_main: Skip to main content
|
||||
nav:
|
||||
assistant: Assistant
|
||||
budgets: Budgets
|
||||
|
||||
@@ -3,6 +3,7 @@ es:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: Alternar modo de privacidad
|
||||
skip_to_main: Saltar al contenido principal
|
||||
nav:
|
||||
assistant: Asistente
|
||||
budgets: Presupuestos
|
||||
|
||||
@@ -3,6 +3,7 @@ fr:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: Activer/désactiver le mode confidentialité
|
||||
skip_to_main: Aller au contenu principal
|
||||
nav:
|
||||
assistant: Assistant
|
||||
budgets: Budgets
|
||||
|
||||
@@ -3,6 +3,7 @@ hu:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: Adatvédelmi mód váltása
|
||||
skip_to_main: Ugrás a fő tartalomhoz
|
||||
nav:
|
||||
assistant: Asszisztens
|
||||
budgets: Költségvetések
|
||||
|
||||
@@ -3,6 +3,7 @@ nb:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: Veksle personvernmodus
|
||||
skip_to_main: Hopp til hovedinnhold
|
||||
nav:
|
||||
assistant: Assistent
|
||||
budgets: Budsjett
|
||||
|
||||
@@ -3,6 +3,7 @@ nl:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: Privacymodus in-/uitschakelen
|
||||
skip_to_main: Ga naar hoofdinhoud
|
||||
nav:
|
||||
assistant: Assistent
|
||||
budgets: Budgetten
|
||||
|
||||
@@ -3,6 +3,7 @@ pl:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: Przełącz tryb prywatności
|
||||
skip_to_main: Przejdź do głównej treści
|
||||
nav:
|
||||
assistant: Asystent
|
||||
budgets: Budżety
|
||||
|
||||
@@ -3,6 +3,7 @@ pt-BR:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: Alternar modo de privacidade
|
||||
skip_to_main: Pular para o conteúdo principal
|
||||
nav:
|
||||
assistant: Assistente
|
||||
budgets: Orçamentos
|
||||
|
||||
@@ -3,6 +3,7 @@ ro:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: Comutare mod confidențialitate
|
||||
skip_to_main: Sari la conținutul principal
|
||||
nav:
|
||||
assistant: Asistent
|
||||
budgets: Bugete
|
||||
|
||||
@@ -3,6 +3,7 @@ tr:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: Gizlilik modunu değiştir
|
||||
skip_to_main: Ana içeriğe atla
|
||||
nav:
|
||||
assistant: Asistan
|
||||
budgets: Bütçeler
|
||||
|
||||
@@ -4,6 +4,7 @@ zh-CN:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: 切换隐私模式
|
||||
skip_to_main: 跳到主要内容
|
||||
nav:
|
||||
assistant: 智能助手
|
||||
budgets: 预算管理
|
||||
|
||||
@@ -3,6 +3,7 @@ zh-TW:
|
||||
layouts:
|
||||
application:
|
||||
privacy_mode: 切換隱私模式
|
||||
skip_to_main: 跳至主要內容
|
||||
nav:
|
||||
assistant: 助手
|
||||
budgets: 預算
|
||||
|
||||
27
test/integration/layout_accessibility_test.rb
Normal file
27
test/integration/layout_accessibility_test.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
require "test_helper"
|
||||
|
||||
class LayoutAccessibilityTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in users(:family_admin)
|
||||
end
|
||||
|
||||
test "application layout renders skip-link pointing at #main and a <main> with id=\"main\"" do
|
||||
get root_path
|
||||
assert_response :ok
|
||||
|
||||
skip_text = I18n.t("layouts.application.skip_to_main")
|
||||
|
||||
assert_select "a[href=\"#main\"]", text: skip_text
|
||||
assert_select "main#main"
|
||||
end
|
||||
|
||||
test "settings layout renders skip-link pointing at #main and a <main> with id=\"main\"" do
|
||||
get settings_profile_path
|
||||
assert_response :ok
|
||||
|
||||
skip_text = I18n.t("layouts.application.skip_to_main")
|
||||
|
||||
assert_select "a[href=\"#main\"]", text: skip_text
|
||||
assert_select "main#main"
|
||||
end
|
||||
end
|
||||
27
test/views/layouts/shared/nav_item_view_test.rb
Normal file
27
test/views/layouts/shared/nav_item_view_test.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
require "test_helper"
|
||||
|
||||
class NavItemViewTest < ActionView::TestCase
|
||||
test "active nav item carries aria-current=\"page\"" do
|
||||
html = render(partial: "layouts/shared/nav_item", locals: {
|
||||
name: "Transactions",
|
||||
path: "/transactions",
|
||||
icon: "credit-card",
|
||||
icon_custom: false,
|
||||
active: true
|
||||
})
|
||||
|
||||
assert_includes html, "aria-current=\"page\""
|
||||
end
|
||||
|
||||
test "inactive nav item omits aria-current" do
|
||||
html = render(partial: "layouts/shared/nav_item", locals: {
|
||||
name: "Transactions",
|
||||
path: "/transactions",
|
||||
icon: "credit-card",
|
||||
icon_custom: false,
|
||||
active: false
|
||||
})
|
||||
|
||||
assert_not_includes html, "aria-current"
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user