🎨 style: Unify Styles across Themes and Improve Accessibility (#7783)

* style: update button styles for improved hover effects and accessibility

* style: enhance CustomMenuItem styling for improved visual feedback

* style: improved accessibility and visual consistency

* chore: add missing localization in ActionsPanel

---------

Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
Marco Beretta 2025-06-08 00:22:08 +02:00 committed by GitHub
parent c22d74d41e
commit cd7dd576c1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 38 additions and 66 deletions

View file

@ -159,7 +159,7 @@ export const CustomMenuItem = React.forwardRef<HTMLDivElement, CustomMenuItemPro
blurOnHoverEnd: false,
...props,
className: cn(
'flex cursor-default items-center gap-2 rounded-lg p-2 outline-none! scroll-m-1 scroll-mt-[calc(var(--combobox-height,0px)+var(--label-height,4px))] aria-disabled:opacity-25 border-l-2 border-transparent data-[active-item]:border-black data-[active-item]:rounded-l-none data-[active-item]:bg-black/[0.075] data-[active-item]:text-black dark:data-[active-item]:bg-white/10 dark:data-[active-item]:text-white dark:data-[active-item]:border-white sm:py-1 sm:text-sm min-w-0 w-full',
'relative flex cursor-default items-center gap-2 rounded-lg p-2 outline-none! scroll-m-1 scroll-mt-[calc(var(--combobox-height,0px)+var(--label-height,4px))] aria-disabled:opacity-25 data-[active-item]:bg-black/[0.075] data-[active-item]:text-black dark:data-[active-item]:bg-white/10 dark:data-[active-item]:text-white sm:py-1 sm:text-sm min-w-0 w-full before:absolute before:left-0 before:top-1 before:bottom-1 before:w-0.5 before:bg-transparent before:rounded-full data-[active-item]:before:bg-black dark:data-[active-item]:before:bg-white',
props.className,
),
};

View file

@ -68,7 +68,7 @@ export default function DialogImage({ isOpen, onOpenChange, src = '', downloadIm
/>
<div className="flex items-center gap-2">
<TooltipAnchor
description={localize('com_ui_save')}
description={localize('com_ui_download')}
render={
<Button onClick={() => downloadImage()} variant="ghost" className="h-10 w-10 p-0">
<ArrowDownToLine className="size-6" />
@ -108,7 +108,7 @@ export default function DialogImage({ isOpen, onOpenChange, src = '', downloadIm
alt="Image"
className="max-h-full max-w-full object-contain"
style={{
maxHeight: 'calc(100vh - 6rem)', // Account for header and padding
maxHeight: 'calc(100vh - 6rem)',
maxWidth: '100%',
}}
/>
@ -117,7 +117,7 @@ export default function DialogImage({ isOpen, onOpenChange, src = '', downloadIm
{/* Side Panel */}
<div
className={`shadow-l-lg fixed right-0 top-0 z-20 h-full w-80 transform rounded-l-2xl border-l border-border-light bg-surface-secondary transition-transform duration-500 ease-in-out ${
className={`shadow-l-lg fixed right-0 top-0 z-20 h-full w-80 transform rounded-l-2xl border-l border-border-light bg-surface-primary transition-transform duration-500 ease-in-out ${
isPromptOpen ? 'translate-x-0' : 'translate-x-full'
}`}
>
@ -132,7 +132,7 @@ export default function DialogImage({ isOpen, onOpenChange, src = '', downloadIm
<div className="space-y-6">
{/* Prompt Section */}
<div>
<h4 className="mb-2 text-sm font-medium text-text-secondary">
<h4 className="mb-2 text-sm font-medium text-text-primary">
{localize('com_ui_prompt')}
</h4>
<div className="rounded-md bg-surface-tertiary p-3">
@ -144,20 +144,18 @@ export default function DialogImage({ isOpen, onOpenChange, src = '', downloadIm
{/* Generation Settings */}
<div>
<h4 className="mb-3 text-sm font-medium text-text-secondary">
<h4 className="mb-3 text-sm font-medium text-text-primary">
{localize('com_ui_generation_settings')}
</h4>
<div className="space-y-3">
<div className="flex items-center justify-between">
<span className="text-sm text-text-secondary">{localize('com_ui_size')}:</span>
<span className="text-sm text-text-primary">{localize('com_ui_size')}:</span>
<span className="text-sm font-medium text-text-primary">
{args?.size || 'Unknown'}
</span>
</div>
<div className="flex items-center justify-between">
<span className="text-sm text-text-secondary">
{localize('com_ui_quality')}:
</span>
<span className="text-sm text-text-primary">{localize('com_ui_quality')}:</span>
<span
className={`rounded px-2 py-1 text-xs font-medium capitalize ${
args?.quality === 'high'
@ -171,7 +169,7 @@ export default function DialogImage({ isOpen, onOpenChange, src = '', downloadIm
</span>
</div>
<div className="flex items-center justify-between">
<span className="text-sm text-text-secondary">
<span className="text-sm text-text-primary">
{localize('com_ui_file_size')}:
</span>
<span className="text-sm font-medium text-text-primary">

View file

@ -178,17 +178,6 @@ export default function OpenAIImageGen({
<div className="relative my-2.5 flex size-5 shrink-0 items-center gap-2.5">
<ProgressText progress={progress} error={cancelled} toolName={toolName} />
</div>
{/* {showInfo && hasInfo && (
<ToolCallInfo
key="tool-call-info"
input={args ?? ''}
output={output}
function_name={function_name}
pendingAuth={authDomain.length > 0 && !cancelled && initialProgress < 1}
/>
)} */}
<div className="relative mb-2 flex w-full justify-start">
<div ref={containerRef} className="w-full max-w-lg">
{dimensions.width !== 'auto' && progress < 1 && (

View file

@ -216,18 +216,12 @@ function FeedbackButtons({
function buttonClasses(isActive: boolean, isLast: boolean) {
return cn(
'hover-button rounded-lg p-1.5',
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-black dark:focus-visible:ring-white',
'hover:bg-gray-100 hover:text-gray-500',
'data-[state=open]:active data-[state=open]:bg-gray-100 data-[state=open]:text-gray-500',
isActive ? 'text-gray-500 dark:text-gray-200 font-bold' : 'dark:text-gray-400/70',
'dark:hover:bg-gray-700 dark:hover:text-gray-200',
'data-[state=open]:dark:bg-gray-700 data-[state=open]:dark:text-gray-200',
'disabled:dark:hover:text-gray-400',
isLast
? ''
: 'data-[state=open]:opacity-100 md:opacity-0 md:group-focus-within:opacity-100 md:group-hover:opacity-100',
'md:group-focus-within:visible md:group-hover:visible md:group-[.final-completion]:visible',
'hover-button rounded-lg p-1.5 text-text-secondary-alt transition-colors duration-200',
'hover:text-text-primary hover:bg-surface-hover',
'md:group-hover:visible md:group-focus-within:visible md:group-[.final-completion]:visible',
!isLast && 'md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100',
'focus-visible:ring-2 focus-visible:ring-black dark:focus-visible:ring-white focus-visible:outline-none',
isActive && 'active text-text-primary bg-surface-hover',
);
}

View file

@ -211,14 +211,12 @@ export default function Fork({
});
const buttonStyle = cn(
'hover-button rounded-lg p-1.5',
'hover:bg-gray-100 hover:text-gray-500',
'dark:text-gray-400/70 dark:hover:bg-gray-700 dark:hover:text-gray-200',
'disabled:dark:hover:text-gray-400',
'hover-button rounded-lg p-1.5 text-text-secondary-alt transition-colors duration-200',
'hover:text-text-primary hover:bg-surface-hover',
'md:group-hover:visible md:group-focus-within:visible md:group-[.final-completion]:visible',
!isLast && 'md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100',
'focus-visible:ring-2 focus-visible:ring-black dark:focus-visible:ring-white focus-visible:outline-none',
isActive && 'active text-gray-700 dark:text-gray-200 bg-gray-100 bg-gray-700',
isActive && 'active text-text-primary bg-surface-hover',
);
const forkConvo = useForkConvoMutation({

View file

@ -77,21 +77,13 @@ const HoverButton = memo(
className = '',
}: HoverButtonProps) => {
const buttonStyle = cn(
'hover-button rounded-lg p-1.5',
'hover:bg-gray-100 hover:text-gray-500',
'dark:text-gray-400/70 dark:hover:bg-gray-700 dark:hover:text-gray-200',
'disabled:dark:hover:text-gray-400',
'hover-button rounded-lg p-1.5 text-text-secondary-alt transition-colors duration-200',
'hover:text-text-primary hover:bg-surface-hover',
'md:group-hover:visible md:group-focus-within:visible md:group-[.final-completion]:visible',
!isLast && 'md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100',
!isVisible && 'opacity-0',
'focus-visible:ring-2 focus-visible:ring-black dark:focus-visible:ring-white focus-visible:outline-none',
isActive && isVisible && 'active text-gray-700 dark:text-gray-200 bg-gray-100 bg-gray-700',
isActive && isVisible && 'active text-text-primary bg-surface-hover',
className,
);