mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-04 09:38:50 +01:00
* 🔧 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
71 lines
2.2 KiB
TypeScript
71 lines
2.2 KiB
TypeScript
import React from 'react';
|
|
import { useRecoilState } from 'recoil';
|
|
import { Dropdown } from '@librechat/client';
|
|
import type { Option } from '~/common';
|
|
import { useLocalize, useTTSBrowser, useTTSExternal } from '~/hooks';
|
|
import { logger } from '~/utils';
|
|
import store from '~/store';
|
|
|
|
export function BrowserVoiceDropdown() {
|
|
const localize = useLocalize();
|
|
const { voices = [] } = useTTSBrowser();
|
|
const [voice, setVoice] = useRecoilState(store.voice);
|
|
|
|
const handleVoiceChange = (newValue?: string | Option) => {
|
|
logger.log('Browser Voice changed:', newValue);
|
|
const newVoice = typeof newValue === 'string' ? newValue : newValue?.value;
|
|
if (newVoice != null) {
|
|
return setVoice(newVoice.toString());
|
|
}
|
|
};
|
|
|
|
const labelId = 'browser-voice-dropdown-label';
|
|
|
|
return (
|
|
<div className="flex items-center justify-between">
|
|
<div id={labelId}>{localize('com_nav_voice_select')}</div>
|
|
<Dropdown
|
|
key={`browser-voice-dropdown-${voices.length}`}
|
|
value={voice ?? ''}
|
|
options={voices}
|
|
onChange={handleVoiceChange}
|
|
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
|
|
testId="BrowserVoiceDropdown"
|
|
className="z-50"
|
|
aria-labelledby={labelId}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function ExternalVoiceDropdown() {
|
|
const localize = useLocalize();
|
|
const { voices = [] } = useTTSExternal();
|
|
const [voice, setVoice] = useRecoilState(store.voice);
|
|
|
|
const handleVoiceChange = (newValue?: string | Option) => {
|
|
logger.log('External Voice changed:', newValue);
|
|
const newVoice = typeof newValue === 'string' ? newValue : newValue?.value;
|
|
if (newVoice != null) {
|
|
return setVoice(newVoice.toString());
|
|
}
|
|
};
|
|
|
|
const labelId = 'external-voice-dropdown-label';
|
|
|
|
return (
|
|
<div className="flex items-center justify-between">
|
|
<div id={labelId}>{localize('com_nav_voice_select')}</div>
|
|
<Dropdown
|
|
key={`external-voice-dropdown-${voices.length}`}
|
|
value={voice ?? ''}
|
|
options={voices}
|
|
onChange={handleVoiceChange}
|
|
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
|
|
testId="ExternalVoiceDropdown"
|
|
className="z-50"
|
|
aria-labelledby={labelId}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|