From 8f7b6ec773b60e5957c16bc2e0f5fbca595da7ff Mon Sep 17 00:00:00 2001 From: bdim404 Date: Mon, 26 Jan 2026 17:11:03 +0800 Subject: [PATCH] Add IconLabel component and integrate it into forms for improved accessibility and UI consistency --- .../src/components/IconLabel.tsx | 26 ++ .../src/components/PresetSelector.tsx | 10 +- .../src/components/tts/CustomVoiceForm.tsx | 256 +++++++++++++----- .../src/components/tts/VoiceCloneForm.tsx | 122 ++++++--- .../src/components/tts/VoiceDesignForm.tsx | 252 ++++++++++++----- qwen3-tts-frontend/src/pages/Home.tsx | 18 +- 6 files changed, 506 insertions(+), 178 deletions(-) create mode 100644 qwen3-tts-frontend/src/components/IconLabel.tsx diff --git a/qwen3-tts-frontend/src/components/IconLabel.tsx b/qwen3-tts-frontend/src/components/IconLabel.tsx new file mode 100644 index 0000000..1702c1a --- /dev/null +++ b/qwen3-tts-frontend/src/components/IconLabel.tsx @@ -0,0 +1,26 @@ +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip' +import type { ElementType } from 'react' + +interface IconLabelProps { + icon: ElementType + tooltip: string + required?: boolean +} + +export function IconLabel({ icon: Icon, tooltip, required = false }: IconLabelProps) { + return ( + + + +
+ + {required && *} +
+
+ +

{tooltip}

+
+
+
+ ) +} diff --git a/qwen3-tts-frontend/src/components/PresetSelector.tsx b/qwen3-tts-frontend/src/components/PresetSelector.tsx index 5ab21d8..418eb43 100644 --- a/qwen3-tts-frontend/src/components/PresetSelector.tsx +++ b/qwen3-tts-frontend/src/components/PresetSelector.tsx @@ -21,7 +21,7 @@ const PresetSelectorInner = ({ presets, onSelect }: PresetSele variant="outline" size="sm" onClick={() => onSelect(preset)} - className="text-xs md:text-sm px-2 h-6 md:h-7" + className="text-xs md:text-sm px-2 py-0.5 h-5" > {preset.label} @@ -34,19 +34,19 @@ const PresetSelectorInner = ({ presets, onSelect }: PresetSele } return ( -
+
{presetButtons}
) diff --git a/qwen3-tts-frontend/src/components/tts/CustomVoiceForm.tsx b/qwen3-tts-frontend/src/components/tts/CustomVoiceForm.tsx index f756fa5..2c2204b 100644 --- a/qwen3-tts-frontend/src/components/tts/CustomVoiceForm.tsx +++ b/qwen3-tts-frontend/src/components/tts/CustomVoiceForm.tsx @@ -6,10 +6,12 @@ import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Textarea } from '@/components/ui/textarea' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' -import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible' +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogFooter } from '@/components/ui/dialog' import { Label } from '@/components/ui/label' -import { ChevronDown } from 'lucide-react' +import { Globe2, User, Type, Sparkles, Play, Settings } from 'lucide-react' import { toast } from 'sonner' +import { IconLabel } from '@/components/IconLabel' +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip' import { ttsApi, jobApi } from '@/lib/api' import { useJobPolling } from '@/hooks/useJobPolling' import { LoadingState } from '@/components/LoadingState' @@ -42,6 +44,13 @@ const CustomVoiceForm = forwardRef((_props, ref) => { const [speakers, setSpeakers] = useState([]) const [isLoading, setIsLoading] = useState(false) const [advancedOpen, setAdvancedOpen] = useState(false) + const [tempAdvancedParams, setTempAdvancedParams] = useState({ + max_new_tokens: 2048, + temperature: 0.3, + top_k: 20, + top_p: 0.7, + repetition_penalty: 1.05 + }) const { currentJob, isPolling, isCompleted, startPolling, elapsedTime } = useJobPolling() @@ -116,9 +125,9 @@ const CustomVoiceForm = forwardRef((_props, ref) => { }, [currentJob?.id, currentJob?.audio_url]) return ( -
-
- + +
+ setValue('speaker', value)} @@ -161,8 +170,8 @@ const CustomVoiceForm = forwardRef((_props, ref) => { )}
-
- +
+