Aria-labels on .shepherd-elements of steps without titles
TheBrockEllis opened this issue · 0 comments
First off, thanks for the amazing tool. I love how customizable it is. It's worked perfectly for us.
We're going through a big accessibility audit (enroute to our first VPAT) and I've been wiring up all of our pages with automated a11y tests. While testing the tour, I came across this error and I'm not sure how to proceed.
Found 1 accessibility violation:
1) aria-dialog-name: ARIA dialog and alertdialog nodes should have an accessible name (serious)
https://dequeuniversity.com/rules/axe/4.7/aria-dialog-name?application=axeAPI
The following 1 node violate this rule:
Selector: .shepherd-element
HTML: <div aria-describedby="tour-step-zero-description" role="dialog" tabindex="0" class="shepherd-element shepherd-tour shepherd-centered shepherd-enabled" data-shepherd-step-id="tour-step-zero" data-popper-escaped="" data-popper-placement="top" style="position: fixed; left: 50%; top: 50%; margin: 0px; transform: translate(-50%, -50%);">
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
(error via axe-core-api
gem for a ruby on rails project)
The problem seems to be that the .shepherd-element
doesn't have a proper aria-label on it. Our tours are just text and don't have shepherd's titles on them so the aria-labeledby
doesn't get applied to the wrapper element. It seems like the right way to get this to work is to add a title
to the step so that Shepherd generates the aria-labeledby
for the wrapper, but then we have to get the product team involved since it modifies the UI.
Any chance you'd be open to a PR that allows users to specify a aria-label
directly for each step so that it can be applied directly to the generated wrapped .shepherd-element
?
Here's the code for the step:
tour.addSteps([
{
id: 'tour-step-zero',
// label: "Proposed aria-label goes here??" <~~~~~~~~~~~
text: `
<div class='d-flex flex-column justify-content-center align-items-center' style='min-height: 200px;'>
<div class='my-5 d-flex flex-direction-column justify-content-center align-items-center' style='width: 100px; height: 100px; border-radius: 100px;'>
<img src='image.src' style='width: 50%; display: block; margin: 0 auto;' />
</div>
</div>
<div class='p-5'>
<h2 class='mb-5 text-center'>Hi, ${firstName}!</h2>
<p class='text-muted text-center lh-base'>Text goes here.
<div class='text-center'>
<button class='btn-sm border-0 px-5 py-3 mb-3' type='button' id='tour-lets-go'>
Let's Go!
</button>
<br>
<a class='text-decoration-none' href='#' id='tour-skip'>No, thanks! I'll explore on my own.</a>
</div>
</div>
`,
when: {
show: () => {
const skipButton = document.querySelector('#tour-skip')
skipButton.addEventListener('click', function (event) {
event.preventDefault();
tour.complete()
})
const goButton = document.querySelector('#tour-lets-go')
goButton.addEventListener('click', function (event) {
tour.next()
})
}
}
},
...