11// src/components/features/generate/GenerateForm.tsx
2- import { useEffect } from 'react' ;
2+ import { useEffect , useState } from 'react' ;
33import { useTranslation } from 'react-i18next' ;
44import { useForm } from 'react-hook-form' ;
55import { zodResolver } from '@hookform/resolvers/zod' ;
6- import { Sparkles , Wand2 , Mic , MicOff } from 'lucide-react' ;
6+ import { ChevronDown , Mic , MicOff , SlidersHorizontal , Sparkles , Wand2 } from 'lucide-react' ;
77import { Button } from '@/components/ui/button' ;
88import { Input } from '@/components/ui/input' ;
99import { Label } from '@/components/ui/label' ;
@@ -29,6 +29,7 @@ interface GenerateFormProps {
2929export function GenerateForm ( { onSubmit, isLoading } : GenerateFormProps ) {
3030 const { t } = useTranslation ( ) ;
3131 const { generateForm, setGenerateForm } = useSessionStore ( ) ;
32+ const [ advancedOpen , setAdvancedOpen ] = useState ( false ) ;
3233
3334 const { register, handleSubmit, setValue, watch, formState : { errors } } = useForm < GenerateInput > ( {
3435 resolver : zodResolver ( GenerateInputSchema ) ,
@@ -128,7 +129,7 @@ export function GenerateForm({ onSubmit, isLoading }: GenerateFormProps) {
128129 ) }
129130 </ div >
130131
131- { /* Two Column Grid */ }
132+ { /* Main Options */ }
132133 < div className = "grid gap-4 sm:grid-cols-2" >
133134 { /* Side */ }
134135 < div className = "space-y-2" >
@@ -183,58 +184,86 @@ export function GenerateForm({ onSubmit, isLoading }: GenerateFormProps) {
183184 </ Select >
184185 </ div >
185186
186- { /* Length */ }
187+ { /* More */ }
187188 < div className = "space-y-2" >
188- < Label className = "text-sm font-medium" > { t ( 'generateForm.length' ) } </ Label >
189- < Select
190- value = { currentValues . length }
191- onValueChange = { ( value ) => setValue ( 'length' , value as GenerateInput [ 'length' ] ) }
189+ < Label className = "text-sm font-medium" > { t ( 'generateForm.more' ) } </ Label >
190+ < Button
191+ type = "button"
192+ variant = "outline"
193+ className = "h-10 w-full justify-between"
194+ aria-expanded = { advancedOpen }
195+ aria-controls = "generate-more-options"
196+ onClick = { ( ) => setAdvancedOpen ( ( open ) => ! open ) }
192197 >
193- < SelectTrigger >
194- < SelectValue />
195- </ SelectTrigger >
196- < SelectContent >
197- < SelectItem value = "brief" > { t ( 'generateForm.lengthBrief' ) } </ SelectItem >
198- < SelectItem value = "standard" > { t ( 'generateForm.lengthStandard' ) } </ SelectItem >
199- < SelectItem value = "comprehensive" > { t ( 'generateForm.lengthComprehensive' ) } </ SelectItem >
200- </ SelectContent >
201- </ Select >
198+ < span className = "flex items-center gap-2" >
199+ < SlidersHorizontal className = "h-4 w-4" />
200+ { t ( 'generateForm.moreOptions' ) }
201+ </ span >
202+ < ChevronDown className = { `h-4 w-4 transition-transform duration-300 ${ advancedOpen ? 'rotate-180' : '' } ` } />
203+ </ Button >
202204 </ div >
205+ </ div >
203206
204- { /* Audience */ }
205- < div className = "space-y-2" >
206- < Label className = "text-sm font-medium" > { t ( 'generateForm.audience' ) } </ Label >
207- < Select
208- value = { currentValues . audience }
209- onValueChange = { ( value ) => setValue ( 'audience' , value as GenerateInput [ 'audience' ] ) }
210- >
211- < SelectTrigger >
212- < SelectValue />
213- </ SelectTrigger >
214- < SelectContent >
215- < SelectItem value = "beginner" > { t ( 'generateForm.audienceBeginner' ) } </ SelectItem >
216- < SelectItem value = "intermediate" > { t ( 'generateForm.audienceIntermediate' ) } </ SelectItem >
217- < SelectItem value = "advanced" > { t ( 'generateForm.audienceAdvanced' ) } </ SelectItem >
218- </ SelectContent >
219- </ Select >
220- </ div >
207+ < div
208+ id = "generate-more-options"
209+ className = { `overflow-hidden transition-all duration-300 ease-in-out ${
210+ advancedOpen ? 'max-h-80 opacity-100' : 'max-h-0 opacity-0'
211+ } `}
212+ >
213+ < div className = "grid gap-4 pt-1 sm:grid-cols-3" >
214+ { /* Length */ }
215+ < div className = "space-y-2" >
216+ < Label className = "text-sm font-medium" > { t ( 'generateForm.length' ) } </ Label >
217+ < Select
218+ value = { currentValues . length }
219+ onValueChange = { ( value ) => setValue ( 'length' , value as GenerateInput [ 'length' ] ) }
220+ >
221+ < SelectTrigger >
222+ < SelectValue />
223+ </ SelectTrigger >
224+ < SelectContent >
225+ < SelectItem value = "brief" > { t ( 'generateForm.lengthBrief' ) } </ SelectItem >
226+ < SelectItem value = "standard" > { t ( 'generateForm.lengthStandard' ) } </ SelectItem >
227+ < SelectItem value = "comprehensive" > { t ( 'generateForm.lengthComprehensive' ) } </ SelectItem >
228+ </ SelectContent >
229+ </ Select >
230+ </ div >
221231
222- { /* Tone */ }
223- < div className = "space-y-2" >
224- < Label className = "text-sm font-medium" > { t ( 'generateForm.tone' ) } </ Label >
225- < Select
226- value = { currentValues . tone }
227- onValueChange = { ( value ) => setValue ( 'tone' , value as GenerateInput [ 'tone' ] ) }
228- >
229- < SelectTrigger >
230- < SelectValue />
231- </ SelectTrigger >
232- < SelectContent >
233- < SelectItem value = "formal" > { t ( 'generateForm.toneFormal' ) } </ SelectItem >
234- < SelectItem value = "conversational" > { t ( 'generateForm.toneConversational' ) } </ SelectItem >
235- < SelectItem value = "aggressive" > { t ( 'generateForm.toneAggressive' ) } </ SelectItem >
236- </ SelectContent >
237- </ Select >
232+ { /* Audience */ }
233+ < div className = "space-y-2" >
234+ < Label className = "text-sm font-medium" > { t ( 'generateForm.audience' ) } </ Label >
235+ < Select
236+ value = { currentValues . audience }
237+ onValueChange = { ( value ) => setValue ( 'audience' , value as GenerateInput [ 'audience' ] ) }
238+ >
239+ < SelectTrigger >
240+ < SelectValue />
241+ </ SelectTrigger >
242+ < SelectContent >
243+ < SelectItem value = "beginner" > { t ( 'generateForm.audienceBeginner' ) } </ SelectItem >
244+ < SelectItem value = "intermediate" > { t ( 'generateForm.audienceIntermediate' ) } </ SelectItem >
245+ < SelectItem value = "advanced" > { t ( 'generateForm.audienceAdvanced' ) } </ SelectItem >
246+ </ SelectContent >
247+ </ Select >
248+ </ div >
249+
250+ { /* Tone */ }
251+ < div className = "space-y-2" >
252+ < Label className = "text-sm font-medium" > { t ( 'generateForm.tone' ) } </ Label >
253+ < Select
254+ value = { currentValues . tone }
255+ onValueChange = { ( value ) => setValue ( 'tone' , value as GenerateInput [ 'tone' ] ) }
256+ >
257+ < SelectTrigger >
258+ < SelectValue />
259+ </ SelectTrigger >
260+ < SelectContent >
261+ < SelectItem value = "formal" > { t ( 'generateForm.toneFormal' ) } </ SelectItem >
262+ < SelectItem value = "conversational" > { t ( 'generateForm.toneConversational' ) } </ SelectItem >
263+ < SelectItem value = "aggressive" > { t ( 'generateForm.toneAggressive' ) } </ SelectItem >
264+ </ SelectContent >
265+ </ Select >
266+ </ div >
238267 </ div >
239268 </ div >
240269
0 commit comments