🔇 fix: Hide Button Icons from Screen Readers (#10776)
Some checks failed
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Has been cancelled
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Has been cancelled

If you've got a screen reader that is reading out the whole page,
each icon button (i.e., `<button><SVG></button>`) will have both
the button's aria-label read out as well as the title from the
SVG (which is usually just "image").

Since we are pretty good about setting aria-labels, we should instead
use `aria-hidden="true"` on these images, since they are not useful
to be read out.

I don't consider this a comprehensive review of all icons in the app,
but I knocked out all the low hanging fruit in this commit.
This commit is contained in:
Daniel Lew 2025-12-11 15:35:17 -06:00 committed by GitHub
parent b288d81f5a
commit 1143f73f59
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
175 changed files with 340 additions and 183 deletions

View file

@ -241,7 +241,7 @@ export default function GenericGrantAccessDialog({
>
<div className="flex min-w-[32px] items-center justify-center gap-2 text-blue-500">
<span className="flex h-6 w-6 items-center justify-center">
<Share2Icon className="icon-md h-4 w-4" />
<Share2Icon className="icon-md h-4 w-4" aria-hidden="true" />
</span>
{totalCurrentShares > 0 && (
<Label className="text-sm font-medium text-text-secondary">{totalCurrentShares}</Label>
@ -256,7 +256,7 @@ export default function GenericGrantAccessDialog({
<OGDialogContent className="max-h-[90vh] w-11/12 overflow-y-auto md:max-w-3xl">
<OGDialogTitle>
<div className="flex items-center gap-2">
<Users className="h-5 w-5" />
<Users className="h-5 w-5" aria-hidden="true" />
{localize('com_ui_share_var', {
0: config?.getShareMessage(resourceName),
})}
@ -270,7 +270,7 @@ export default function GenericGrantAccessDialog({
{hasPeoplePickerAccess && (
<div className="space-y-2">
<h4 className="mb-2 flex items-center gap-2 text-sm font-medium text-text-primary">
<UserCheck className="h-4 w-4" />
<UserCheck className="h-4 w-4" aria-hidden="true" />
{localize('com_ui_user_group_permissions')} ( {allShares.length} )
</h4>
@ -295,7 +295,7 @@ export default function GenericGrantAccessDialog({
if (allShares.length === 0 && !hasChanges) {
return (
<div className="rounded-lg border-2 border-dashed border-border-light p-8 text-center">
<Users className="mx-auto h-8 w-8 text-text-primary" />
<Users className="mx-auto h-8 w-8 text-text-primary" aria-hidden="true" />
<p className="mt-2 text-sm text-text-primary">
{localize('com_ui_no_individual_access')}
</p>
@ -311,7 +311,7 @@ export default function GenericGrantAccessDialog({
{!hasAtLeastOneOwner && hasChanges && (
<div className="rounded-lg border border-destructive/30 bg-destructive/10 p-3 text-center">
<div className="flex items-center justify-center gap-2 text-sm text-red-600 dark:text-red-400">
<UserX className="h-4 w-4" />
<UserX className="h-4 w-4" aria-hidden="true" />
{localize('com_ui_at_least_one_owner_required')}
</div>
</div>
@ -363,7 +363,11 @@ export default function GenericGrantAccessDialog({
: localize('com_ui_copy_url_to_clipboard')
}
>
{isCopying ? <CopyCheck className="h-4 w-4" /> : <Link className="h-4 w-4" />}
{isCopying ? (
<CopyCheck className="h-4 w-4" aria-hidden="true" />
) : (
<Link className="h-4 w-4" aria-hidden="true" />
)}
</Button>
)}
</div>