️ fix: Accessibility, UI consistency, dialog & avatar refactors (#9975)

* 🔧 refactor: Improve accessibility and styling in ChatGroupItem and FilterPrompts components

* 🔧 fix: Add button type and keyboard accessibility to dropdown menu trigger in ChatGroupItem

* 🔧 fix(757): Enhance accessibility by updating aria-labels and adding localization for prompt groups

* 🔧 fix(618): Update version to 0.3.1 and enhance accessibility in InfoHoverCard component

* 🔧 fix(618): Update aria-label in InfoHoverCard to use dynamic text prop for improved accessibility

* 🔧 fix: Enhance accessibility by updating aria-labels and roles in Conversations components

* 🔧 fix(620): Enhance accessibility by adding tabIndex to Tabs.Content components in ArtifactTabs, Settings, and Speech components

* refactor: remove RevokeKeysButton component and update related components for accessibility

- Deleted RevokeKeysButton component.
- Updated SharedLinks and General components to use Label for accessibility.
- Enhanced Personalization component with aria-labelledby and aria-describedby attributes.
- Refactored ConversationModeSwitch to use ToggleSwitch for better state management.
- Improved AutoSendTextSelector with local state management and accessibility attributes.
- Replaced Switch components with ToggleSwitch in various Speech and TTS components for consistency.
- Added aria-labelledby attributes to Dropdown components for better accessibility.
- Updated translation.json to include new localization keys and improved existing ones.
- Enhanced Slider component to support aria attributes for better accessibility.

* 🔧 fix: Enhance user feedback for API key operations with success and error messages

* 🔧 fix: Update aria-labels in Avatar component for improved localization and accessibility

* 🔧 fix: Refactor handleFile and handleDrop functions for improved readability and maintainability
This commit is contained in:
Marco Beretta 2025-10-07 20:12:49 +02:00 committed by GitHub
parent bcd97aad2f
commit a5189052ec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
56 changed files with 1158 additions and 857 deletions

View file

@ -1,26 +0,0 @@
import { useRecoilState } from 'recoil';
import { Switch } from '@librechat/client';
import { useLocalize } from '~/hooks';
import store from '~/store';
export default function AtCommandSwitch() {
const [atCommand, setAtCommand] = useRecoilState<boolean>(store.atCommand);
const localize = useLocalize();
const handleCheckedChange = (value: boolean) => {
setAtCommand(value);
};
return (
<div className="flex items-center justify-between">
<div>{localize('com_nav_at_command_description')}</div>
<Switch
id="atCommand"
checked={atCommand}
onCheckedChange={handleCheckedChange}
className="ml-4"
data-testid="atCommand"
/>
</div>
);
}

View file

@ -1,10 +1,33 @@
import { memo } from 'react';
import { InfoHoverCard, ESide } from '@librechat/client';
import { PermissionTypes, Permissions } from 'librechat-data-provider';
import SlashCommandSwitch from './SlashCommandSwitch';
import { useLocalize, useHasAccess } from '~/hooks';
import PlusCommandSwitch from './PlusCommandSwitch';
import AtCommandSwitch from './AtCommandSwitch';
import ToggleSwitch from '../ToggleSwitch';
import store from '~/store';
const commandSwitchConfigs = [
{
stateAtom: store.atCommand,
localizationKey: 'com_nav_at_command_description' as const,
switchId: 'atCommand',
key: 'atCommand',
permissionType: undefined,
},
{
stateAtom: store.plusCommand,
localizationKey: 'com_nav_plus_command_description' as const,
switchId: 'plusCommand',
key: 'plusCommand',
permissionType: PermissionTypes.MULTI_CONVO,
},
{
stateAtom: store.slashCommand,
localizationKey: 'com_nav_slash_command_description' as const,
switchId: 'slashCommand',
key: 'slashCommand',
permissionType: PermissionTypes.PROMPTS,
},
] as const;
function Commands() {
const localize = useLocalize();
@ -19,6 +42,19 @@ function Commands() {
permission: Permissions.USE,
});
const getShowSwitch = (permissionType?: PermissionTypes) => {
if (!permissionType) {
return true;
}
if (permissionType === PermissionTypes.MULTI_CONVO) {
return hasAccessToMultiConvo === true;
}
if (permissionType === PermissionTypes.PROMPTS) {
return hasAccessToPrompts === true;
}
return true;
};
return (
<div className="space-y-4 p-1">
<div className="flex items-center gap-2">
@ -28,19 +64,16 @@ function Commands() {
<InfoHoverCard side={ESide.Bottom} text={localize('com_nav_chat_commands_info')} />
</div>
<div className="flex flex-col gap-3 text-sm text-text-primary">
<div className="pb-3">
<AtCommandSwitch />
</div>
{hasAccessToMultiConvo === true && (
<div className="pb-3">
<PlusCommandSwitch />
{commandSwitchConfigs.map((config) => (
<div key={config.key} className="pb-3">
<ToggleSwitch
stateAtom={config.stateAtom}
localizationKey={config.localizationKey}
switchId={config.switchId}
showSwitch={getShowSwitch(config.permissionType)}
/>
</div>
)}
{hasAccessToPrompts === true && (
<div className="pb-3">
<SlashCommandSwitch />
</div>
)}
))}
</div>
</div>
);

View file

@ -1,26 +0,0 @@
import { useRecoilState } from 'recoil';
import { Switch } from '@librechat/client';
import { useLocalize } from '~/hooks';
import store from '~/store';
export default function PlusCommandSwitch() {
const [plusCommand, setPlusCommand] = useRecoilState<boolean>(store.plusCommand);
const localize = useLocalize();
const handleCheckedChange = (value: boolean) => {
setPlusCommand(value);
};
return (
<div className="flex items-center justify-between">
<div>{localize('com_nav_plus_command_description')}</div>
<Switch
id="plusCommand"
checked={plusCommand}
onCheckedChange={handleCheckedChange}
className="ml-4"
data-testid="plusCommand"
/>
</div>
);
}

View file

@ -1,25 +0,0 @@
import { useRecoilState } from 'recoil';
import { Switch } from '@librechat/client';
import { useLocalize } from '~/hooks';
import store from '~/store';
export default function SlashCommandSwitch() {
const [slashCommand, setSlashCommand] = useRecoilState<boolean>(store.slashCommand);
const localize = useLocalize();
const handleCheckedChange = (value: boolean) => {
setSlashCommand(value);
};
return (
<div className="flex items-center justify-between">
<div>{localize('com_nav_slash_command_description')}</div>
<Switch
id="slashCommand"
checked={slashCommand}
onCheckedChange={handleCheckedChange}
data-testid="slashCommand"
/>
</div>
);
}