mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-22 10:16:13 +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
|
|
@ -92,6 +92,7 @@ export default function Badge({
|
|||
'@container-[600px]:h-4 @container-[600px]:w-4 relative h-5 w-5',
|
||||
!label && 'mx-auto',
|
||||
)}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
)}
|
||||
<span className="@container-[600px]:inline relative hidden">{label}</span>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ const DialogContent = React.forwardRef<
|
|||
{children}
|
||||
{showCloseButton && (
|
||||
<DialogPrimitive.Close className="absolute right-6 top-[1.6rem] rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-gray-100 dark:focus:ring-white dark:focus:ring-offset-gray-700 dark:data-[state=open]:bg-gray-800">
|
||||
<X className="h-5 w-5 text-black dark:text-white" />
|
||||
<X className="h-5 w-5 text-black dark:text-white" aria-hidden="true" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ const DialogContent = React.forwardRef<
|
|||
{children}
|
||||
{showCloseButton && (
|
||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-ring-primary ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
||||
<X className="h-4 w-4" />
|
||||
<X className="h-4 w-4" aria-hidden="true" />
|
||||
{/* eslint-disable-next-line i18next/no-literal-string */}
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ const PaginationPrevious = ({
|
|||
className={cn('gap-1 pl-2.5', className)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronLeft className="h-4 w-4" />
|
||||
<ChevronLeft className="h-4 w-4" aria-hidden="true" />
|
||||
<span>Previous</span>
|
||||
</PaginationLink>
|
||||
);
|
||||
|
|
@ -77,7 +77,7 @@ const PaginationNext = ({ className, ...props }: React.ComponentProps<typeof Pag
|
|||
{...props}
|
||||
>
|
||||
<span>Next</span>
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
<ChevronRight className="h-4 w-4" aria-hidden="true" />
|
||||
</PaginationLink>
|
||||
);
|
||||
PaginationNext.displayName = 'PaginationNext';
|
||||
|
|
@ -88,7 +88,7 @@ const PaginationEllipsis = ({ className, ...props }: React.ComponentProps<'span'
|
|||
className={cn('flex h-9 w-9 items-center justify-center', className)}
|
||||
{...props}
|
||||
>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
<MoreHorizontal className="h-4 w-4" aria-hidden="true" />
|
||||
<span className="sr-only">More pages</span>
|
||||
</span>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -102,7 +102,11 @@ const Radio = memo(function Radio({
|
|||
currentValue === option.value ? 'text-foreground' : 'text-foreground'
|
||||
} ${disabled ? 'cursor-not-allowed opacity-50' : ''} ${fullWidth ? 'flex-1' : ''}`}
|
||||
>
|
||||
{option.icon && <span className="flex-shrink-0">{option.icon}</span>}
|
||||
{option.icon && (
|
||||
<span className="flex-shrink-0" aria-hidden="true">
|
||||
{option.icon}
|
||||
</span>
|
||||
)}
|
||||
<span className="whitespace-nowrap">{option.label}</span>
|
||||
</button>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ const TagPrimitiveRoot = React.forwardRef<HTMLDivElement, TagProps>(
|
|||
className="rounded-full bg-green-600/50"
|
||||
aria-label={`Remove ${label}`}
|
||||
>
|
||||
<X className="m-[1.5px] p-1" />
|
||||
<X className="m-[1.5px] p-1" aria-hidden="true" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ type ThemeType = 'system' | 'dark' | 'light';
|
|||
|
||||
const Theme = ({ theme, onChange }: { theme: string; onChange: (value: string) => void }) => {
|
||||
const themeIcons: Record<ThemeType, JSX.Element> = {
|
||||
system: <Monitor />,
|
||||
dark: <Moon color="white" />,
|
||||
light: <Sun />,
|
||||
system: <Monitor aria-hidden="true" />,
|
||||
dark: <Moon color="white" aria-hidden="true" />,
|
||||
light: <Sun aria-hidden="true" />,
|
||||
};
|
||||
|
||||
const nextTheme = isDark(theme) ? 'light' : 'dark';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue