diff --git a/web/bun.lockb b/web/bun.lockb index 0f676f38..c5770638 100755 Binary files a/web/bun.lockb and b/web/bun.lockb differ diff --git a/web/package.json b/web/package.json index fb299fb1..8bacb9a9 100644 --- a/web/package.json +++ b/web/package.json @@ -15,50 +15,74 @@ }, "devDependencies": { "@biomejs/biome": "1.9.4", - "@tanstack/router-plugin": "^1.114.30", - "@types/node": "^22.13.14", - "@types/react": "^19.0.12", + "@tanstack/router-plugin": "^1.114.32", + "@types/node": "^22.13.17", + "@types/react": "^19.1.0", "@types/react-copy-to-clipboard": "^5.0.7", - "@types/react-dom": "^19.0.4", + "@types/react-dom": "^19.1.1", "@types/react-syntax-highlighter": "^15.5.13", "@vitejs/plugin-react": "^4.3.4", "rimraf": "^6.0.1", - "tailwindcss": "^4.0.17", + "tailwindcss": "^4.1.1", "typescript": "^5.8.2", - "vite": "^6.2.3", + "vite": "^6.2.4", "vite-bundle-visualizer": "^1.2.1" }, "dependencies": { - "@hookform/resolvers": "^4.1.3", + "@hookform/resolvers": "^5.0.1", + "@radix-ui/react-accordion": "^1.2.3", "@radix-ui/react-alert-dialog": "^1.1.6", + "@radix-ui/react-aspect-ratio": "^1.1.2", + "@radix-ui/react-avatar": "^1.1.3", "@radix-ui/react-checkbox": "^1.1.4", + "@radix-ui/react-collapsible": "^1.1.3", + "@radix-ui/react-context-menu": "^2.2.6", + "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-dropdown-menu": "^2.1.6", + "@radix-ui/react-hover-card": "^1.1.6", "@radix-ui/react-label": "^2.1.2", + "@radix-ui/react-menubar": "^1.1.6", + "@radix-ui/react-navigation-menu": "^1.2.5", + "@radix-ui/react-popover": "^1.1.6", + "@radix-ui/react-progress": "^1.1.2", "@radix-ui/react-radio-group": "^1.2.3", + "@radix-ui/react-scroll-area": "^1.2.3", "@radix-ui/react-select": "^2.1.6", "@radix-ui/react-separator": "^1.1.2", + "@radix-ui/react-slider": "^1.2.3", "@radix-ui/react-slot": "^1.1.2", "@radix-ui/react-switch": "^1.1.3", "@radix-ui/react-tabs": "^1.1.3", + "@radix-ui/react-toggle": "^1.1.2", + "@radix-ui/react-toggle-group": "^1.1.2", "@radix-ui/react-tooltip": "^1.1.8", - "@tailwindcss/vite": "^4.0.17", - "@tanstack/react-query": "^5.70.0", - "@tanstack/react-router": "^1.114.29", - "@tanstack/router-devtools": "^1.114.29", + "@tailwindcss/vite": "^4.1.1", + "@tanstack/react-query": "^5.71.3", + "@tanstack/react-router": "^1.114.32", + "@tanstack/router-devtools": "^1.114.32", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "cmdk": "^1.1.1", + "date-fns": "^4.1.0", + "embla-carousel-react": "^8.5.2", "i18next": "^24.2.3", - "lucide-react": "^0.485.0", + "input-otp": "^1.4.2", + "lucide-react": "^0.487.0", + "next-themes": "^0.4.6", "react": "^19.1.0", "react-copy-to-clipboard": "^5.1.0", + "react-day-picker": "9.6.4", "react-dom": "^19.1.0", "react-hook-form": "^7.55.0", "react-i18next": "^15.4.1", + "react-resizable-panels": "^2.1.7", "react-syntax-highlighter": "^15.6.1", - "sonner": "^2.0.2", - "tailwind-merge": "^3.0.2", + "recharts": "^2.15.1", + "sonner": "^2.0.3", + "tailwind-merge": "^3.1.0", "tailwind-scrollbar": "^4.0.2", "tailwindcss-animate": "^1.0.7", + "vaul": "^1.1.2", "zod": "^3.24.2" }, "trustedDependencies": ["@biomejs/biome"] diff --git a/web/src/components/code-viewer.tsx b/web/src/components/code-viewer.tsx index 572329c9..f193bc37 100644 --- a/web/src/components/code-viewer.tsx +++ b/web/src/components/code-viewer.tsx @@ -1,4 +1,5 @@ import { Button, type ButtonProps } from "@/components/ui/button"; +import { cn } from "@/lib/utils"; import { Check, Copy } from "lucide-react"; import { type HTMLProps, type ReactNode, useCallback, useEffect, useState } from "react"; import { CopyToClipboard } from "react-copy-to-clipboard"; @@ -50,27 +51,24 @@ export function CopyButton({ value }: Readonly) { export function CodeViewer({ code, header, + button, language, height, showLineNumbers = true, wrapLongLines = true, -}: CodeViewerProps) { +}: Readonly) { const lineProps: lineTagPropsFunction | HTMLProps | undefined = wrapLongLines ? { style: { overflowWrap: "break-word", whiteSpace: "pre-wrap" } } : undefined; return (
- {header && ( -
- {header} +
+ {header} +
+ {button}
- )} - {!header && ( -
- -
- )} +
( - + {t("mainConfig.server")} @@ -38,7 +38,7 @@ export function AntSwordTabContent({ control={form.control} name="headerName" render={({ field }) => ( - + {t("shellToolConfig.headerName")} @@ -48,7 +48,7 @@ export function AntSwordTabContent({ control={form.control} name="headerValue" render={({ field }) => ( - + {t("shellToolConfig.headerValue")} diff --git a/web/src/components/tools/behinder-tab.tsx b/web/src/components/tools/behinder-tab.tsx index 964c0a6d..cbc0083d 100644 --- a/web/src/components/tools/behinder-tab.tsx +++ b/web/src/components/tools/behinder-tab.tsx @@ -27,7 +27,7 @@ export function BehinderTabContent({ control={form.control} name="behinderPass" render={({ field }) => ( - + {t("shellToolConfig.behinderPass")} @@ -38,7 +38,7 @@ export function BehinderTabContent({ control={form.control} name="headerName" render={({ field }) => ( - + {t("shellToolConfig.headerName")} @@ -48,7 +48,7 @@ export function BehinderTabContent({ control={form.control} name="headerValue" render={({ field }) => ( - + {t("shellToolConfig.headerValue")} diff --git a/web/src/components/tools/classname-field.tsx b/web/src/components/tools/classname-field.tsx index 5f5a2f7d..3ba5cac9 100644 --- a/web/src/components/tools/classname-field.tsx +++ b/web/src/components/tools/classname-field.tsx @@ -12,7 +12,7 @@ export function OptionalClassFormField({ form }: Readonly<{ form: UseFormReturn< control={form.control} name="shellClassName" render={({ field }) => ( - + {t("mainConfig.shellClassName")} {t("optional")} @@ -24,7 +24,7 @@ export function OptionalClassFormField({ form }: Readonly<{ form: UseFormReturn< control={form.control} name="injectorClassName" render={({ field }) => ( - + {t("mainConfig.injectorClassName")} {t("optional")} diff --git a/web/src/components/tools/command-tab.tsx b/web/src/components/tools/command-tab.tsx index 7ba8f2ac..6fafcb6c 100644 --- a/web/src/components/tools/command-tab.tsx +++ b/web/src/components/tools/command-tab.tsx @@ -27,7 +27,7 @@ export function CommandTabContent({ control={form.control} name="commandParamName" render={({ field }) => ( - + {t("shellToolConfig.paramName")} diff --git a/web/src/components/tools/custom-tab.tsx b/web/src/components/tools/custom-tab.tsx index 9c6c076f..df7b4efa 100644 --- a/web/src/components/tools/custom-tab.tsx +++ b/web/src/components/tools/custom-tab.tsx @@ -32,7 +32,7 @@ export default function CustomTabContent({ control={form.control} name="shellClassBase64" render={({ field }) => ( - + {t("shellToolConfig.base64String")} File
- + {isFile ? ( { diff --git a/web/src/components/tools/godzilla-tab.tsx b/web/src/components/tools/godzilla-tab.tsx index 30aa6f5d..f2f30183 100644 --- a/web/src/components/tools/godzilla-tab.tsx +++ b/web/src/components/tools/godzilla-tab.tsx @@ -28,7 +28,7 @@ export function GodzillaTabContent({ control={form.control} name="godzillaPass" render={({ field }) => ( - + {t("shellToolConfig.pass")} @@ -38,7 +38,7 @@ export function GodzillaTabContent({ control={form.control} name="godzillaKey" render={({ field }) => ( - + {t("shellToolConfig.key")} @@ -48,7 +48,7 @@ export function GodzillaTabContent({ control={form.control} name="headerName" render={({ field }) => ( - + {t("shellToolConfig.headerName")} @@ -58,7 +58,7 @@ export function GodzillaTabContent({ control={form.control} name="headerValue" render={({ field }) => ( - + {t("shellToolConfig.headerValue")} diff --git a/web/src/components/tools/neoreg-tab.tsx b/web/src/components/tools/neoreg-tab.tsx index 61fb1a20..b27307b6 100644 --- a/web/src/components/tools/neoreg-tab.tsx +++ b/web/src/components/tools/neoreg-tab.tsx @@ -28,7 +28,7 @@ export function NeoRegTabContent({ control={form.control} name="headerName" render={({ field }) => ( - + {t("shellToolConfig.headerName")} @@ -38,7 +38,7 @@ export function NeoRegTabContent({ control={form.control} name="headerValue" render={({ field }) => ( - + {t("shellToolConfig.headerValue")} diff --git a/web/src/components/tools/shelltype-field.tsx b/web/src/components/tools/shelltype-field.tsx index 4bd045db..65ce4446 100644 --- a/web/src/components/tools/shelltype-field.tsx +++ b/web/src/components/tools/shelltype-field.tsx @@ -16,7 +16,7 @@ export function ShellTypeFormField({ control={form.control} name="shellType" render={({ field }) => ( - + {t("mainConfig.shellMountType")} @@ -38,7 +38,7 @@ export function Suo5TabContent({ control={form.control} name="headerValue" render={({ field }) => ( - + {t("shellToolConfig.headerValue")} diff --git a/web/src/components/tools/urlpattern-field.tsx b/web/src/components/tools/urlpattern-field.tsx index 5b086e58..23a004a3 100644 --- a/web/src/components/tools/urlpattern-field.tsx +++ b/web/src/components/tools/urlpattern-field.tsx @@ -13,7 +13,7 @@ export function UrlPatternFormField({ form }: Readonly<{ form: UseFormReturn ( - + {t("mainConfig.urlPattern")} diff --git a/web/src/components/ui/alert-dialog.tsx b/web/src/components/ui/alert-dialog.tsx index 6dfbfb49..05f1664b 100644 --- a/web/src/components/ui/alert-dialog.tsx +++ b/web/src/components/ui/alert-dialog.tsx @@ -1,93 +1,102 @@ +"use client"; + import * as React from "react"; import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"; import { cn } from "@/lib/utils"; import { buttonVariants } from "@/components/ui/button"; -const AlertDialog = AlertDialogPrimitive.Root; +function AlertDialog({ ...props }: React.ComponentProps) { + return ; +} -const AlertDialogTrigger = AlertDialogPrimitive.Trigger; +function AlertDialogTrigger({ ...props }: React.ComponentProps) { + return ; +} -const AlertDialogPortal = AlertDialogPrimitive.Portal; +function AlertDialogPortal({ ...props }: React.ComponentProps) { + return ; +} -const AlertDialogOverlay = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName; - -const AlertDialogContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - ) { + return ( + - -)); -AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName; + ); +} -const AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes) => ( -
-); -AlertDialogHeader.displayName = "AlertDialogHeader"; +function AlertDialogContent({ className, ...props }: React.ComponentProps) { + return ( + + + + + ); +} -const AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes) => ( -
-); -AlertDialogFooter.displayName = "AlertDialogFooter"; +function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} -const AlertDialogTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName; +function AlertDialogFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} -const AlertDialogDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName; +function AlertDialogTitle({ className, ...props }: React.ComponentProps) { + return ( + + ); +} -const AlertDialogAction = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName; +function AlertDialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} -const AlertDialogCancel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName; +function AlertDialogAction({ className, ...props }: React.ComponentProps) { + return ; +} + +function AlertDialogCancel({ className, ...props }: React.ComponentProps) { + return ; +} export { AlertDialog, diff --git a/web/src/components/ui/alert.tsx b/web/src/components/ui/alert.tsx index d457ccb7..aadf66c4 100644 --- a/web/src/components/ui/alert.tsx +++ b/web/src/components/ui/alert.tsx @@ -4,12 +4,13 @@ import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "@/lib/utils"; const alertVariants = cva( - "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7", + "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current", { variants: { variant: { - default: "bg-background text-foreground", - destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", + default: "bg-card text-card-foreground", + destructive: + "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90", }, }, defaultVariants: { @@ -18,26 +19,31 @@ const alertVariants = cva( }, ); -const Alert = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes & VariantProps ->(({ className, variant, ...props }, ref) => ( -
-)); -Alert.displayName = "Alert"; +function Alert({ className, variant, ...props }: React.ComponentProps<"div"> & VariantProps) { + return
; +} -const AlertTitle = React.forwardRef>( - ({ className, ...props }, ref) => ( -
- ), -); -AlertTitle.displayName = "AlertTitle"; +function AlertTitle({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} -const AlertDescription = React.forwardRef>( - ({ className, ...props }, ref) => ( -
- ), -); -AlertDescription.displayName = "AlertDescription"; +function AlertDescription({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} export { Alert, AlertTitle, AlertDescription }; diff --git a/web/src/components/ui/button.tsx b/web/src/components/ui/button.tsx index ef8b515f..0e17490e 100644 --- a/web/src/components/ui/button.tsx +++ b/web/src/components/ui/button.tsx @@ -5,22 +5,24 @@ import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "@/lib/utils"; const buttonVariants = cva( - "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", { variants: { variant: { - default: "bg-primary text-primary-foreground shadow hover:bg-primary/90", - destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90", - outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground", - secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80", - ghost: "hover:bg-accent hover:text-accent-foreground", + default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90", + destructive: + "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: + "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", + secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", link: "text-primary underline-offset-4 hover:underline", }, size: { - default: "h-9 px-4 py-2", - sm: "h-8 rounded-md px-3 text-xs", - lg: "h-10 rounded-md px-8", - icon: "h-9 w-9", + default: "h-9 px-4 py-2 has-[>svg]:px-3", + sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", + lg: "h-10 rounded-md px-6 has-[>svg]:px-4", + icon: "size-9", }, }, defaultVariants: { @@ -30,18 +32,19 @@ const buttonVariants = cva( }, ); -export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { - asChild?: boolean; +function Button({ + className, + variant, + size, + asChild = false, + ...props +}: React.ComponentProps<"button"> & + VariantProps & { + asChild?: boolean; + }) { + const Comp = asChild ? Slot : "button"; + + return ; } -const Button = React.forwardRef( - ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : "button"; - return ; - }, -); -Button.displayName = "Button"; - export { Button, buttonVariants }; diff --git a/web/src/components/ui/card.tsx b/web/src/components/ui/card.tsx index 82099ea7..a8fc56ae 100644 --- a/web/src/components/ui/card.tsx +++ b/web/src/components/ui/card.tsx @@ -2,42 +2,55 @@ import * as React from "react"; import { cn } from "@/lib/utils"; -const Card = React.forwardRef>(({ className, ...props }, ref) => ( -
-)); -Card.displayName = "Card"; +function Card({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} -const CardHeader = React.forwardRef>( - ({ className, ...props }, ref) => ( -
- ), -); -CardHeader.displayName = "CardHeader"; +function CardHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} -const CardTitle = React.forwardRef>( - ({ className, ...props }, ref) => ( -
- ), -); -CardTitle.displayName = "CardTitle"; +function CardTitle({ className, ...props }: React.ComponentProps<"div">) { + return
; +} -const CardDescription = React.forwardRef>( - ({ className, ...props }, ref) => ( -
- ), -); -CardDescription.displayName = "CardDescription"; +function CardDescription({ className, ...props }: React.ComponentProps<"div">) { + return
; +} -const CardContent = React.forwardRef>( - ({ className, ...props }, ref) =>
, -); -CardContent.displayName = "CardContent"; +function CardAction({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} -const CardFooter = React.forwardRef>( - ({ className, ...props }, ref) => ( -
- ), -); -CardFooter.displayName = "CardFooter"; +function CardContent({ className, ...props }: React.ComponentProps<"div">) { + return
; +} -export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }; +function CardFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent }; diff --git a/web/src/components/ui/checkbox.tsx b/web/src/components/ui/checkbox.tsx index 5a4cc5a5..af4f2a07 100644 --- a/web/src/components/ui/checkbox.tsx +++ b/web/src/components/ui/checkbox.tsx @@ -1,26 +1,29 @@ +"use client"; + import * as React from "react"; import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; -import { Check } from "lucide-react"; +import { CheckIcon } from "lucide-react"; import { cn } from "@/lib/utils"; -const Checkbox = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - - - -)); -Checkbox.displayName = CheckboxPrimitive.Root.displayName; +function Checkbox({ className, ...props }: React.ComponentProps) { + return ( + + + + + + ); +} export { Checkbox }; diff --git a/web/src/components/ui/dropdown-menu.tsx b/web/src/components/ui/dropdown-menu.tsx index 767ced0c..43ea299f 100644 --- a/web/src/components/ui/dropdown-menu.tsx +++ b/web/src/components/ui/dropdown-menu.tsx @@ -1,180 +1,219 @@ +"use client"; + import * as React from "react"; import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"; -import { Check, ChevronRight, Circle } from "lucide-react"; +import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"; import { cn } from "@/lib/utils"; -const DropdownMenu = DropdownMenuPrimitive.Root; +function DropdownMenu({ ...props }: React.ComponentProps) { + return ; +} -const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger; +function DropdownMenuPortal({ ...props }: React.ComponentProps) { + return ; +} -const DropdownMenuGroup = DropdownMenuPrimitive.Group; +function DropdownMenuTrigger({ ...props }: React.ComponentProps) { + return ; +} -const DropdownMenuPortal = DropdownMenuPrimitive.Portal; +function DropdownMenuContent({ + className, + sideOffset = 4, + ...props +}: React.ComponentProps) { + return ( + + + + ); +} -const DropdownMenuSub = DropdownMenuPrimitive.Sub; +function DropdownMenuGroup({ ...props }: React.ComponentProps) { + return ; +} -const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup; - -const DropdownMenuSubTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean; - } ->(({ className, inset, children, ...props }, ref) => ( - - {children} - - -)); -DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName; - -const DropdownMenuSubContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName; - -const DropdownMenuContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, sideOffset = 4, ...props }, ref) => ( - - & { + inset?: boolean; + variant?: "default" | "destructive"; +}) { + return ( + - -)); -DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName; + ); +} -const DropdownMenuItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean; - } ->(({ className, inset, ...props }, ref) => ( - svg]:size-4 [&>svg]:shrink-0", - inset && "pl-8", - className, - )} - {...props} - /> -)); -DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName; +function DropdownMenuCheckboxItem({ + className, + children, + checked, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ); +} -const DropdownMenuCheckboxItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, checked, ...props }, ref) => ( - - - - - - - {children} - -)); -DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName; +function DropdownMenuRadioGroup({ ...props }: React.ComponentProps) { + return ; +} -const DropdownMenuRadioItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - - - - - - - {children} - -)); -DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName; +function DropdownMenuRadioItem({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + + + + + + {children} + + ); +} -const DropdownMenuLabel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean; - } ->(({ className, inset, ...props }, ref) => ( - -)); -DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName; +function DropdownMenuLabel({ + className, + inset, + ...props +}: React.ComponentProps & { + inset?: boolean; +}) { + return ( + + ); +} -const DropdownMenuSeparator = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName; +function DropdownMenuSeparator({ className, ...props }: React.ComponentProps) { + return ( + + ); +} -const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes) => { - return ; -}; -DropdownMenuShortcut.displayName = "DropdownMenuShortcut"; +function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<"span">) { + return ( + + ); +} + +function DropdownMenuSub({ ...props }: React.ComponentProps) { + return ; +} + +function DropdownMenuSubTrigger({ + className, + inset, + children, + ...props +}: React.ComponentProps & { + inset?: boolean; +}) { + return ( + + {children} + + + ); +} + +function DropdownMenuSubContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} export { DropdownMenu, + DropdownMenuPortal, DropdownMenuTrigger, DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuLabel, DropdownMenuItem, DropdownMenuCheckboxItem, + DropdownMenuRadioGroup, DropdownMenuRadioItem, - DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, - DropdownMenuGroup, - DropdownMenuPortal, DropdownMenuSub, - DropdownMenuSubContent, DropdownMenuSubTrigger, - DropdownMenuRadioGroup, + DropdownMenuSubContent, }; diff --git a/web/src/components/ui/form.tsx b/web/src/components/ui/form.tsx index d2465746..d2f203f4 100644 --- a/web/src/components/ui/form.tsx +++ b/web/src/components/ui/form.tsx @@ -1,7 +1,15 @@ import * as React from "react"; import * as LabelPrimitive from "@radix-ui/react-label"; import { Slot } from "@radix-ui/react-slot"; -import { Controller, ControllerProps, FieldPath, FieldValues, FormProvider, useFormContext } from "react-hook-form"; +import { + Controller, + FormProvider, + useFormContext, + useFormState, + type ControllerProps, + type FieldPath, + type FieldValues, +} from "react-hook-form"; import { cn } from "@/lib/utils"; import { Label } from "@/components/ui/label"; @@ -33,8 +41,8 @@ const FormField = < const useFormField = () => { const fieldContext = React.useContext(FormFieldContext); const itemContext = React.useContext(FormItemContext); - const { getFieldState, formState } = useFormContext(); - + const { getFieldState } = useFormContext(); + const formState = useFormState({ name: fieldContext.name }); const fieldState = getFieldState(fieldContext.name, formState); if (!fieldContext) { @@ -59,78 +67,70 @@ type FormItemContextValue = { const FormItemContext = React.createContext({} as FormItemContextValue); -const FormItem = React.forwardRef>( - ({ className, ...props }, ref) => { - const id = React.useId(); +function FormItem({ className, ...props }: React.ComponentProps<"div">) { + const id = React.useId(); - return ( - -
- - ); - }, -); -FormItem.displayName = "FormItem"; + return ( + +
+ + ); +} -const FormLabel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => { +function FormLabel({ className, ...props }: React.ComponentProps) { const { error, formItemId } = useFormField(); - return