LibreChat/client/src/components/Nav/SettingsTabs/Speech/STT/AutoSendTextSelector.tsx
Marco Beretta a5189052ec
️ 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
2025-10-07 14:12:49 -04:00

114 lines
3.5 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { Slider, InputNumber, Switch } from '@librechat/client';
import { cn, defaultTextProps, optionText } from '~/utils/';
import { useLocalize } from '~/hooks';
import store from '~/store';
export default function AutoSendTextSelector() {
const localize = useLocalize();
const speechToText = useRecoilValue(store.speechToText);
const [autoSendText, setAutoSendText] = useRecoilState(store.autoSendText);
// Local state for enabled/disabled toggle
const [isEnabled, setIsEnabled] = useState(autoSendText !== -1);
const [delayValue, setDelayValue] = useState(autoSendText === -1 ? 3 : autoSendText);
// Sync local state when autoSendText changes externally
useEffect(() => {
setIsEnabled(autoSendText !== -1);
if (autoSendText !== -1) {
setDelayValue(autoSendText);
}
}, [autoSendText]);
const handleToggle = (enabled: boolean) => {
setIsEnabled(enabled);
if (enabled) {
setAutoSendText(delayValue);
} else {
setAutoSendText(-1);
}
};
const handleSliderChange = (value: number[]) => {
const newValue = value[0];
setDelayValue(newValue);
if (isEnabled) {
setAutoSendText(newValue);
}
};
const handleInputChange = (value: number[] | null) => {
const newValue = value ? value[0] : 3;
setDelayValue(newValue);
if (isEnabled) {
setAutoSendText(newValue);
}
};
const labelId = 'auto-send-text-label';
return (
<div className="flex flex-col gap-3">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<div id={labelId}>{localize('com_nav_auto_send_text')}</div>
</div>
<Switch
id="autoSendTextToggle"
checked={isEnabled}
onCheckedChange={handleToggle}
className="ml-4"
data-testid="autoSendTextToggle"
aria-labelledby={labelId}
disabled={!speechToText}
/>
</div>
{isEnabled && (
<div className="mt-2 flex items-center justify-between">
<div className="flex items-center justify-between">
<div id="auto-send-delay-label" className="text-sm text-text-secondary">
{localize('com_nav_setting_delay')}
</div>
</div>
<div className="flex items-center justify-between">
<Slider
value={[delayValue]}
onValueChange={handleSliderChange}
onDoubleClick={() => {
setDelayValue(3);
if (isEnabled) {
setAutoSendText(3);
}
}}
min={0}
max={60}
step={1}
className="ml-4 flex h-4 w-24"
disabled={!speechToText || !isEnabled}
aria-labelledby="auto-send-delay-label"
/>
<div className="w-2" />
<InputNumber
value={`${delayValue} s`}
disabled={!speechToText || !isEnabled}
onChange={handleInputChange}
min={0}
max={60}
aria-labelledby="auto-send-delay-label"
className={cn(
defaultTextProps,
cn(
optionText,
'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200',
),
)}
/>
</div>
</div>
)}
</div>
);
}