Add ARIA labels to progressbars
People using screen readers might have a hard time knowing what a progressbar is about unless we provide a label for it. Axe was reporting failures like: ``` aria-progressbar-name: ARIA progressbar nodes must have an accessible name (serious) https://dequeuniversity.com/rules/axe/4.10/aria-progressbar-name?application=axeAPI The following 1 node violate this rule: Selector: .progress HTML: <div class="progress" role="progressbar" tabindex="0" aria-valuenow="0.0" aria-valuemin="0" aria-valuemax="100"> <div class="progress-meter" style="width: 0.0%"></div> </div> Fix any of the following: - aria-label attribute does not exist or is empty - aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty - Element has no title attribute ``` Note that, in the case of the ballot progressbar, it's easier to use `aria-labelledby`, while in other place it's easier to use `aria-label`, so we using the easier solution in each scenario.
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
<h5><%= t("milestones.index.progress") %></h5>
|
<h5><%= t("milestones.index.progress") %></h5>
|
||||||
|
|
||||||
<div class="margin">
|
<div class="margin">
|
||||||
<%= progress_tag_for(primary_progress_bar) %>
|
<%= progress_tag_for(primary_progress_bar, label: t("milestones.index.progress")) %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% if secondary_progress_bars.any? %>
|
<% if secondary_progress_bars.any? %>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<%= progress_bar.title %>
|
<%= progress_bar.title %>
|
||||||
</div>
|
</div>
|
||||||
<div class="small-12 medium-6 large-8 column end">
|
<div class="small-12 medium-6 large-8 column end">
|
||||||
<%= progress_tag_for(progress_bar) %>
|
<%= progress_tag_for(progress_bar, label: progress_bar.title) %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -19,11 +19,12 @@ class Milestones::ProgressBarsComponent < ApplicationComponent
|
|||||||
milestoneable.secondary_progress_bars
|
milestoneable.secondary_progress_bars
|
||||||
end
|
end
|
||||||
|
|
||||||
def progress_tag_for(progress_bar)
|
def progress_tag_for(progress_bar, label:)
|
||||||
text = number_to_percentage(progress_bar.percentage, precision: 0)
|
text = number_to_percentage(progress_bar.percentage, precision: 0)
|
||||||
|
|
||||||
tag.div class: "progress",
|
tag.div class: "progress",
|
||||||
role: "progressbar",
|
role: "progressbar",
|
||||||
|
"aria-label": label,
|
||||||
"aria-valuenow": progress_bar.percentage,
|
"aria-valuenow": progress_bar.percentage,
|
||||||
"aria-valuetext": "#{progress_bar.percentage}%",
|
"aria-valuetext": "#{progress_bar.percentage}%",
|
||||||
"aria-valuemax": ProgressBar::RANGE.max,
|
"aria-valuemax": ProgressBar::RANGE.max,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<%= sanitize(ballot.amount_progress(heading)) %>
|
<%= sanitize(ballot.amount_progress(heading)) %>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="progress" role="progressbar" tabindex="0"
|
<div class="progress" role="progressbar" tabindex="0" aria-labelledby="total_amount"
|
||||||
aria-valuenow="<%= ballot.percentage_spent(heading) %>" aria-valuemin="0" aria-valuemax="100">
|
aria-valuenow="<%= ballot.percentage_spent(heading) %>" aria-valuemin="0" aria-valuemax="100">
|
||||||
<div class="progress-meter"
|
<div class="progress-meter"
|
||||||
style="width: <%= ballot.percentage_spent(heading) %>%">
|
style="width: <%= ballot.percentage_spent(heading) %>%">
|
||||||
|
|||||||
@@ -37,7 +37,8 @@
|
|||||||
<%= next_goal_progress %>%
|
<%= next_goal_progress %>%
|
||||||
</div>
|
</div>
|
||||||
<div class="progress" role="progressbar" tabindex="0" aria-valuenow="0" aria-valuemin="0"
|
<div class="progress" role="progressbar" tabindex="0" aria-valuenow="0" aria-valuemin="0"
|
||||||
aria-valuetext="<%= "#{next_goal_progress}%" %>" aria-valuemax="100">
|
aria-valuetext="<%= "#{next_goal_progress}%" %>" aria-valuemax="100"
|
||||||
|
aria-label="<%= t("layouts.dashboard.proposal_totals.current_goal") %>">
|
||||||
<div class="progress-meter" style="width: <%= next_goal_progress %>%"></div>
|
<div class="progress-meter" style="width: <%= next_goal_progress %>%"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ describe Milestones::ProgressBarsComponent do
|
|||||||
|
|
||||||
expect(page).to have_content "Progress"
|
expect(page).to have_content "Progress"
|
||||||
expect(page).to have_css "[role=progressbar]", count: 1
|
expect(page).to have_css "[role=progressbar]", count: 1
|
||||||
|
expect(page).to have_css "[role=progressbar][aria-label='Progress']"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "renders both main and secondary progress bars" do
|
it "renders both main and secondary progress bars" do
|
||||||
@@ -29,5 +30,7 @@ describe Milestones::ProgressBarsComponent do
|
|||||||
expect(page).to have_content "Progress"
|
expect(page).to have_content "Progress"
|
||||||
expect(page).to have_content "Build laboratory"
|
expect(page).to have_content "Build laboratory"
|
||||||
expect(page).to have_css "[role=progressbar]", count: 2
|
expect(page).to have_css "[role=progressbar]", count: 2
|
||||||
|
expect(page).to have_css "[role=progressbar][aria-label='Progress']"
|
||||||
|
expect(page).to have_css "[role=progressbar][aria-label='Build laboratory']"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -108,6 +108,12 @@ describe "Ballots" do
|
|||||||
create(:budget_investment, :selected, heading: new_york, price: 20000, title: "Paint cabs black")
|
create(:budget_investment, :selected, heading: new_york, price: 20000, title: "Paint cabs black")
|
||||||
|
|
||||||
visit budget_investments_path(budget, heading_id: new_york)
|
visit budget_investments_path(budget, heading_id: new_york)
|
||||||
|
|
||||||
|
within("#progress_bar") do
|
||||||
|
expect(page).to have_css "#total_amount", exact_text: "AMOUNT SPENT €0 / TOTAL BUDGET €1,000,000"
|
||||||
|
expect(page).to have_css "[role=progressbar][aria-labelledby='total_amount']"
|
||||||
|
end
|
||||||
|
|
||||||
add_to_ballot("Bring back King Kong")
|
add_to_ballot("Bring back King Kong")
|
||||||
|
|
||||||
within("#progress_bar") do
|
within("#progress_bar") do
|
||||||
|
|||||||
Reference in New Issue
Block a user