mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-23 11:50:14 +01:00
🎨 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:
parent
c22d74d41e
commit
cd7dd576c1
9 changed files with 38 additions and 66 deletions
|
|
@ -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,
|
||||
),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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 && (
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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({
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue