-
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): accessible goal and gauge chart #1174
Conversation
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.
👏 👏 👏
{validGoalChart && goalChartData && <dd>{`Minimum: ${goalChartData.minimum}`}</dd>} | ||
{validGoalChart && goalChartData && <dd>{`Maximum: ${goalChartData.maximum}`}</dd>} | ||
{validGoalChart && goalChartData && <dd>{`Target: ${goalChartData.target}`}</dd>} | ||
{validGoalChart && goalChartData && <dd>{`Value: ${goalChartData.value}`}</dd>} |
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 follow the same DOM structure for all the items on in the list: <dt>{category}</dt><dd>{dataPoint}</dd>
. We can also probably simplify it so there's only one conditional at the same time.
Not tested but something like this should work:
{validGoalChart && goalChartData && <dd>{`Minimum: ${goalChartData.minimum}`}</dd>} | |
{validGoalChart && goalChartData && <dd>{`Maximum: ${goalChartData.maximum}`}</dd>} | |
{validGoalChart && goalChartData && <dd>{`Target: ${goalChartData.target}`}</dd>} | |
{validGoalChart && goalChartData && <dd>{`Value: ${goalChartData.value}`}</dd>} | |
{validGoalChart && goalChartData && <> | |
<dt>Minimum:</dt> | |
<dd>${goalChartData.minimum}</dd> | |
<dt>Maximum:</dt> | |
<dd>${goalChartData.maximum}</dd> | |
<dt>Target:</dt> | |
<dd>${goalChartData.target}</dd> | |
<dt>Value:</dt> | |
<dd>${goalChartData.}}</dd> | |
</>} |
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.
Thank you, this makes sense! 44b9eb5
labelId, | ||
goalChartLabels, | ||
}: A11ySettings & ScreenReaderLabelProps) { | ||
if (!label && !goalChartLabels?.majorLabel) return null; |
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.
Should we do a goalChartLabels.minorLabel
check here too?
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.
Yas - 44b9eb5 thanks!!
const goalChartLabelsSection = !goalChartLabels?.majorLabel | ||
? null | ||
: `Goal chart label: ${goalChartLabels.majorLabel} ${goalChartLabels.minorLabel}`; | ||
|
||
return ( | ||
<Heading id={labelId}> | ||
{label} | ||
{goalChartLabelsSection} | ||
</Heading> |
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 think this whole "while label to render" thing is, unfortunately, going to be more complicated...
So, first, the easy change:
The minorLabel
we can just render as a <p>
under the heading as there isn't a great semantic way to to signify a subheading but also shoving it all into a heading seems incorrect. So the DOM will look something like this:
return <>
{unifedLabel &&
<Heading id={labelId}>
{unifiedLabel}
</Heading>
}
{goalChartLabels.minorLabel && <p>{goalChartLabels.minorLabel}</p>}
</>;
Now we've got the more difficult change that I hid under a new variable I made up called unifiedLabel
.
-
Goal charts are kind of great in that they're one of the few that have a visible label built in. I imagine a separate accessible label doesn't need to actually be passed in very often so let's hide that bit of indirection from users.
-
If both an accessible label and a chart label are passed in, just from what I see users doing a lot, I'd bet they will often be identical so let's check for that too before printing both.
-
Finally, only if both are supplied and are different should we print both and make clear what's what.
let unifiedLabel = '';
if (!label && goalChartLabels?.majorLabel) unifiedLabel = goalChartLabels?.majorLabel;
else if (label && !goalChartLabels?.majorLabel) unifiedLabel = label;
else if (label && goalChartLabels?.majorLabel && label !== goalChartLabels.majorLabel) {
unifiedLabel = `${label}; Chart visible label: ${goalChartLabels.majorLabel}`;
}
👆 I also changed the string a little bit. Because we don't know what the user might be passing in, and it seems a little strange to pass in both, I'm being super explicit about it but also trying not to duplicate info (we elsewhere say it's a goal chart).
Hope this all makes sense! Happy to zoom about it too!
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 think I'm following!! 44b9eb5 for changes, 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.
Code LGTM, will test this next week before giving it a green light
<dd id={defaultSummaryId}>{chartTypeDescription}</dd> | ||
{validGoalChart && goalChartData ? ( | ||
<> | ||
<dt>{'Minimum: '}</dt> |
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.
Do we need the extra space at the end here? I don't think screen readers need it and I think this is hidden visually.
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.
Ah good catch thank you 4f8e86c
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! 🚀
<> | ||
{unifiedLabel && ( | ||
<Heading id={labelId}> | ||
{label} |
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.
{label} |
Can delete, the unifiedLabel
includes it
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!!! Good catch 7ad9893
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
🎉 This PR is included in version 31.1.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
# [31.1.0](elastic/elastic-charts@v31.0.0...v31.1.0) (2021-07-06) ### Bug Fixes * **heatmap:** pick correct brush end value ([opensearch-project#1230](elastic/elastic-charts#1230)) ([cb95a75](elastic/elastic-charts@cb95a75)), closes [opensearch-project#1229](elastic/elastic-charts#1229) ### Features * **a11y:** accessible goal and gauge chart ([#1174](elastic/elastic-charts#1174)) ([775dc98](elastic/elastic-charts@775dc98)), closes [opensearch-project#1160](elastic/elastic-charts#1160)
Summary
Goal chart are more accessible! By default, users of assistive technologies will be able to learn more about goal charts such as the minimum, maximum, target, current value, and label major and minor.
Details
Fixes #1160
Checklist