mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
⌨️ style(a11y): kb access for LLM endpoint menu; refactor: style (#3714)
This commit is contained in:
parent
98b437edd5
commit
0c5568b80b
6 changed files with 48 additions and 50 deletions
|
|
@ -84,14 +84,13 @@ export default function HeaderOptions({
|
||||||
)}
|
)}
|
||||||
{!noSettings[endpoint] && interfaceConfig?.parameters && (
|
{!noSettings[endpoint] && interfaceConfig?.parameters && (
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
|
||||||
className={cn(
|
|
||||||
cardStyle,
|
|
||||||
'z-50 flex h-[40px] min-w-4 flex-none items-center justify-center px-3 focus:ring-0 focus:ring-offset-0',
|
|
||||||
'hover:bg-gray-50 radix-state-open:bg-gray-50 dark:hover:bg-gray-700 dark:radix-state-open:bg-gray-700',
|
|
||||||
)}
|
|
||||||
onClick={triggerAdvancedMode}
|
|
||||||
aria-label="Settings/parameters"
|
aria-label="Settings/parameters"
|
||||||
|
id="parameters-button"
|
||||||
|
data-testid="parameters-button"
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
onClick={triggerAdvancedMode}
|
||||||
|
className="flex h-[40px] min-w-4 px-3 radix-state-open:bg-surface-hover"
|
||||||
>
|
>
|
||||||
<Settings2 className="w-4 text-gray-600 dark:text-white" />
|
<Settings2 className="w-4 text-gray-600 dark:text-white" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -97,11 +97,8 @@ const MenuItem: FC<MenuItemProps> = ({
|
||||||
<div
|
<div
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
className={cn(
|
className={cn(
|
||||||
'group m-1.5 flex max-h-[40px] cursor-pointer gap-2 rounded px-5 py-2.5 !pr-3 text-sm !opacity-100',
|
'group m-1.5 flex max-h-[40px] cursor-pointer gap-2 rounded px-5 py-2.5 !pr-3 text-sm !opacity-100 hover:bg-surface-hover',
|
||||||
'hover:bg-black/5 dark:hover:bg-gray-600',
|
|
||||||
'radix-disabled:pointer-events-none radix-disabled:opacity-50',
|
'radix-disabled:pointer-events-none radix-disabled:opacity-50',
|
||||||
'focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2',
|
|
||||||
'dark:focus:ring-gray-400 dark:focus:ring-offset-gray-900',
|
|
||||||
)}
|
)}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
{...rest}
|
{...rest}
|
||||||
|
|
@ -138,10 +135,7 @@ const MenuItem: FC<MenuItemProps> = ({
|
||||||
className={cn(
|
className={cn(
|
||||||
'invisible flex gap-x-1 group-hover:visible',
|
'invisible flex gap-x-1 group-hover:visible',
|
||||||
selected ? 'visible' : '',
|
selected ? 'visible' : '',
|
||||||
expiryTime
|
expiryTime ? 'text-token-text-primary w-full rounded-lg p-2' : '',
|
||||||
? 'w-full rounded-lg p-2 hover:text-gray-400 dark:hover:text-gray-400'
|
|
||||||
: '',
|
|
||||||
'focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 dark:focus:ring-gray-400 dark:focus:ring-offset-gray-900',
|
|
||||||
)}
|
)}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { Content, Portal, Root, Trigger } from '@radix-ui/react-popover';
|
||||||
import { EditPresetDialog, PresetItems } from './Presets';
|
import { EditPresetDialog, PresetItems } from './Presets';
|
||||||
import { useLocalize, usePresets } from '~/hooks';
|
import { useLocalize, usePresets } from '~/hooks';
|
||||||
import { useChatContext } from '~/Providers';
|
import { useChatContext } from '~/Providers';
|
||||||
import { cn } from '~/utils';
|
import { Button } from '~/components/ui';
|
||||||
|
|
||||||
const PresetsMenu: FC = () => {
|
const PresetsMenu: FC = () => {
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
|
|
@ -25,19 +25,17 @@ const PresetsMenu: FC = () => {
|
||||||
return (
|
return (
|
||||||
<Root>
|
<Root>
|
||||||
<Trigger asChild>
|
<Trigger asChild>
|
||||||
<button
|
<Button
|
||||||
className={cn(
|
type="button"
|
||||||
'pointer-cursor relative flex flex-col rounded-md border border-gray-100 bg-white text-left focus:ring-0 focus:ring-offset-0 dark:border-gray-700 dark:bg-gray-800 sm:text-sm',
|
variant="outline"
|
||||||
'hover:bg-gray-50 radix-state-open:bg-gray-50 dark:hover:bg-gray-700 dark:radix-state-open:bg-gray-700',
|
className="flex h-[40px] min-w-4 px-3 radix-state-open:bg-surface-hover"
|
||||||
'z-50 flex h-[40px] min-w-4 flex-none items-center justify-center px-3',
|
|
||||||
)}
|
|
||||||
id="presets-button"
|
id="presets-button"
|
||||||
data-testid="presets-button"
|
data-testid="presets-button"
|
||||||
title={localize('com_endpoint_examples')}
|
title={localize('com_endpoint_examples')}
|
||||||
aria-label={localize('com_endpoint_examples')}
|
aria-label={localize('com_endpoint_examples')}
|
||||||
>
|
>
|
||||||
<BookCopy className="icon-sm" id="presets-button" />
|
<BookCopy className="icon-sm" id="presets-button" />
|
||||||
</button>
|
</Button>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
<Portal>
|
<Portal>
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,25 @@
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { ChevronDown } from 'lucide-react';
|
||||||
import { Trigger } from '@radix-ui/react-popover';
|
import { Trigger } from '@radix-ui/react-popover';
|
||||||
|
|
||||||
export default function TitleButton({ primaryText = '', secondaryText = '' }) {
|
export default function TitleButton({ primaryText = '', secondaryText = '' }) {
|
||||||
|
const [isExpanded, setIsExpanded] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Trigger asChild>
|
<Trigger asChild>
|
||||||
<button
|
<button
|
||||||
className="group flex cursor-pointer items-center gap-1 rounded-xl px-3 py-2 text-lg font-medium hover:bg-gray-50 radix-state-open:bg-gray-50 dark:hover:bg-gray-700 dark:radix-state-open:bg-gray-700"
|
className="group flex cursor-pointer items-center gap-2 rounded-lg px-3 py-1.5 text-lg font-medium transition-colors duration-200 hover:bg-surface-hover radix-state-open:bg-surface-hover"
|
||||||
type="button"
|
|
||||||
aria-label={`Select ${primaryText}`}
|
aria-label={`Select ${primaryText}`}
|
||||||
|
aria-haspopup="dialog"
|
||||||
|
aria-expanded={isExpanded}
|
||||||
|
aria-controls="radix-:r6:"
|
||||||
|
onClick={() => setIsExpanded(!isExpanded)}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
{primaryText}{' '}
|
<span className="text-token-text-secondary"> {primaryText} </span>
|
||||||
{!!secondaryText && <span className="text-token-text-secondary">{secondaryText}</span>}
|
{!!secondaryText && <span className="text-token-text-secondary">{secondaryText}</span>}
|
||||||
</div>
|
</div>
|
||||||
<svg
|
<ChevronDown className="text-token-text-secondary size-4" />
|
||||||
width="16"
|
|
||||||
height="17"
|
|
||||||
viewBox="0 0 16 17"
|
|
||||||
fill="none"
|
|
||||||
className="text-token-text-tertiary"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M11.3346 7.83203L8.00131 11.1654L4.66797 7.83203"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ function PluginStoreDialog({ isOpen, setIsOpen }: TPluginStoreDialogProps) {
|
||||||
(error: TError) => {
|
(error: TError) => {
|
||||||
setError(true);
|
setError(true);
|
||||||
if (error.response?.data?.message) {
|
if (error.response?.data?.message) {
|
||||||
setErrorMessage(error.response?.data?.message);
|
setErrorMessage(error.response.data.message);
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setError(false);
|
setError(false);
|
||||||
|
|
@ -187,7 +187,8 @@ function PluginStoreDialog({ isOpen, setIsOpen }: TPluginStoreDialogProps) {
|
||||||
value={searchValue}
|
value={searchValue}
|
||||||
onChange={handleSearch}
|
onChange={handleSearch}
|
||||||
placeholder={localize('com_nav_plugin_search')}
|
placeholder={localize('com_nav_plugin_search')}
|
||||||
className="flex rounded-md border border-gray-200 bg-transparent py-2 pl-10 pr-2 shadow-[0_0_10px_rgba(0,0,0,0.05)] outline-none placeholder:text-gray-400 focus:border-gray-400 focus:bg-gray-50 focus:outline-none focus:ring-0 focus:ring-gray-400 focus:ring-opacity-0 focus:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:border-gray-500 focus:dark:bg-gray-600 dark:focus:outline-none dark:focus:ring-0 dark:focus:ring-gray-500 dark:focus:ring-offset-0 dark:focus:ring-offset-gray-900"
|
className="
|
||||||
|
text-token-text-primary flex rounded-md border border-border-heavy bg-surface-tertiary py-2 pl-10 pr-2"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2271,30 +2271,30 @@ button.scroll-convo {
|
||||||
}
|
}
|
||||||
|
|
||||||
.moon-rise {
|
.moon-rise {
|
||||||
animation: moonRise 4s ease-in-out infinite; /* 'forwards' mantém a lua na posição final após a animação */
|
animation: moonRise 4s ease-in-out infinite;
|
||||||
transform-origin: 45% 50%; /* Ajuste dependendo da posição relativa do morro */
|
transform-origin: 45% 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes moveUp {
|
@keyframes moveUp {
|
||||||
0% {
|
0% {
|
||||||
transform: translateY(0.5px); /* Move um pouco para cima */
|
transform: translateY(0.5px);
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
10% {
|
10% {
|
||||||
transform: translateY(0.5px); /* Move um pouco para cima */
|
transform: translateY(0.5px);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
20% {
|
20% {
|
||||||
transform: translateY(0px); /* Move um pouco para cima */
|
transform: translateY(0px);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
transform: translateY(0px); /* Move um pouco para cima */
|
transform: translateY(0px);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
60%,
|
60%,
|
||||||
100% {
|
100% {
|
||||||
transform: translateY(0px); /* Move um pouco para cima */
|
transform: translateY(0px);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2341,3 +2341,16 @@ button.scroll-convo {
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:focus-visible {
|
||||||
|
outline: 2px solid #000;
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark :focus-visible {
|
||||||
|
outline: 2px solid #fff;
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue