mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-23 18:56:12 +01:00
🔇 fix: Hide Button Icons from Screen Readers (#10776)
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:
parent
b288d81f5a
commit
1143f73f59
175 changed files with 340 additions and 183 deletions
|
|
@ -80,7 +80,7 @@ export default function AccessRolesPicker({
|
|||
<span className="font-medium">
|
||||
{selectedRoleInfo?.name || localize('com_ui_select')}
|
||||
</span>
|
||||
<ChevronDown className="h-4 w-4 text-text-secondary" />
|
||||
<ChevronDown className="h-4 w-4 text-text-secondary" aria-hidden="true" />
|
||||
</Ariakit.MenuButton>
|
||||
}
|
||||
items={dropdownItems}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -85,7 +85,10 @@ export function SearchPicker<TOption extends { key: string; value: string }>({
|
|||
{isLoading ? (
|
||||
<Spinner className="absolute left-3 h-4 w-4" />
|
||||
) : (
|
||||
<Search className="absolute left-3 h-4 w-4 text-text-secondary group-focus-within:text-text-primary group-hover:text-text-primary" />
|
||||
<Search
|
||||
className="absolute left-3 h-4 w-4 text-text-secondary group-focus-within:text-text-primary group-hover:text-text-primary"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
)}
|
||||
<Ariakit.Combobox
|
||||
ref={inputRef}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export default function SelectedPrincipalsList({
|
|||
return (
|
||||
<div className={`space-y-3 ${className}`}>
|
||||
<div className="rounded-lg border border-dashed border-border-medium py-8 text-center text-muted-foreground">
|
||||
<Users className="mx-auto mb-2 h-8 w-8 opacity-50" />
|
||||
<Users className="mx-auto mb-2 h-8 w-8 opacity-50" aria-hidden="true" />
|
||||
<p className="mt-1 text-xs">{localize('com_ui_search_above_to_add_all')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -64,7 +64,7 @@ export default function SelectedPrincipalsList({
|
|||
<span>{subtitle}</span>
|
||||
{share.source === 'entra' && (
|
||||
<>
|
||||
<ExternalLink className="h-3 w-3" />
|
||||
<ExternalLink className="h-3 w-3" aria-hidden="true" />
|
||||
<span>{localize('com_ui_azure_ad')}</span>
|
||||
</>
|
||||
)}
|
||||
|
|
@ -89,7 +89,7 @@ export default function SelectedPrincipalsList({
|
|||
className="h-9 w-9 p-0 hover:border-destructive/10 hover:bg-destructive/10 hover:text-destructive"
|
||||
aria-label={localize('com_ui_remove_user', { 0: displayName })}
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
<X className="h-4 w-4" aria-hidden="true" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue