⌨️ style(a11y): kb access for LLM endpoint menu; refactor: style (#3714)

This commit is contained in:
Marco Beretta 2024-08-22 00:19:33 +02:00 committed by GitHub
parent 98b437edd5
commit 0c5568b80b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 48 additions and 50 deletions

View file

@ -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>

View file

@ -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();

View file

@ -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

View file

@ -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>
); );

View file

@ -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>

View file

@ -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;
}