-
Notifications
You must be signed in to change notification settings - Fork 122
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
feat(a11y): add label for screen readers #1121
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1121 +/- ##
==========================================
+ Coverage 72.26% 72.90% +0.64%
==========================================
Files 387 405 +18
Lines 12021 12388 +367
Branches 2629 2680 +51
==========================================
+ Hits 8687 9032 +345
- Misses 3309 3322 +13
- Partials 25 34 +9
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
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.
Looking p good overall!
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.
Left a couple small code comments but otherwise looks good!
(Holding off approving until I have a chance to run through it in VoiceOver though.)
|
||
const ariaProps = { | ||
'aria-labelledby': labelledBy || label ? labelledBy ?? chartIdLabel : '', | ||
'aria-describedby': `${labelledBy || ''} ${useDefaultSummary ? chartIdLabel : ''}`, |
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.
Did you mean to use chartIdDescription
here?
'aria-describedby': `${labelledBy || ''} ${useDefaultSummary ? chartIdLabel : ''}`, | |
'aria-describedby': `${labelledBy || ''} ${useDefaultSummary ? chartIdDescription : ''}`, |
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.
And I'm also confused by the fact that we are reusing labelledBy
in the describedBy
. Should we introduce a new props called describedBy
?
Codecov Report
@@ Coverage Diff @@
## master #1121 +/- ##
==========================================
+ Coverage 72.26% 72.90% +0.64%
==========================================
Files 387 405 +18
Lines 12021 12388 +367
Branches 2629 2680 +51
==========================================
+ Hits 8687 9032 +345
- Misses 3309 3322 +13
- Partials 25 34 +9
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
@@ -82,6 +82,9 @@ export interface ReactiveChartStateProps { | |||
description?: string; | |||
useDefaultSummary: boolean; | |||
chartId: string; | |||
label?: string; | |||
labelledBy?: string; | |||
HeadingLevel: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p'; |
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.
each prop name should follow the camelCase
with the first char lowercase, independently if you use them later as component
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.
We should also sanitize this: it's true that in a TS this will throw error if the value is one of the union type, but in the JS compiled world not. This can lead to errors if this heading comes from an user input, or stored string value.
we can have a function that checks and returns/construct the appropriate header based on the input, like:
{label && <HeadingLevel id={chartIdLabel}>{label}</HeadingLevel>}
const ChartLabel = ({headingLevel: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p', id: string, label?: string}) => {
if(!label) return null;
switch(headingLevel){
case 'h1':
return <h1 id={id}>{label}</h1>
......
}
}
.....
<ChartLabel id={chartIdLabel} label={label} headingLevel={headingLevel} />
@nickofthyme other suggestions?
|
||
const ariaProps = { | ||
'aria-labelledby': labelledBy || label ? labelledBy ?? chartIdLabel : '', | ||
'aria-describedby': `${labelledBy || ''} ${useDefaultSummary ? chartIdLabel : ''}`, |
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.
And I'm also confused by the fact that we are reusing labelledBy
in the describedBy
. Should we introduce a new props called describedBy
?
@markov00 @nickofthyme do you think it would be better in terms of Kibana dashboards etc. for the |
if (ariaLabelledBy || useDefaultSummary) { | ||
ariaProps['aria-describedby'] = `${ariaLabelledBy || ''} ${useDefaultSummary ? chartIdLabel : undefined}`; | ||
} |
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.
@markov00 Good catch in #1121 (comment)
Adding a suggestion here so I could target more lines, I think the ariaLabelledBy
stuff snuck in by mistake. It should probably be something like:
if (ariaLabelledBy || useDefaultSummary) { | |
ariaProps['aria-describedby'] = `${ariaLabelledBy || ''} ${useDefaultSummary ? chartIdLabel : undefined}`; | |
} | |
if (accessibilityDescription || useDefaultSummary) { | |
ariaProps['aria-describedby'] = `${accessibilityDescription ? chartIdDescription : undefined} ${useDefaultSummary ? aNewIdForTheChartSeriesTypesDD : undefined}`; | |
} |
(I'm suggesting making a new id just for the chartSeriesTypes
<dd>
because description text can't be structured data so we can't just set an id for the whole <dl>
and use that. It's not perfect but it works well enough for a quick description imo.
@rshen91 Feel free to reach out if this suggestion doesn't make any sense! It's a little convoluted.
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.
Woops added this in 6150d2d thank you!
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.
One small tweak but otherwise looks good to me! Ship it!
This will be an awesome one to get integrated into Dashboards!
jenkins test this |
This commit extracts all the Settings props related to accessibility into an internal configuration, and reuse that configuration within the code without thinking about defaults" BREAKING CHANGE: `description` prop in `<Settings/>` is renamed to `ariaDescription`
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.
LGTM!
Remember to add the BREAKING CHANGE:
footer when merging
<dl id={a11ySettings.defaultSummaryId}> | ||
<dt>Chart type</dt> | ||
<dd>{chartSeriesTypes}</dd> | ||
</dl> |
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.
@markov00 Setting the summary id
here would be ideal but aria-labelledby
can't reliably report structured content so we're better off putting it on a simple string. Reporting just the chart type seems appropriate for a supplemental description (better than nothing, type of situation).
<dl id={a11ySettings.defaultSummaryId}> | |
<dt>Chart type</dt> | |
<dd>{chartSeriesTypes}</dd> | |
</dl> | |
<dl> | |
<dt>Chart type</dt> | |
<dd id={a11ySettings.defaultSummaryId}>{chartSeriesTypes}</dd> | |
</dl> |
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.
committing in #1118
headingLevel: 'p', | ||
|
||
ariaUseDefaultSummary: true, | ||
ariaLabelHeadingLevel: 'h2', |
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.
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.
committing in #1118 thank you!
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 sorry about that, I was reading the API docs and was marked as h2
# [29.0.0](v28.2.0...v29.0.0) (2021-04-22) ### Features * **a11y:** add label for screen readers ([#1121](#1121)) ([920e585](920e585)), closes [#1096](#1096) * **annotations:** marker body with dynamic positioning ([#1116](#1116)) ([601abac](601abac)) ### BREAKING CHANGES * **a11y:** `description` prop in `<Settings/>` is renamed to `ariaDescription` Co-authored-by: Marco Vettorello <[email protected]>
🎉 This PR is included in version 29.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
# [29.0.0](elastic/elastic-charts@v28.2.0...v29.0.0) (2021-04-22) ### Features * **a11y:** add label for screen readers ([opensearch-project#1121](elastic/elastic-charts#1121)) ([ddb8782](elastic/elastic-charts@ddb8782)), closes [opensearch-project#1096](elastic/elastic-charts#1096) * **annotations:** marker body with dynamic positioning ([#1116](elastic/elastic-charts#1116)) ([997d487](elastic/elastic-charts@997d487)) ### BREAKING CHANGES * **a11y:** `description` prop in `<Settings/>` is renamed to `ariaDescription` Co-authored-by: Marco Vettorello <[email protected]>
Summary
Fixes #1096
This PR allows the consumer to set the heading level (or as a p tag), a label, and labelledBy aria-prop for a cartesian chart that can be read by a screen reader.
PR1121.mp4
Renamed the story within test_cases to
accessibility customizations
with a knob for this change.Checklist
Delete any items that are not applicable to this PR.
src/index.ts
(and stories only import from../src
except for test data & storybook)