From 5fd9b23f03bccd6d3bc427ee0e5c31bfb69e3c42 Mon Sep 17 00:00:00 2001 From: Innei Date: Thu, 1 Aug 2024 13:33:11 +0800 Subject: [PATCH] feat: resizeable setting panel and adjust action tab Signed-off-by: Innei --- package.json | 1 + pnpm-lock.yaml | 14 ++ .../src/components/ui/collapse/Collapse.tsx | 89 ++++++++++ .../src/components/ui/collapse/index.ts | 1 + .../src/modules/settings/action-card.tsx | 160 +++++++++--------- .../src/modules/settings/modal/layout.tsx | 75 ++++---- .../tabs/wallet/transaction-section/index.tsx | 4 +- 7 files changed, 225 insertions(+), 119 deletions(-) create mode 100644 src/renderer/src/components/ui/collapse/Collapse.tsx create mode 100644 src/renderer/src/components/ui/collapse/index.ts diff --git a/package.json b/package.json index 0f35d1778..5ffd8794b 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,7 @@ "path-to-regexp": "7.1.0", "posthog-js": "1.150.0", "posthog-node": "4.0.1", + "re-resizable": "6.9.17", "react-error-boundary": "4.0.13", "react-fast-marquee": "1.6.5", "react-hook-form": "7.52.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b0e9026fb..acfee375f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -220,6 +220,9 @@ importers: posthog-node: specifier: 4.0.1 version: 4.0.1 + re-resizable: + specifier: 6.9.17 + version: 6.9.17(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-error-boundary: specifier: 4.0.13 version: 4.0.13(react@18.3.1) @@ -5525,6 +5528,12 @@ packages: random-path@0.1.2: resolution: {integrity: sha512-4jY0yoEaQ5v9StCl5kZbNIQlg1QheIDBrdkDn53EynpPb9FgO6//p3X/tgMnrC45XN6QZCzU1Xz/+pSSsJBpRw==} + re-resizable@6.9.17: + resolution: {integrity: sha512-OBqd1BwVXpEJJn/yYROG+CbeqIDBWIp6wathlpB0kzZWWZIY1gPTsgK2yJEui5hOvkCdC2mcexF2V3DZVfLq2g==} + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: @@ -12833,6 +12842,11 @@ snapshots: murmur-32: 0.2.0 optional: true + re-resizable@6.9.17(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 diff --git a/src/renderer/src/components/ui/collapse/Collapse.tsx b/src/renderer/src/components/ui/collapse/Collapse.tsx new file mode 100644 index 000000000..71e2901ef --- /dev/null +++ b/src/renderer/src/components/ui/collapse/Collapse.tsx @@ -0,0 +1,89 @@ +import { cn } from "@renderer/lib/utils" +import type { Variants } from "framer-motion" +import { AnimatePresence, m } from "framer-motion" +import * as React from "react" + +import { microReboundPreset } from "../constants/spring" + +interface CollapseProps { + title: React.ReactNode +} +export const Collapse: Component = (props) => { + const [isOpened, setIsOpened] = React.useState(false) + return ( + + ) +} + +export const CollapseControlled: Component< + { + isOpened: boolean + onOpenChange: (v: boolean) => void + } & CollapseProps +> = (props) => ( +
+
props.onOpenChange(!props.isOpened)} + > + {props.title} +
+ +
+
+ + {props.children} + +
+) +export const CollapseContent: Component<{ + isOpened: boolean + withBackground?: boolean +}> = ({ isOpened, className, children }) => { + const variants = React.useMemo(() => { + const v = { + open: { + opacity: 1, + height: "auto", + transition: microReboundPreset, + }, + collapsed: { + opacity: 0, + height: 0, + overflow: "hidden", + }, + } satisfies Variants + + return v + }, []) + return ( + <> + + {isOpened && ( + + {children} + + )} + + + ) +} diff --git a/src/renderer/src/components/ui/collapse/index.ts b/src/renderer/src/components/ui/collapse/index.ts new file mode 100644 index 000000000..7e16bb66d --- /dev/null +++ b/src/renderer/src/components/ui/collapse/index.ts @@ -0,0 +1 @@ +export * from "./Collapse" diff --git a/src/renderer/src/modules/settings/action-card.tsx b/src/renderer/src/modules/settings/action-card.tsx index 0621bff5f..c4c59c206 100644 --- a/src/renderer/src/modules/settings/action-card.tsx +++ b/src/renderer/src/modules/settings/action-card.tsx @@ -1,13 +1,8 @@ import { Button } from "@renderer/components/ui/button" import { Card, CardHeader } from "@renderer/components/ui/card" -import { - Collapsible, - CollapsibleContent, - CollapsibleTrigger, -} from "@renderer/components/ui/collapsible" +import { Collapse, CollapseControlled } from "@renderer/components/ui/collapse" import { Divider } from "@renderer/components/ui/divider" import { Input } from "@renderer/components/ui/input" -import { Label } from "@renderer/components/ui/label" import { Radio } from "@renderer/components/ui/radio-group" import { RadioGroup } from "@renderer/components/ui/radio-group/RadioGroup" import { @@ -27,6 +22,7 @@ import { TableRow, } from "@renderer/components/ui/table" import { ViewSelectContent } from "@renderer/components/view-select-content" +import { stopPropagation } from "@renderer/lib/dom" import { cn } from "@renderer/lib/utils" import type { SupportedLanguages } from "@renderer/models" @@ -251,25 +247,33 @@ const OperationTableCell = ({ const SettingCollapsible = ({ title, - children, - open, onOpenChange, + open, + children, }: { title: string children: React.ReactNode open?: boolean onOpenChange?: (open: boolean) => void -}) => ( - -
- - - - -
- {children} -
-) +}) => { + if (typeof open === "boolean" && typeof onOpenChange === "function") { + return ( + +
{children}
+
+ ) + } + + return ( + +
{children}
+
+ ) +} const CommonSelectTrigger = ({ className }: { className?: string }) => ( @@ -287,33 +291,36 @@ export function ActionCard({ return ( - -
- -

Name

- { - data.name = e.target.value - onChange(data) - }} - /> - + + +

Name

+ { + data.name = e.target.value + onChange(data) + }} + /> +
{data.name}
- -
-
- + + )} + > +

When feeds match…

@@ -421,22 +428,26 @@ export function ActionCard({ )}
-

- Then do… -

+

Then do…

- { - if (open) { - data.result.translation = TransitionOptions[0].value - } else { - delete data.result.translation - } - onChange(data) - }} - > +
+ + Generate summary using AI + + { + data.result.summary = checked + onChange(data) + }} + /> +
+ + +
+ + Translate into + - - - { - if (open) { - data.result.summary = true - } else { - delete data.result.summary - } - onChange(data) - }} - > - { - data.result.summary = checked - onChange(data) - }} - /> - +
+ +
- - +
+ ) diff --git a/src/renderer/src/modules/settings/modal/layout.tsx b/src/renderer/src/modules/settings/modal/layout.tsx index c0c0f00e6..867288858 100644 --- a/src/renderer/src/modules/settings/modal/layout.tsx +++ b/src/renderer/src/modules/settings/modal/layout.tsx @@ -4,6 +4,7 @@ import { Logo } from "@renderer/components/icons/logo" import { preventDefault } from "@renderer/lib/dom" import { cn } from "@renderer/lib/utils" import { useDragControls } from "framer-motion" +import { Resizable } from "re-resizable" import type { PointerEventHandler, PropsWithChildren } from "react" import { useCallback, useEffect } from "react" @@ -51,7 +52,7 @@ export function SettingModalLayout( scale: 0.96, }} className={cn( - "relative flex h-[500px] max-h-[80vh] w-[calc(170px+55ch)] max-w-full flex-col overflow-hidden rounded-xl border border-border", + "relative flex overflow-hidden rounded-xl border border-border", !overlay && "shadow-perfect", )} onContextMenu={preventDefault} @@ -64,40 +65,48 @@ export function SettingModalLayout( cursor: "grabbing", }} > - {draggable && ( -
- )} -
-
-
- - {APP_NAME} + + {draggable && ( +
+ )} +
+
+
+ + {APP_NAME} +
+ {settings.map((t) => ( + + ))} +
+
+ {children}
- {settings.map((t) => ( - - ))}
-
- {children} -
-
+
) } diff --git a/src/renderer/src/modules/settings/tabs/wallet/transaction-section/index.tsx b/src/renderer/src/modules/settings/tabs/wallet/transaction-section/index.tsx index 18929f24d..0fe2141d2 100644 --- a/src/renderer/src/modules/settings/tabs/wallet/transaction-section/index.tsx +++ b/src/renderer/src/modules/settings/tabs/wallet/transaction-section/index.tsx @@ -46,8 +46,8 @@ export const TransactionsSection = () => {
- - + + Type