1
- import { Spring } from "@follow/components/constants/spring.js"
2
1
import { useMobile } from "@follow/components/hooks/useMobile.js"
3
2
import { Button } from "@follow/components/ui/button/index.js"
4
3
import { Card , CardContent , CardFooter , CardHeader } from "@follow/components/ui/card/index.jsx"
@@ -12,14 +11,14 @@ import {
12
11
FormMessage ,
13
12
} from "@follow/components/ui/form/index.jsx"
14
13
import { Input } from "@follow/components/ui/input/index.js"
14
+ import { SegmentGroup , SegmentItem } from "@follow/components/ui/segment/index.js"
15
15
import { ResponsiveSelect } from "@follow/components/ui/select/responsive.js"
16
16
import { getBackgroundGradient } from "@follow/utils/color"
17
17
import { zodResolver } from "@hookform/resolvers/zod"
18
18
import { repository } from "@pkg"
19
19
import { useMutation } from "@tanstack/react-query"
20
20
import { produce } from "immer"
21
21
import { atom , useAtomValue , useStore } from "jotai"
22
- import { m } from "motion/react"
23
22
import type { ChangeEvent , FC } from "react"
24
23
import { memo , useCallback , useState } from "react"
25
24
import { useForm } from "react-hook-form"
@@ -232,99 +231,89 @@ export function DiscoverForm({ type = "search" }: { type?: string }) {
232
231
< Form { ...form } >
233
232
< form
234
233
onSubmit = { form . handleSubmit ( onSubmit ) }
235
- className = "w-full max-w-[540px] space-y-8 "
234
+ className = "w-full max-w-[540px]"
236
235
data-testid = "discover-form"
237
236
>
238
- < FormField
239
- control = { form . control }
240
- name = "keyword"
241
- render = { ( { field } ) => (
242
- < FormItem >
243
- < FormLabel className = "flex items-center gap-4" >
244
- { t ( info [ type ] ?. label ! ) }
245
- { info [ type ] ?. labelSuffix }
246
- </ FormLabel >
247
- < FormControl >
248
- < Input autoFocus { ...field } onChange = { handleKeywordChange } />
249
- </ FormControl >
250
- < FormMessage />
251
- </ FormItem >
252
- ) }
253
- />
254
- { type === "search" && (
237
+ < div className = "border-border bg-material-ultra-thin rounded-lg border p-5 shadow-sm" >
255
238
< FormField
256
239
control = { form . control }
257
- name = "target "
240
+ name = "keyword "
258
241
render = { ( { field } ) => (
259
- < FormItem className = "!mt-4 flex items-center justify-between" >
260
- < FormLabel > { t ( "discover.target.label" ) } </ FormLabel >
242
+ < FormItem className = "mb-4" >
243
+ < FormLabel className = "text-text text-headline mb-2 flex items-center gap-2 pl-2 font-bold" >
244
+ { t ( info [ type ] ?. label ! ) }
245
+ { info [ type ] ?. labelSuffix }
246
+ </ FormLabel >
261
247
< FormControl >
262
- < div className = "flex gap-4 text-sm" >
263
- { isMobile ? (
264
- < ResponsiveSelect
265
- size = "sm"
266
- value = { field . value }
267
- onValueChange = { handleTargetChange }
268
- items = { [
269
- { label : t ( "discover.target.feeds" ) , value : "feeds" } ,
270
- { label : t ( "discover.target.lists" ) , value : "lists" } ,
271
- ] }
272
- />
273
- ) : (
274
- < div className = "relative flex h-7 items-stretch overflow-hidden rounded-lg bg-zinc-100/80 p-0.5 shadow-inner dark:bg-zinc-800/80" >
275
- < m . div
276
- className = "absolute left-0.5 top-0.5 z-0 h-6 rounded-md bg-white shadow-sm dark:bg-zinc-700"
277
- initial = { false }
278
- animate = { {
279
- x : field . value === "lists" ? "calc(100% + 2px)" : 0 ,
280
- width : "calc(50% - 4px)" ,
281
- } }
282
- transition = { Spring . presets . smooth }
283
- />
284
- < button
285
- type = "button"
286
- onClick = { ( ) => handleTargetChange ( "feeds" ) }
287
- className = { `relative z-10 min-w-[80px] rounded-md px-4 text-sm font-medium transition-colors duration-200 ${
288
- field . value === "feeds"
289
- ? "text-zinc-900 dark:text-white"
290
- : "text-zinc-500 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white"
291
- } `}
292
- >
293
- { t ( "discover.target.feeds" ) }
294
- </ button >
295
- < button
296
- type = "button"
297
- onClick = { ( ) => handleTargetChange ( "lists" ) }
298
- className = { `relative z-10 min-w-[80px] rounded-md px-4 text-sm font-medium transition-colors duration-200 ${
299
- field . value === "lists"
300
- ? "text-zinc-900 dark:text-white"
301
- : "text-zinc-500 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-white"
302
- } `}
303
- >
304
- { t ( "discover.target.lists" ) }
305
- </ button >
306
- </ div >
307
- ) }
308
- </ div >
248
+ < Input
249
+ autoFocus
250
+ { ...field }
251
+ onChange = { handleKeywordChange }
252
+ placeholder = { type === "search" ? "Enter URL or keyword..." : undefined }
253
+ />
309
254
</ FormControl >
310
255
< FormMessage />
311
256
</ FormItem >
312
257
) }
313
258
/>
314
- ) }
315
- < div className = "center flex" data-testid = "discover-form-actions" >
316
- < Button disabled = { ! form . formState . isValid } type = "submit" isLoading = { mutation . isPending } >
317
- { info [ type ] ! . showModal ? t ( "discover.preview" ) : t ( "words.search" ) }
318
- </ Button >
259
+ { type === "search" && (
260
+ < FormField
261
+ control = { form . control }
262
+ name = "target"
263
+ render = { ( { field } ) => (
264
+ < FormItem className = "mb-4 pl-2" >
265
+ < div className = "mb-2 flex items-center justify-between" >
266
+ < FormLabel className = "text-text-secondary text-headline font-medium" >
267
+ { t ( "discover.target.label" ) }
268
+ </ FormLabel >
269
+ < FormControl >
270
+ < div className = "flex" >
271
+ { isMobile ? (
272
+ < ResponsiveSelect
273
+ size = "sm"
274
+ value = { field . value }
275
+ onValueChange = { handleTargetChange }
276
+ items = { [
277
+ { label : t ( "discover.target.feeds" ) , value : "feeds" } ,
278
+ { label : t ( "discover.target.lists" ) , value : "lists" } ,
279
+ ] }
280
+ />
281
+ ) : (
282
+ < SegmentGroup
283
+ className = "-mt-2 h-8"
284
+ value = { field . value }
285
+ onValueChanged = { handleTargetChange }
286
+ >
287
+ < SegmentItem value = "feeds" label = { t ( "discover.target.feeds" ) } />
288
+ < SegmentItem value = "lists" label = { t ( "discover.target.lists" ) } />
289
+ </ SegmentGroup >
290
+ ) }
291
+ </ div >
292
+ </ FormControl >
293
+ </ div >
294
+ < FormMessage />
295
+ </ FormItem >
296
+ ) }
297
+ />
298
+ ) }
299
+ < div className = "center flex" data-testid = "discover-form-actions" >
300
+ < Button
301
+ disabled = { ! form . formState . isValid }
302
+ type = "submit"
303
+ isLoading = { mutation . isPending }
304
+ >
305
+ { info [ type ] ! . showModal ? t ( "discover.preview" ) : t ( "words.search" ) }
306
+ </ Button >
307
+ </ div >
319
308
</ div >
320
309
</ form >
321
310
</ Form >
322
311
{ mutation . isSuccess && (
323
312
< div className = "mt-8 w-full max-w-lg" >
324
- < div className = "mb-4 pl-7 text-sm text-zinc-500" >
313
+ < div className = "mb-4 text-sm text-zinc-500" >
325
314
{ t ( "discover.search.results" , { count : mutation . data ?. length || 0 } ) }
326
315
</ div >
327
- < div className = "space-y-6 text-sm" >
316
+ < div className = "space-y-4 text-sm" >
328
317
{ discoverSearchData ?. map ( ( item ) => (
329
318
< SearchCard
330
319
key = { item . feed ?. id || item . list ?. id }
0 commit comments