-
-
Notifications
You must be signed in to change notification settings - Fork 367
[Icons] Add support for <title> and <desc> elements in SVG for accessibility #2904
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
base: 2.x
Are you sure you want to change the base?
Conversation
When passing title and/or desc as attributes to ux_icon(), they are now embedded directly into the SVG as <title> and <desc> child elements. Each <title> and <desc> element is given a unique id and automatically referenced via aria-labelledby, if no such attribute was already set. This ensures compliance with accessibility best practices for inline SVG content. See: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title https://developer.mozilla.org/en-US/docs/Web/SVG/Element/desc
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 for working in this!
Please be sure to add tests
src/Icons/src/Icon.php
Outdated
$titleId = 'title-' . bin2hex(random_bytes(4)); | ||
$labelledByIds[] = $titleId; | ||
$a11yContent .= sprintf('<title id="%s">%s</title>', $titleId, htmlspecialchars((string) $title, ENT_QUOTES)); | ||
} | ||
|
||
if ($desc) { | ||
$descId = 'desc-' . bin2hex(random_bytes(4)); |
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 feel like it's a not a good idea to generate random strings for eacg title/desc, especially when you render a lot of icons in a single page.
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.
"IDs for the <title> and elements are generated only when the aria-labelledby attribute is automatically added to reference them."
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.
Yeah I know, but I don't think generating random values like that is a good thing, it can be CPU intensive and it's untestable.
Instead, either we generate these ids based on the icon (name, title, description, ...), either we use an internal incremental counter or something similar
Thanks for suggestions. can you check again please. |
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'm sorry, but I don't understand the benefits over using <title>
and <desc>
, instead of using aria-label
and aria-description
attribute. Do you have more information about that?
Tests are still missing, please make sure to add tests for making the CI green, thanks
<svg class="text-success" width="16px" height="16px" aria-labelledby="icon-title-abc icon-desc-def"> | ||
<title id="icon-title-abc">Add Stock</title> | ||
<desc id="icon-desc-def">This icon indicates stock entry functionality.</desc> |
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 id
attributes do no match the actual behaviour
src/Icons/src/Icon.php
Outdated
// Special case for aria-* attributes | ||
// https://www.w3.org/TR/wai-aria-1.1/#state_prop_def | ||
if (true === $value && str_starts_with($name, 'aria-')) { | ||
if ($value === true && str_starts_with($name, 'aria-')) { | ||
$value = 'true'; | ||
} | ||
|
||
$htmlAttributes .= ' '.$name; | ||
if (true === $value) { | ||
|
||
$htmlAttributes .= ' ' . $name; | ||
|
||
if ($value === true) { | ||
continue; | ||
} | ||
|
||
$value = htmlspecialchars($value, \ENT_QUOTES | \ENT_SUBSTITUTE, 'UTF-8'); | ||
$htmlAttributes .= '="'.$value.'"'; | ||
$htmlAttributes .= '="' . $value . '"'; | ||
} | ||
|
||
return '<svg'.$htmlAttributes.'>'.$this->innerSvg.'</svg>'; | ||
|
||
// Inject <title> and <desc> before inner content | ||
return '<svg' . $htmlAttributes . '>' . $a11yContent . $innerSvg . '</svg>'; |
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.
Please revert all changes here, except for $a11yContent
usage, PR must contains only the necessary changes
And apply Fabbot suggestions aswell, thanks |
When passing title and/or desc as attributes to ux_icon(), they are now embedded directly into the SVG as <title> and child elements.
Each <title> and element is given a unique id and automatically referenced via aria-labelledby, if no such attribute was already set.
This ensures compliance with accessibility best practices for inline SVG content.
See:
Example Usage:
Renders: