-
-
Notifications
You must be signed in to change notification settings - Fork 830
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test: components/progress-bar components/progress-ring #562
Conversation
- Add title to make ring accessibly hoverable. - Add label/labelledby as aria options. - Remove ununsed label slot.
- Match coverage with progress-ring - Attached titles/label/labelledby - Value '' on aria-valuenow is does not pass AXE
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/shoelace/shoelace/E9HADu39vq2z4AEE2FRsGExPSFxC |
describe('when provided just a value parameter', async () => { | ||
before(async () => { | ||
el = await fixture<SlProgressBar>(html`<sl-progress-bar value="25"></sl-progress-bar>`); | ||
}); | ||
|
||
it('should render a component that does not pass accessibility test.', async () => { | ||
await expect(el).not.to.be.accessible(); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default progress isn't accessible, should this be reflected in the documentation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For others reading, the test fails with:
Error: Accessibility Violations
---
Rule: aria-progressbar-name
Impact: serious
ARIA progressbar nodes must have an accessible name (https://dequeuniversity.com/rules/axe/4.2/aria-progressbar-name?application=axeAPI)
Issue target: sl-progress-ring,.progress-ring
Context: <div part="base" class="progress-ring" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="25" style="--percentage: 0.25">
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
---
aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty
Element has no title attribute
---
at processResults (node_modules/chai-a11y-axe/src/accessible.js:87:15)
at node_modules/chai-a11y-axe/src/accessible.js:117:7
at async o.<anonymous> (src/components/progress-ring/progress-ring.test.ts:15:6)
Would using a localized term such as "Progress" be a good default? Seems better than nothing. Then the user can choose to customize it with something more specific, e.g. "File upload progress".
aria-valuemin="0" | ||
aria-valuemax="100" | ||
aria-valuenow="${this.indeterminate ? '' : this.value}" | ||
aria-valuenow="${this.indeterminate ? 0 : this.value}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While the progress-bar is indeterminate, I suspect that it's closest to "0". We require a value other that '' for it to pass AXE.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, as always 💙
After reviewing this and leaving some notes, I think it might be best to remove the base part element and defer title
, aria-label
, and aria-labelledby
to the host element.
Let me know what you think. I'm happy to pick up this work if you prefer!
@@ -27,6 +28,15 @@ export default class SlProgressRing extends LitElement { | |||
/** The current progress, 0 to 100. */ | |||
@property({ type: Number, reflect: true }) value = 0; | |||
|
|||
/** When set, will place a hoverable title on the progress ring. */ | |||
@property() title: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will technically put a title
on the host element and the base part. Is it necessary to pass it through or can we leave it on the host and omit this declaration?
@@ -50,6 +60,9 @@ export default class SlProgressRing extends LitElement { | |||
part="base" | |||
class="progress-ring" | |||
role="progressbar" | |||
title=${ifDefined(this.title)} | |||
aria-label=${ifDefined(this.ariaLabel)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So far I've avoided using aria-like attributes as part of Shoelace's API. In some components, you'll see label
attribute that are used to populate an internal aria label. The idea is that it's harder to mess up accessibility if the library handles it internally. Can we use label
instead?
@@ -50,6 +60,9 @@ export default class SlProgressRing extends LitElement { | |||
part="base" | |||
class="progress-ring" | |||
role="progressbar" | |||
title=${ifDefined(this.title)} | |||
aria-label=${ifDefined(this.ariaLabel)} | |||
aria-labelledby=${ifDefined(this.ariaLabelledBy)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this will work since the property is defined on the host (light DOM) and the aria attribute is on the base part (shadow DOM).
One way to make this "just work" is to remove the base part and make the <sl-progress-ring|bar>
have role="progressbar"
. Then you'll get title
, aria-label
, and aria-labelled
by for free.
If that sounds like a good idea, let me know and I'll merge this and make those updates. 😄
describe('when provided just a value parameter', async () => { | ||
before(async () => { | ||
el = await fixture<SlProgressBar>(html`<sl-progress-bar value="25"></sl-progress-bar>`); | ||
}); | ||
|
||
it('should render a component that does not pass accessibility test.', async () => { | ||
await expect(el).not.to.be.accessible(); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For others reading, the test fails with:
Error: Accessibility Violations
---
Rule: aria-progressbar-name
Impact: serious
ARIA progressbar nodes must have an accessible name (https://dequeuniversity.com/rules/axe/4.2/aria-progressbar-name?application=axeAPI)
Issue target: sl-progress-ring,.progress-ring
Context: <div part="base" class="progress-ring" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="25" style="--percentage: 0.25">
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
---
aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty
Element has no title attribute
---
at processResults (node_modules/chai-a11y-axe/src/accessible.js:87:15)
at node_modules/chai-a11y-axe/src/accessible.js:117:7
at async o.<anonymous> (src/components/progress-ring/progress-ring.test.ts:15:6)
Would using a localized term such as "Progress" be a good default? Seems better than nothing. Then the user can choose to customize it with something more specific, e.g. "File upload progress".
I suspect this makes sense, but what does that mean for the other progress bar aria attributes like I'm happy to try review later in the week, or if you want to do it that's fine by me to. |
Yeah they would need to be moved to the host element as well. |
I went with a |
This PR aims to cover props passed to progress-bar/progress-ring.
docs/components/progress-ring.md
had the incorrect instructions for updating track width.title/aria-label/aria-labelledby
to give the best AXE coverage, I suspect that users will expect a title, which gives a native hoverable when you hover over the SVG of the graphs. A user may wish to omit this, or they may wish to have an external label, so all three are required.https://dequeuniversity.com/rules/axe/4.1/aria-progressbar-name