Skip to content

Commit bac823a

Browse files
committed
refactor(desktop): enhance UI components and form layouts
- Updated DropZone component to include a cursor button style for better user interaction. - Refactored DiscoverForm to improve layout and styling, including the addition of a SegmentGroup for target selection. - Enhanced form styling across various components for a more cohesive appearance, including rounded borders and shadow effects. - Improved accessibility and visual hierarchy in user forms and import forms. Signed-off-by: Innei <[email protected]>
1 parent 9a46e0d commit bac823a

File tree

7 files changed

+79
-85
lines changed

7 files changed

+79
-85
lines changed

apps/desktop/src/renderer/src/components/ui/drop-zone.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export const DropZone = ({
5959

6060
return (
6161
<label
62-
className={`center flex h-[100px] w-full rounded-md border border-dashed ${
62+
className={`center cursor-button flex h-[100px] w-full rounded-md border border-dashed ${
6363
isDragging ? "border-blue-500 bg-blue-100" : ""
6464
}`}
6565
htmlFor="upload-file"

apps/desktop/src/renderer/src/modules/discover/form.tsx

Lines changed: 66 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { Spring } from "@follow/components/constants/spring.js"
21
import { useMobile } from "@follow/components/hooks/useMobile.js"
32
import { Button } from "@follow/components/ui/button/index.js"
43
import { Card, CardContent, CardFooter, CardHeader } from "@follow/components/ui/card/index.jsx"
@@ -12,14 +11,14 @@ import {
1211
FormMessage,
1312
} from "@follow/components/ui/form/index.jsx"
1413
import { Input } from "@follow/components/ui/input/index.js"
14+
import { SegmentGroup, SegmentItem } from "@follow/components/ui/segment/index.js"
1515
import { ResponsiveSelect } from "@follow/components/ui/select/responsive.js"
1616
import { getBackgroundGradient } from "@follow/utils/color"
1717
import { zodResolver } from "@hookform/resolvers/zod"
1818
import { repository } from "@pkg"
1919
import { useMutation } from "@tanstack/react-query"
2020
import { produce } from "immer"
2121
import { atom, useAtomValue, useStore } from "jotai"
22-
import { m } from "motion/react"
2322
import type { ChangeEvent, FC } from "react"
2423
import { memo, useCallback, useState } from "react"
2524
import { useForm } from "react-hook-form"
@@ -232,99 +231,89 @@ export function DiscoverForm({ type = "search" }: { type?: string }) {
232231
<Form {...form}>
233232
<form
234233
onSubmit={form.handleSubmit(onSubmit)}
235-
className="w-full max-w-[540px] space-y-8"
234+
className="w-full max-w-[540px]"
236235
data-testid="discover-form"
237236
>
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">
255238
<FormField
256239
control={form.control}
257-
name="target"
240+
name="keyword"
258241
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>
261247
<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+
/>
309254
</FormControl>
310255
<FormMessage />
311256
</FormItem>
312257
)}
313258
/>
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>
319308
</div>
320309
</form>
321310
</Form>
322311
{mutation.isSuccess && (
323312
<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">
325314
{t("discover.search.results", { count: mutation.data?.length || 0 })}
326315
</div>
327-
<div className="space-y-6 text-sm">
316+
<div className="space-y-4 text-sm">
328317
{discoverSearchData?.map((item) => (
329318
<SearchCard
330319
key={item.feed?.id || item.list?.id}

apps/desktop/src/renderer/src/modules/discover/import.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,10 @@ export function DiscoverImport({ isInit = false }: { isInit?: boolean }) {
106106
return (
107107
<>
108108
<Form {...form}>
109-
<form onSubmit={form.handleSubmit(onSubmit)} className="w-full max-w-[540px] space-y-8">
109+
<form
110+
onSubmit={form.handleSubmit(onSubmit)}
111+
className="bg-material-ultra-thin w-full max-w-[540px] space-y-8 rounded-lg border p-5 shadow-sm"
112+
>
110113
<FormField
111114
control={form.control}
112115
name="file"
@@ -124,8 +127,8 @@ export function DiscoverImport({ isInit = false }: { isInit?: boolean }) {
124127
</Fragment>
125128
) : (
126129
<Fragment>
127-
<i className="i-mgc-file-upload-cute-re size-5" />
128-
<span className="ml-2 text-sm opacity-80">
130+
<i className="i-mgc-file-upload-cute-re text-text-tertiary size-10" />
131+
<span className="text-title2 text-text-tertiary ml-2">
129132
{t("discover.import.click_to_upload")}
130133
</span>
131134
</Fragment>

apps/desktop/src/renderer/src/modules/discover/inbox-list-form.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export function DiscoverInboxList() {
4646
const preCheck = useCanCreateMoreInboxAndNotify()
4747

4848
return (
49-
<div className="mx-auto w-full max-w-[540px]">
49+
<div className="bg-material-ultra-thin mx-auto w-full max-w-[540px] rounded-lg border p-5 shadow-sm">
5050
<div className="mb-4 flex flex-wrap items-center gap-2 text-sm text-zinc-500">
5151
<span>{t("discover.inbox.description")}</span>
5252
<a

apps/desktop/src/renderer/src/modules/discover/transform-form.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export function DiscoverTransform() {
6868
return (
6969
<>
7070
{data?.rsshub!.routes && (
71-
<div className="w-full max-w-[540px]">
71+
<div className="bg-material-ultra-thin w-full max-w-[540px] rounded-lg border p-5 shadow-sm">
7272
<DiscoverFeedForm
7373
routePrefix="rsshub"
7474
route={data?.rsshub.routes["/transform/html/:url/:routeParams"]!}

apps/desktop/src/renderer/src/modules/discover/user-form.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export function DiscoverUser() {
2828
return (
2929
<>
3030
{data?.follow!.routes && (
31-
<div className="w-full max-w-[540px]">
31+
<div className="bg-material-ultra-thin w-full max-w-[540px] rounded-lg border p-5 shadow-sm">
3232
<DiscoverFeedForm
3333
routePrefix="follow"
3434
route={data.follow.routes[Object.keys(data.follow.routes)[0]!]!}

packages/components/src/ui/segment/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Spring } from "@follow/components/constants/spring"
12
import { cn } from "@follow/utils/utils"
23
import { m } from "motion/react"
34
import type { ReactNode } from "react"
@@ -33,7 +34,7 @@ export const SegmentGroup = (props: ComponentType<SegmentGroupProps>) => {
3334
<div
3435
role="tablist"
3536
className={cn(
36-
"bg-material-medium text-text-secondary inline-flex h-9 items-center justify-center rounded-lg p-1 outline-none",
37+
"bg-fill-secondary text-text-secondary inline-flex h-9 items-center justify-center rounded-lg p-1 outline-none",
3738
className,
3839
)}
3940
tabIndex={0}
@@ -73,6 +74,7 @@ export const SegmentItem: Component<{
7374
{isActive && (
7475
<m.span
7576
layout
77+
transition={Spring.presets.smooth}
7678
layoutId={layoutId}
7779
className="bg-background absolute inset-0 z-0 rounded-md shadow"
7880
/>

0 commit comments

Comments
 (0)