Templarian / MaterialDesign-React

Dist for Material Design Icons React Component for JS/TypeScript
https://materialdesignicons.com
MIT License
142 stars 20 forks source link

Need a way to add a title child element and ARIA attributes for sake of accessibility #23

Closed boaticus closed 5 years ago

boaticus commented 5 years ago

There seems to be no way to add title or desc child elements, or their related ARIA attributes. Both are necessities for basic accessibility (a11y) affordances[1].

Two goals here:

  1. Be understood by accessible browsing technology like screen readers

  2. Ability to have a description of the item appear when a user hovers their mouse over the SVG icon.

Both goals can be accomplished by accommodating ARIA attributes and the title and/or desc child elements.

Remember: title and alt attributes added to the svg element are not valid, not supported by browsers, aren't read by screen readers, and don't display the tooltip on hover, and thus are insufficient for a11y concerns. To work reliably, it has to be the child element of svg, not an attribute.

With this change, I'd expect to have a title parameter on the Icon component, thusly:

<Icon 
  path={mdiShieldCheck}
  className="my-verified-badge" 
  title="Verified"
  titleId="myUniqueTitleID"
 />

Which you'd expect to yield something akin to this:

<svg aria-labelledby="myUniqueTitleID">
  <title id="..."></title>
  <path> ... </path>
</svg>

Specifically, using the mdi icon from my example:

<svg viewBox="0 0 24 24" class="my-verified-badge" aria-labelledby="myUniqueTitleID"><title id="myUniqueTitleID">Verified</title><path d="M10,17L6,13L7.41,11.59L10,14.17L16.59,7.58L18,9M12,1L3,5V11C3,16.55 6.84,21.74 12,23C17.16,21.74 21,16.55 21,11V5L12,1Z"></path></svg>

Here's an example using the desc attribute as well, which adds a description that will be read aloud by screen reader technology to give much-needed context to the SVG (here, an mdi icon):

<Icon 
  path={mdiShieldCheck}
  className="my-verified-badge" 
  title="Verified"
  titleId="myUniqueTitleID"
  description="This member is a verified member of the community."
  descId="myUniqueDescID"
 />
<svg aria-labelledby="myUniqueTitleID myUniqueDescID">
  <title id="..."></title>
  <desc id="..."></desc>
  <path> ... </path>
</svg>

Specifically, using the mdi icon from my example (line breaks added to aid in readability here):

<svg viewBox="0 0 24 24" class="my-verified-badge" aria-labelledby="myUniqueTitleID myUniqueDescID">
<title id="myUniqueTitleID">Verified</title>
<desc id="myUniqueDescID">This member is a verified member of the community.</desc>
<path d="M10,17L6,13L7.41,11.59L10,14.17L16.59,7.58L18,9M12,1L3,5V11C3,16.55 6.84,21.74 12,23C17.16,21.74 21,16.55 21,11V5L12,1Z"></path>
</svg>

All that said... has anyone else run into this issue when trying to make the icons accessible?

[1] https://css-tricks.com/accessible-svgs/

Templarian commented 5 years ago

This has been on my todo list in my head for a while.

Templarian commented 5 years ago

By the way due to my backlog right now I won't be able to get to this for a bit unfortunately, but lets figure out what this needs to look like.

We can generate aria-labelledby="myUniqueTitleID myUniqueDescID" id's dynamically if the attributes for title and description are set.

Am I missing any edge cases?

Templarian commented 5 years ago

Started updating the unit tests for this feature to match the props above. Hopefully have some time tomorrow to work on this and get it pushed.

<button><Icon /> User Profile</button>
<button><Icon title="User Profile" /></button>
<button aria-label="User Profile"><Icon /></button> <!-- More correct? -->
<button><Icon title="User Profile" description="User Profile Icon" /></button>

The last example probably shouldn't be used in 99% of cases, but we'll support it.

Templarian commented 5 years ago

Need to update <Stack> next.

Templarian commented 5 years ago
Templarian commented 5 years ago

Will publish it later this week. Might need a few more tests before I feel comfortable releasing.

Templarian commented 5 years ago

Docs and a few more unit tests are in.

@boaticus Anything missing before we release it? Docs etc?

boaticus commented 5 years ago

Excellent work @Templarian! Also, I took a look at the unit tests and they look great.

boaticus commented 5 years ago

It looks like the only thing left to update for this issue are the docs.

Templarian commented 5 years ago

Published!