From e9cae01feb6083c717cf4b9417d64c5222bbc8b3 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 13:35:17 +0100 Subject: [PATCH 001/100] =?UTF-8?q?feat(button):=20=E2=9C=A8=20enhance=20b?= =?UTF-8?q?utton=20component=20with=20new=20styles=20and=20props?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated button styles for improved UI consistency. * Introduced `mergeProps` and `useRender` for better prop handling. * Added new size and variant options for flexibility. --- src/components/ui/button.tsx | 71 ++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index 36d18b8..36ec030 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -1,11 +1,12 @@ -import { Slot } from "@radix-ui/react-slot"; +import { mergeProps } from "@base-ui-components/react/merge-props"; +import { useRender } from "@base-ui-components/react/use-render"; import { cva, type VariantProps } from "class-variance-authority"; import type * as React from "react"; 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-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", + "relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 rounded-lg border bg-clip-padding text-sm font-medium whitespace-nowrap transition-shadow outline-none before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-lg)-1px)] focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", { defaultVariants: { size: "default", @@ -13,48 +14,54 @@ const buttonVariants = cva( }, variants: { size: { - default: "h-9 px-4 py-2 has-[>svg]:px-3", - icon: "size-9", - lg: "h-10 px-6 has-[>svg]:px-4", - sm: "h-8 gap-1.5 px-3 has-[>svg]:px-2.5", - xs: "size-2", + default: + "min-h-8 px-[calc(--spacing(3)-1px)] py-[calc(--spacing(1.5)-1px)]", + icon: "size-8", + "icon-lg": "size-9", + "icon-sm": "size-7", + lg: "min-h-9 px-[calc(--spacing(3.5)-1px)] py-[calc(--spacing(2)-1px)]", + sm: "min-h-7 gap-1.5 px-[calc(--spacing(2.5)-1px)] py-[calc(--spacing(1)-1px)]", + xl: "min-h-10 px-[calc(--spacing(4)-1px)] py-[calc(--spacing(2)-1px)] text-base [&_svg:not([class*='size-'])]:size-4.5", + xs: "min-h-6 gap-1 rounded-md px-[calc(--spacing(2)-1px)] py-[calc(--spacing(1)-1px)] text-xs before:rounded-[calc(var(--radius-md)-1px)] [&_svg:not([class*='size-'])]:size-3", }, variant: { default: - "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90", + "border-primary bg-primary text-primary-foreground shadow-xs shadow-primary/24 not-disabled:inset-shadow-[0_1px_--theme(--color-white/16%)] hover:bg-primary/90 [&:is(:active,[data-pressed])]:inset-shadow-[0_1px_--theme(--color-black/8%)] [&:is(:disabled,:active,[data-pressed])]:shadow-none", 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", - ghost: - "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", - link: "text-primary underline-offset-4 hover:underline", + "border-destructive bg-destructive text-white shadow-xs shadow-destructive/24 not-disabled:inset-shadow-[0_1px_--theme(--color-white/16%)] hover:bg-destructive/90 [&:is(:active,[data-pressed])]:inset-shadow-[0_1px_--theme(--color-black/8%)] [&:is(:disabled,:active,[data-pressed])]:shadow-none", + "destructive-outline": + "border-border bg-transparent text-destructive-foreground shadow-xs not-disabled:not-active:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] dark:bg-input/32 dark:not-in-data-[slot=group]:bg-clip-border dark:not-disabled:before:shadow-[0_-1px_--theme(--color-white/4%)] dark:not-disabled:not-active:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/8%)] [&:is(:disabled,:active,[data-pressed])]:shadow-none [&:is(:hover,[data-pressed])]:border-destructive/32 [&:is(:hover,[data-pressed])]:bg-destructive/4", + ghost: "border-transparent hover:bg-accent data-pressed:bg-accent", + link: "border-transparent underline-offset-4 hover:underline", 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", + "border-border bg-background shadow-xs not-disabled:not-active:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] dark:bg-input/32 dark:not-in-data-[slot=group]:bg-clip-border dark:not-disabled:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/4%)] dark:not-disabled:not-active:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/8%)] [&:is(:disabled,:active,[data-pressed])]:shadow-none [&:is(:hover,[data-pressed])]:bg-accent/50 dark:[&:is(:hover,[data-pressed])]:bg-input/64", secondary: - "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80", + "border-secondary bg-secondary text-secondary-foreground hover:bg-secondary/90 data-pressed:bg-secondary/90", }, }, }, ); -function Button({ - className, - variant, - size, - asChild = false, - ...props -}: React.ComponentProps<"button"> & - VariantProps & { - asChild?: boolean; - }) { - const Comp = asChild ? Slot : "button"; +interface ButtonProps extends useRender.ComponentProps<"button"> { + variant?: VariantProps["variant"]; + size?: VariantProps["size"]; +} + +function Button({ className, variant, size, render, ...props }: ButtonProps) { + const typeValue: React.ButtonHTMLAttributes["type"] = + render ? undefined : "button"; + + const defaultProps = { + className: cn(buttonVariants({ className, size, variant })), + "data-slot": "button", + type: typeValue, + }; - return ( - - ); + return useRender({ + defaultTagName: "button", + props: mergeProps<"button">(defaultProps, props), + render, + }); } export { Button, buttonVariants }; From a845e02ccf887b8bd1fa3d0875c11e805f12a34f Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 13:35:29 +0100 Subject: [PATCH 002/100] =?UTF-8?q?feat(badge):=20=E2=9C=A8=20enhance=20`B?= =?UTF-8?q?adge`=20component=20with=20new=20variants=20and=20improved=20st?= =?UTF-8?q?yling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactored badge styles for better responsiveness and clarity. * Added new size and variant options to the `badgeVariants`. * Updated the `Badge` component to use `mergeProps` for prop handling. --- src/components/ui/badge.tsx | 55 ++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx index ac23f37..da75762 100644 --- a/src/components/ui/badge.tsx +++ b/src/components/ui/badge.tsx @@ -1,46 +1,57 @@ -import { Slot } from "@radix-ui/react-slot"; +import { mergeProps } from "@base-ui-components/react/merge-props"; +import { useRender } from "@base-ui-components/react/use-render"; import { cva, type VariantProps } from "class-variance-authority"; -import type * as React from "react"; import { cn } from "@/lib/utils"; const badgeVariants = cva( - "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-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 transition-[color,box-shadow] overflow-hidden", + "relative inline-flex shrink-0 items-center justify-center gap-1 rounded-sm border border-transparent font-medium whitespace-nowrap transition-shadow outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3 [button,a&]:cursor-pointer [button,a&]:pointer-coarse:after:absolute [button,a&]:pointer-coarse:after:size-full [button,a&]:pointer-coarse:after:min-h-11 [button,a&]:pointer-coarse:after:min-w-11", { defaultVariants: { + size: "default", variant: "default", }, variants: { + size: { + default: "px-[calc(--spacing(1)-1px)] text-xs", + lg: "px-[calc(--spacing(1.5)-1px)] text-sm", + sm: "rounded-[calc(var(--radius-sm)-2px)] px-[calc(--spacing(1)-1px)] text-[.625rem]", + }, variant: { default: - "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90", + "bg-primary text-primary-foreground [button,a&]:hover:bg-primary/90", destructive: - "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + "bg-destructive text-white [button,a&]:hover:bg-destructive/90", + error: + "bg-destructive/8 text-destructive-foreground dark:bg-destructive/16", + info: "bg-info/8 text-info-foreground dark:bg-info/16", outline: - "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground", + "border-border bg-transparent dark:bg-input/32 [button,a&]:hover:bg-accent/50 dark:[button,a&]:hover:bg-input/48", secondary: - "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90", + "bg-secondary text-secondary-foreground [button,a&]:hover:bg-secondary/90", + success: "bg-success/8 text-success-foreground dark:bg-success/16", + warning: "bg-warning/8 text-warning-foreground dark:bg-warning/16", }, }, }, ); -function Badge({ - className, - variant, - asChild = false, - ...props -}: React.ComponentProps<"span"> & - VariantProps & { asChild?: boolean }) { - const Comp = asChild ? Slot : "span"; +interface BadgeProps extends useRender.ComponentProps<"span"> { + variant?: VariantProps["variant"]; + size?: VariantProps["size"]; +} + +function Badge({ className, variant, size, render, ...props }: BadgeProps) { + const defaultProps = { + className: cn(badgeVariants({ className, size, variant })), + "data-slot": "badge", + }; - return ( - - ); + return useRender({ + defaultTagName: "span", + props: mergeProps<"span">(defaultProps, props), + render, + }); } export { Badge, badgeVariants }; From 8b2cac0ccb7503e9cb2334a9b81357a626112193 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 13:35:37 +0100 Subject: [PATCH 003/100] =?UTF-8?q?feat(avatar):=20=E2=9C=A8=20refactor=20?= =?UTF-8?q?`Avatar`=20component=20to=20use=20new=20base=20UI=20primitives?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated imports to use `@base-ui-components/react/avatar`. * Enhanced styling for `Avatar`, `AvatarImage`, and `AvatarFallback` components. * Improved class names for better alignment and visual consistency. --- src/components/ui/avatar.tsx | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx index d619d5f..e749d0b 100644 --- a/src/components/ui/avatar.tsx +++ b/src/components/ui/avatar.tsx @@ -1,16 +1,12 @@ -import * as AvatarPrimitive from "@radix-ui/react-avatar"; -import type * as React from "react"; +import { Avatar as AvatarPrimitive } from "@base-ui-components/react/avatar"; import { cn } from "@/lib/utils"; -function Avatar({ - className, - ...props -}: React.ComponentProps) { +function Avatar({ className, ...props }: AvatarPrimitive.Root.Props) { return ( ) { +function AvatarImage({ className, ...props }: AvatarPrimitive.Image.Props) { return ( @@ -35,11 +28,11 @@ function AvatarImage({ function AvatarFallback({ className, ...props -}: React.ComponentProps) { +}: AvatarPrimitive.Fallback.Props) { return ( Date: Mon, 27 Oct 2025 13:35:59 +0100 Subject: [PATCH 004/100] =?UTF-8?q?feat(dialogs):=20=E2=9C=A8=20replace=20?= =?UTF-8?q?`AlertDialogAction`=20and=20`AlertDialogCancel`=20with=20`Butto?= =?UTF-8?q?n`=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated multiple dialog components to use `Button` for actions. * Improved consistency in UI by standardizing button usage across dialogs. --- .../dialogs/connectserver.dialog.tsx | 11 ++- .../dialogs/deleteinstallation.dialog.tsx | 11 ++- .../dialogs/deleteserver.dialog.tsx | 11 ++- .../dialogs/deleteversion.dialog.tsx | 14 ++- src/components/dialogs/deleteworld.dialog.tsx | 11 ++- src/components/dialogs/removemod.dialog.tsx | 11 ++- src/components/ui/alert-dialog.tsx | 95 ++++++++----------- 7 files changed, 73 insertions(+), 91 deletions(-) diff --git a/src/components/dialogs/connectserver.dialog.tsx b/src/components/dialogs/connectserver.dialog.tsx index 2ac33f4..f456499 100644 --- a/src/components/dialogs/connectserver.dialog.tsx +++ b/src/components/dialogs/connectserver.dialog.tsx @@ -1,8 +1,6 @@ import { useState } from "react"; import { AlertDialog, - AlertDialogAction, - AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, @@ -14,6 +12,7 @@ import type { PublicServer } from "@/hooks/use-public-servers"; import { useDialogStore } from "@/stores/dialogs"; import { useInstallations } from "@/stores/installations"; import { PasswordInput } from "../inputs"; +import { Button } from "../ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger } from "../ui/select"; export type ConnectServerDialogProps = { @@ -77,8 +76,10 @@ export function ConnectServerDialog({ )} - Cancel - closeDialog()} variant="outline"> + Cancel + + diff --git a/src/components/dialogs/deleteinstallation.dialog.tsx b/src/components/dialogs/deleteinstallation.dialog.tsx index f1d506c..72449bf 100644 --- a/src/components/dialogs/deleteinstallation.dialog.tsx +++ b/src/components/dialogs/deleteinstallation.dialog.tsx @@ -5,8 +5,6 @@ import { MapIcon, MapPinXIcon } from "lucide-react"; import { toast } from "sonner"; import { AlertDialog, - AlertDialogAction, - AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, @@ -17,6 +15,7 @@ import { useSavesFromInstallation } from "@/hooks/use-saves"; import { useDialogStore } from "@/stores/dialogs"; import { type Installation, useInstallations } from "@/stores/installations"; import { useServerStore } from "@/stores/servers"; +import { Button } from "../ui/button"; export type DeleteInstallationDialogProps = { installation: Installation; @@ -146,13 +145,15 @@ export function DeleteInstallationDialog({ )} - Cancel - closeDialog()} variant="outline"> + Cancel + + diff --git a/src/components/dialogs/deleteserver.dialog.tsx b/src/components/dialogs/deleteserver.dialog.tsx index 4e9891e..fb093a7 100644 --- a/src/components/dialogs/deleteserver.dialog.tsx +++ b/src/components/dialogs/deleteserver.dialog.tsx @@ -1,8 +1,6 @@ import { toast } from "sonner"; import { AlertDialog, - AlertDialogAction, - AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, @@ -12,6 +10,7 @@ import { import { useRemoveServerFromInstallation } from "@/hooks/use-remove-server-from-installation"; import { useDialogStore } from "@/stores/dialogs"; import { type Server, useServerStore } from "@/stores/servers"; +import { Button } from "../ui/button"; export type DeleteServerDialogProps = { server: Server; @@ -50,8 +49,10 @@ export function DeleteServerDialog({ - Cancel - closeDialog()} variant="outline"> + Cancel + + diff --git a/src/components/dialogs/deleteversion.dialog.tsx b/src/components/dialogs/deleteversion.dialog.tsx index 6ddaeba..4cd4bdb 100644 --- a/src/components/dialogs/deleteversion.dialog.tsx +++ b/src/components/dialogs/deleteversion.dialog.tsx @@ -4,8 +4,6 @@ import { motion } from "framer-motion"; import { toast } from "sonner"; import { AlertDialog, - AlertDialogAction, - AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, @@ -14,6 +12,7 @@ import { } from "@/components/ui/alert-dialog"; import { installedVersionsQueryKey } from "@/hooks/use-installed-versions"; import { useDialogStore } from "@/stores/dialogs"; +import { Button } from "../ui/button"; export type DeleteVersionDialogProps = { version: string; @@ -84,13 +83,12 @@ export function DeleteVersionDialog({ - Cancel - removeVersion(version)} - > + + diff --git a/src/components/dialogs/deleteworld.dialog.tsx b/src/components/dialogs/deleteworld.dialog.tsx index 4f89667..0327726 100644 --- a/src/components/dialogs/deleteworld.dialog.tsx +++ b/src/components/dialogs/deleteworld.dialog.tsx @@ -6,8 +6,6 @@ import { useId, useState } from "react"; import { toast } from "sonner"; import { AlertDialog, - AlertDialogAction, - AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, @@ -16,6 +14,7 @@ import { } from "@/components/ui/alert-dialog"; import type { World } from "@/lib/types"; import { useDialogStore } from "@/stores/dialogs"; +import { Button } from "../ui/button"; import { Checkbox } from "../ui/checkbox"; export type DeleteWorldDialogProps = { @@ -152,13 +151,15 @@ export function DeleteWorldDialog({ - Cancel - closeDialog()} variant="outline"> + Cancel + + diff --git a/src/components/dialogs/removemod.dialog.tsx b/src/components/dialogs/removemod.dialog.tsx index cf8da84..8252a87 100644 --- a/src/components/dialogs/removemod.dialog.tsx +++ b/src/components/dialogs/removemod.dialog.tsx @@ -3,8 +3,6 @@ import { invoke } from "@tauri-apps/api/core"; import { toast } from "sonner"; import { AlertDialog, - AlertDialogAction, - AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, @@ -14,6 +12,7 @@ import { import { installedModsQueryKey } from "@/hooks/use-installed-mods"; import { useDialogStore } from "@/stores/dialogs"; import type { Installation } from "@/stores/installations"; +import { Button } from "../ui/button"; export type RemoveModDialogProps = { name: string; @@ -83,8 +82,10 @@ export function RemoveModDialog({ - Cancel - closeDialog()} variant="outline"> + Cancel + + diff --git a/src/components/ui/alert-dialog.tsx b/src/components/ui/alert-dialog.tsx index d86e3c3..10114ef 100644 --- a/src/components/ui/alert-dialog.tsx +++ b/src/components/ui/alert-dialog.tsx @@ -1,61 +1,57 @@ -import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"; -import type * as React from "react"; -import { buttonVariants } from "@/components/ui/button"; +import { AlertDialog as AlertDialogPrimitive } from "@base-ui-components/react/alert-dialog"; + import { cn } from "@/lib/utils"; -function AlertDialog({ - ...props -}: React.ComponentProps) { +function AlertDialog(props: AlertDialogPrimitive.Root.Props) { return ; } -function AlertDialogTrigger({ - ...props -}: React.ComponentProps) { +function AlertDialogTrigger(props: AlertDialogPrimitive.Trigger.Props) { return ( ); } -function AlertDialogPortal({ - ...props -}: React.ComponentProps) { - return ( - - ); +function AlertDialogPortal(props: AlertDialogPrimitive.Portal.Props) { + return ; } -function AlertDialogOverlay({ +function AlertDialogBackdrop({ className, ...props -}: React.ComponentProps) { +}: AlertDialogPrimitive.Backdrop.Props) { return ( - ); } -function AlertDialogContent({ +function AlertDialogPopup({ className, ...props -}: React.ComponentProps) { +}: AlertDialogPrimitive.Popup.Props) { return ( - - + +
+
+ +
+
); } @@ -92,7 +88,7 @@ function AlertDialogFooter({ function AlertDialogTitle({ className, ...props -}: React.ComponentProps) { +}: AlertDialogPrimitive.Title.Props) { return ( ) { +}: AlertDialogPrimitive.Description.Props) { return ( ); } -function AlertDialogAction({ - className, - ...props -}: React.ComponentProps) { - return ( - - ); -} - -function AlertDialogCancel({ - className, - ...props -}: React.ComponentProps) { +function AlertDialogClose(props: AlertDialogPrimitive.Close.Props) { return ( - + ); } export { AlertDialog, AlertDialogPortal, - AlertDialogOverlay, + AlertDialogBackdrop, + AlertDialogBackdrop as AlertDialogOverlay, AlertDialogTrigger, - AlertDialogContent, + AlertDialogPopup, + AlertDialogPopup as AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, - AlertDialogAction, - AlertDialogCancel, + AlertDialogClose, }; From 0df467a577e408e721c05d2758e27565b7ed9904 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 13:36:10 +0100 Subject: [PATCH 005/100] =?UTF-8?q?chore(deps):=20=F0=9F=94=A7=20update=20?= =?UTF-8?q?dependencies=20in=20`package.json`=20and=20`bun.lock`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Bump `@base-ui-components/react` to `^1.0.0-beta.4` * Update `@tanstack/react-devtools` to `^0.3.10` * Upgrade `lucide-react` to `^0.548.0` * Adjust other dependencies for compatibility --- bun.lock | 30 ++++------ package.json | 4 +- src/components/ui/dialog.tsx | 111 ++++++++++++++++------------------- 3 files changed, 64 insertions(+), 81 deletions(-) diff --git a/bun.lock b/bun.lock index b67de43..4dd628a 100644 --- a/bun.lock +++ b/bun.lock @@ -4,14 +4,12 @@ "": { "name": "test-app", "dependencies": { - "@base-ui-components/react": "^1.0.0-beta.3", + "@base-ui-components/react": "^1.0.0-beta.4", "@dnd-kit/core": "^6.3.1", "@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@monaco-editor/react": "^4.7.0", - "@radix-ui/react-alert-dialog": "^1.1.15", - "@radix-ui/react-avatar": "^1.1.10", "@radix-ui/react-checkbox": "^1.3.3", "@radix-ui/react-context-menu": "^2.2.16", "@radix-ui/react-dialog": "^1.1.15", @@ -28,12 +26,12 @@ "@radix-ui/react-toggle-group": "^1.1.11", "@radix-ui/react-tooltip": "^1.2.8", "@tailwindcss/vite": "^4.1.16", - "@tanstack/react-devtools": "^0.7.7", + "@tanstack/react-devtools": "^0.7.8", "@tanstack/react-form": "^1.23.8", "@tanstack/react-query": "^5.90.5", "@tanstack/react-query-devtools": "^5.90.2", - "@tanstack/react-router": "^1.133.25", - "@tanstack/react-router-devtools": "^1.133.25", + "@tanstack/react-router": "^1.133.27", + "@tanstack/react-router-devtools": "^1.133.27", "@tanstack/react-virtual": "^3.13.12", "@tauri-apps/api": "^2.9.0", "@tauri-apps/plugin-dialog": "~2", @@ -50,7 +48,7 @@ "cmdk": "^1.1.1", "date-fns": "^4.1.0", "input-otp": "^1.4.2", - "lucide-react": "^0.546.0", + "lucide-react": "^0.548.0", "motion": "^12.23.24", "react": "^19.1.1", "react-dom": "^19.1.1", @@ -61,14 +59,14 @@ "zustand": "^5.0.8", }, "devDependencies": { - "@biomejs/biome": "^2.2.7", - "@tanstack/devtools-vite": "^0.3.9", - "@tanstack/router-plugin": "^1.133.25", + "@biomejs/biome": "^2.3.0", + "@tanstack/devtools-vite": "^0.3.10", + "@tanstack/router-plugin": "^1.133.27", "@tauri-apps/cli": "^2.9.1", "@types/react": "^19.2.2", "@types/react-dom": "^19.2.2", - "@vitejs/plugin-react": "^5.0.4", - "lefthook": "^2.0.0", + "@vitejs/plugin-react": "^5.1.0", + "lefthook": "^2.0.1", "tw-animate-css": "^1.4.0", "typescript": "~5.9.3", "vite": "^7.1.12", @@ -251,12 +249,8 @@ "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], - "@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw=="], - "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="], - "@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.1.10", "", { "dependencies": { "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog=="], - "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw=="], "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="], @@ -323,8 +317,6 @@ "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="], - "@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.0", "", { "dependencies": { "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA=="], - "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="], "@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ=="], @@ -695,7 +687,7 @@ "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], - "lucide-react": ["lucide-react@0.546.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Z94u6fKT43lKeYHiVyvyR8fT7pwCzDu7RyMPpTvh054+xahSgj4HFQ+NmflvzdXsoAjYGdCguGaFKYuvq0ThCQ=="], + "lucide-react": ["lucide-react@0.548.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-63b16z63jM9yc1MwxajHeuu0FRZFsDtljtDjYm26Kd86UQ5HQzu9ksEtoUUw4RBuewodw/tGFmvipePvRsKeDA=="], "magic-string": ["magic-string@0.30.19", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="], diff --git a/package.json b/package.json index 048311d..5e407b4 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,11 @@ { "dependencies": { - "@base-ui-components/react": "^1.0.0-beta.3", + "@base-ui-components/react": "^1.0.0-beta.4", "@dnd-kit/core": "^6.3.1", "@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@monaco-editor/react": "^4.7.0", - "@radix-ui/react-alert-dialog": "^1.1.15", - "@radix-ui/react-avatar": "^1.1.10", "@radix-ui/react-checkbox": "^1.3.3", "@radix-ui/react-context-menu": "^2.2.16", "@radix-ui/react-dialog": "^1.1.15", diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index c4b3968..08b5f38 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -1,79 +1,73 @@ -import * as DialogPrimitive from "@radix-ui/react-dialog"; +"use client"; + +import { Dialog as DialogPrimitive } from "@base-ui-components/react/dialog"; import { XIcon } from "lucide-react"; -import type * as React from "react"; import { cn } from "@/lib/utils"; -function Dialog({ - ...props -}: React.ComponentProps) { - return ; -} +const Dialog = DialogPrimitive.Root; -function DialogTrigger({ - ...props -}: React.ComponentProps) { +function DialogTrigger(props: DialogPrimitive.Trigger.Props) { return ; } -function DialogPortal({ - ...props -}: React.ComponentProps) { - return ; +function DialogPortal(props: DialogPrimitive.Portal.Props) { + return ; } -function DialogClose({ - ...props -}: React.ComponentProps) { +function DialogClose(props: DialogPrimitive.Close.Props) { return ; } -function DialogOverlay({ +function DialogBackdrop({ className, ...props -}: React.ComponentProps) { +}: DialogPrimitive.Backdrop.Props) { return ( - ); } -function DialogContent({ +function DialogPopup({ className, children, showCloseButton = true, ...props -}: React.ComponentProps & { +}: DialogPrimitive.Popup.Props & { showCloseButton?: boolean; }) { return ( - - - - {children} - {showCloseButton && ( - + +
+
+ - - Close - - )} - + {children} + {showCloseButton && ( + + + Close + + )} + +
+
); } @@ -81,7 +75,7 @@ function DialogContent({ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { return (
@@ -92,7 +86,7 @@ function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { return (
) { ); } -function DialogTitle({ - className, - ...props -}: React.ComponentProps) { +function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) { return ( @@ -117,10 +108,10 @@ function DialogTitle({ function DialogDescription({ className, ...props -}: React.ComponentProps) { +}: DialogPrimitive.Description.Props) { return ( @@ -129,13 +120,15 @@ function DialogDescription({ export { Dialog, + DialogTrigger, + DialogPortal, DialogClose, - DialogContent, - DialogDescription, - DialogFooter, + DialogBackdrop, + DialogBackdrop as DialogOverlay, + DialogPopup, + DialogPopup as DialogContent, DialogHeader, - DialogOverlay, - DialogPortal, + DialogFooter, DialogTitle, - DialogTrigger, + DialogDescription, }; From 0b044e1a80a24b4ee70f372842fe2d67dbbfe6b6 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 13:38:06 +0100 Subject: [PATCH 006/100] =?UTF-8?q?feat(checkbox):=20=E2=9C=A8=20refactor?= =?UTF-8?q?=20`Checkbox`=20component=20to=20use=20new=20base=20UI=20primit?= =?UTF-8?q?ives?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated import to use `Checkbox` from `@base-ui-components/react/checkbox`. * Enhanced styling and structure for improved accessibility and visual consistency. * Replaced `CheckIcon` with SVG rendering for checked and indeterminate states. --- src/components/ui/checkbox.tsx | 54 ++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/components/ui/checkbox.tsx b/src/components/ui/checkbox.tsx index 027ced9..2aed3d8 100644 --- a/src/components/ui/checkbox.tsx +++ b/src/components/ui/checkbox.tsx @@ -1,28 +1,58 @@ -import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; -import { CheckIcon } from "lucide-react"; -import type * as React from "react"; +import { Checkbox as CheckboxPrimitive } from "@base-ui-components/react/checkbox"; import { cn } from "@/lib/utils"; -function Checkbox({ - className, - ...props -}: React.ComponentProps) { +function Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) { return ( - - + render={(props, state) => ( + + {state.indeterminate ? ( + + Indeterminate Checkbox + + + ) : ( + + Checked Checkbox + + + )} + + )} + /> ); } From 074f612eeff79efbe551ade334987023840ae8df Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 13:40:43 +0100 Subject: [PATCH 007/100] =?UTF-8?q?feat(separator):=20=E2=9C=A8=20refactor?= =?UTF-8?q?=20`Separator`=20component=20to=20use=20new=20base=20UI=20primi?= =?UTF-8?q?tives?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated import to use `@base-ui-components/react/separator`. * Removed unused `decorative` prop. * Enhanced class names for better styling and responsiveness. --- bun.lock | 3 --- package.json | 1 - src/components/ui/separator.tsx | 11 ++++------- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/bun.lock b/bun.lock index 4dd628a..8e7e1ac 100644 --- a/bun.lock +++ b/bun.lock @@ -10,7 +10,6 @@ "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@monaco-editor/react": "^4.7.0", - "@radix-ui/react-checkbox": "^1.3.3", "@radix-ui/react-context-menu": "^2.2.16", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", @@ -251,8 +250,6 @@ "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="], - "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw=="], - "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="], "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], diff --git a/package.json b/package.json index 5e407b4..f8fa03b 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,6 @@ "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@monaco-editor/react": "^4.7.0", - "@radix-ui/react-checkbox": "^1.3.3", "@radix-ui/react-context-menu": "^2.2.16", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", diff --git a/src/components/ui/separator.tsx b/src/components/ui/separator.tsx index 9eaf7d4..22f7a46 100644 --- a/src/components/ui/separator.tsx +++ b/src/components/ui/separator.tsx @@ -1,22 +1,19 @@ -import * as SeparatorPrimitive from "@radix-ui/react-separator"; -import type * as React from "react"; +import { Separator as SeparatorPrimitive } from "@base-ui-components/react/separator"; import { cn } from "@/lib/utils"; function Separator({ className, orientation = "horizontal", - decorative = true, ...props -}: React.ComponentProps) { +}: SeparatorPrimitive.Props) { return ( - From 3568c87c97dcf2a39b7036e2562af59551b09644 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 13:41:12 +0100 Subject: [PATCH 008/100] =?UTF-8?q?feat(tooltip):=20=E2=9C=A8=20refactor?= =?UTF-8?q?=20`Tooltip`=20component=20to=20use=20new=20base=20UI=20primiti?= =?UTF-8?q?ves?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated imports to use `@base-ui-components/react/tooltip`. * Simplified `TooltipProvider` and `Tooltip` components. * Enhanced `TooltipPopup` to include alignment and side properties. * Removed unnecessary arrow rendering logic. --- bun.lock | 3 -- package.json | 1 - src/components/ui/tooltip.tsx | 79 ++++++++++++++++------------------- 3 files changed, 35 insertions(+), 48 deletions(-) diff --git a/bun.lock b/bun.lock index 8e7e1ac..90a5be3 100644 --- a/bun.lock +++ b/bun.lock @@ -23,7 +23,6 @@ "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-toggle": "^1.1.10", "@radix-ui/react-toggle-group": "^1.1.11", - "@radix-ui/react-tooltip": "^1.2.8", "@tailwindcss/vite": "^4.1.16", "@tanstack/react-devtools": "^0.7.8", "@tanstack/react-form": "^1.23.8", @@ -304,8 +303,6 @@ "@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q=="], - "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg=="], - "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], diff --git a/package.json b/package.json index f8fa03b..626abd3 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-toggle": "^1.1.10", "@radix-ui/react-toggle-group": "^1.1.11", - "@radix-ui/react-tooltip": "^1.2.8", "@tailwindcss/vite": "^4.1.16", "@tanstack/react-devtools": "^0.7.8", "@tanstack/react-form": "^1.23.8", diff --git a/src/components/ui/tooltip.tsx b/src/components/ui/tooltip.tsx index 21dede2..a4575e4 100644 --- a/src/components/ui/tooltip.tsx +++ b/src/components/ui/tooltip.tsx @@ -1,64 +1,55 @@ -import * as TooltipPrimitive from "@radix-ui/react-tooltip"; -import type * as React from "react"; +import { Tooltip as TooltipPrimitive } from "@base-ui-components/react/tooltip"; import { cn } from "@/lib/utils"; -function TooltipProvider({ - delayDuration = 0, - ...props -}: React.ComponentProps) { - return ( - - ); -} +const TooltipProvider = TooltipPrimitive.Provider; -function Tooltip({ - ...props -}: React.ComponentProps) { - return ( - - - - ); -} +const Tooltip = TooltipPrimitive.Root; -function TooltipTrigger({ - ...props -}: React.ComponentProps) { +function TooltipTrigger(props: TooltipPrimitive.Trigger.Props) { return ; } -function TooltipContent({ +function TooltipPopup({ className, - sideOffset = 0, - arrow = true, + align = "center", + sideOffset = 4, + side = "top", children, ...props -}: React.ComponentProps & { - arrow?: boolean; +}: TooltipPrimitive.Popup.Props & { + align?: TooltipPrimitive.Positioner.Props["align"]; + side?: TooltipPrimitive.Positioner.Props["side"]; + sideOffset?: TooltipPrimitive.Positioner.Props["sideOffset"]; }) { return ( - - {children} - {arrow && ( - - )} - + + {children} + + ); } -export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }; +export { + TooltipProvider, + Tooltip, + TooltipTrigger, + TooltipPopup, + TooltipPopup as TooltipContent, +}; From da020aead24c1823cc1cedf40078a6f73d011ffd Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 14:58:54 +0100 Subject: [PATCH 009/100] =?UTF-8?q?feat(installation-card):=20=E2=9C=A8=20?= =?UTF-8?q?refactor=20`InstallationCard`=20to=20use=20`Group`=20and=20`Gro?= =?UTF-8?q?upItem`=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated button triggers to utilize `GroupItem` for better structure and styling. * Improved readability and maintainability of the `InstallationCard` component. --- src/components/cards/installation.card.tsx | 177 ++++++++++++--------- 1 file changed, 104 insertions(+), 73 deletions(-) diff --git a/src/components/cards/installation.card.tsx b/src/components/cards/installation.card.tsx index 5e1836d..82595a3 100644 --- a/src/components/cards/installation.card.tsx +++ b/src/components/cards/installation.card.tsx @@ -11,6 +11,7 @@ import { useDownloadVersion } from "@/hooks/use-download-version"; import { useInstalledVersions } from "@/hooks/use-installed-versions"; import { cn } from "@/lib/utils"; import type { Installation } from "@/stores/installations"; +import { Group, GroupItem } from "../ui/group"; import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; interface InstallationCardProps { @@ -63,39 +64,51 @@ export function InstallationCard({
-
+ {versions.includes(installation.version) ? ( <> - - - + onPlay(installation)} + size="icon" + variant="ghost" + /> + } + > + + Play {installation.name} + + } + /> Play {installation.name} ) : ( <> - - - + installVersion(installation.version)} + size="icon" + variant="ghost" + /> + } + > + + + Download version {installation.version} + + + } + /> Download version {installation.version} @@ -103,63 +116,81 @@ export function InstallationCard({ )} - - - + onAddMods(installation)} + size="icon" + variant="ghost" + /> + } + > + + Add mods to {installation.name} + + } + /> Add mods - - - + onEdit(installation)} + size="icon" + variant="ghost" + /> + } + > + + Edit {installation.name} + + } + /> Edit {installation.name} - - - + onUnfavorite(installation)} + size="icon" + variant="ghost" + /> + } + > + + + {installation.favorite ? "Unfavorite" : "Favorite"}{" "} + {installation.name} + + + } + /> {installation.favorite ? "Unfavorite" : "Favorite"} -
+ ); } From 1a3c0f8ea96c2e1b39df02e41ea72e3e5e58c6d1 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 14:59:07 +0100 Subject: [PATCH 010/100] =?UTF-8?q?feat(server-card):=20=E2=9C=A8=20refact?= =?UTF-8?q?or=20`ServerCard`=20to=20use=20`Group`=20and=20`GroupItem`=20co?= =?UTF-8?q?mponents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated the structure of the `ServerCard` component to utilize `Group` and `GroupItem` for better organization and styling. * Enhanced tooltip functionality by integrating `GroupItem` for button rendering. --- src/components/cards/server.card.tsx | 153 +++++++++++++++------------ 1 file changed, 84 insertions(+), 69 deletions(-) diff --git a/src/components/cards/server.card.tsx b/src/components/cards/server.card.tsx index 11aeea5..a7cdc5d 100644 --- a/src/components/cards/server.card.tsx +++ b/src/components/cards/server.card.tsx @@ -6,6 +6,7 @@ import { cn } from "@/lib/utils"; import { useInstallations } from "@/stores/installations"; import type { Server } from "@/stores/servers"; import { useSettingsStore } from "@/stores/settings"; +import { Group, GroupItem } from "../ui/group"; import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; interface ServerCardProps { @@ -58,85 +59,99 @@ export function ServerCard({ )}
-
+ - {versions.includes(installation.version) ? ( - <> - - - - Connect to {server.name} - - ) : ( - <> - - - - - Download version {installation.version} - - - )} + + versions.includes(installation.version) + ? onConnect(server) + : installVersion(installation.version) + } + size="icon" + variant="ghost" + /> + } + > + {versions.includes(installation.version) ? ( + <> + + Play {server.name} + + ) : ( + <> + + + Download version {installation.version} + + + )} + + } + /> + + {versions.includes(installation.version) + ? `Connect to ${server.name}` + : `Download version ${installation.version}`} + - - - + onEdit(server)} + size="icon" + variant="ghost" + /> + } + > + + Edit {server.name} + + } + /> Edit {server.name} - - - + onUnfavorite(server)} + size="icon" + variant="ghost" + /> + } + > + + + {server.favorite ? "Unfavorite" : "Favorite"} {server.name} + + + } + /> {server.favorite ? "Unfavorite" : "Favorite"} {server.name} -
+ ); } From 7bca21f5070b5e71a52970442ed9d3a19dffeede Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 14:59:14 +0100 Subject: [PATCH 011/100] =?UTF-8?q?feat(mod-item):=20=E2=9C=A8=20refactor?= =?UTF-8?q?=20`ModItem`=20to=20utilize=20`Group`,=20`GroupItem`,=20and=20`?= =?UTF-8?q?GroupSeparator`=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improved structure and readability by replacing button wrappers with `Group` components. * Enhanced tooltip triggers for better accessibility and maintainability. --- src/components/items/mod.item.tsx | 247 ++++++++++++++++++------------ 1 file changed, 149 insertions(+), 98 deletions(-) diff --git a/src/components/items/mod.item.tsx b/src/components/items/mod.item.tsx index 3506eeb..1144498 100644 --- a/src/components/items/mod.item.tsx +++ b/src/components/items/mod.item.tsx @@ -30,6 +30,7 @@ import type { OutputMod } from "@/routes/install-mods/$id"; import { useDialogStore } from "@/stores/dialogs"; import type { Installation } from "@/stores/installations"; import { useModsFilters } from "@/stores/modsFilters"; +import { Group, GroupItem, GroupSeparator } from "../ui/group"; export function ModItem({ mod, @@ -176,19 +177,21 @@ export function ModItem({

by

- - {/** biome-ignore lint/a11y/noStaticElementInteractions: Not really relevant */} - setAuthor(mod.author)} - onKeyUp={(e) => { - if (e.key === "Enter") { - setAuthor(mod.author); - } - }} - > - {mod.author} - + setAuthor(mod.author)} + onKeyUp={(e) => { + if (e.key === "Enter") { + setAuthor(mod.author); + } + }} + /> + } + > + {mod.author} Click to filter by author {mod.author} @@ -206,30 +209,39 @@ export function ModItem({ -
+ {updateMod && installation && updateMod && installedMod && compareSemverAsc(updateMod.modversion, installedMod.version) > 0 && ( - - - + + removeModFromInstallation({ + modpath: installedMod?.path ?? "", + path: installation.path, + }) + } + size="icon" + variant="outline" + /> + } + > + )} {!installedMod && installation && ( - - - + + downloadLatestModVersion({ + path: `${installation.path}${pathDelimiter}Mods`, + }) + } + size="icon" + variant="outline" + /> + } + > + )} {installation && installedMod && ( - - - + + openDialog("UpdateModDialog", { + installation, + mod: installedMod, + versionFrom: installedMod.version, + }) + } + size="icon" + variant="outline" + /> + } + > + )} {installation && (installedMod ? ( - - - + + openDialog("RemoveModDialog", { + installation, + name: mod.name, + path: installedMod.path ?? "", + }) + } + size="icon" + variant="destructive-outline" + /> + } + > + ) : ( - - - + + openDialog("AddModDialog", { + installation, + modid: mod.modid, + }) + } + size="icon" + variant="outline" + /> + } + > + ))} -
+ ); } From 1d917e3e1692c0882765fd64cc75bb47aa256957 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 14:59:19 +0100 Subject: [PATCH 012/100] =?UTF-8?q?feat(version-item):=20=E2=9C=A8=20refac?= =?UTF-8?q?tor=20`VersionItem`=20to=20improve=20`TooltipTrigger`=20usage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated `TooltipTrigger` to use `render` prop for better flexibility. * Cleaned up button styling for a more consistent appearance. --- src/components/items/version.item.tsx | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/items/version.item.tsx b/src/components/items/version.item.tsx index 382c124..2fb8ef3 100644 --- a/src/components/items/version.item.tsx +++ b/src/components/items/version.item.tsx @@ -26,17 +26,18 @@ export function VersionItem({ version }: VersionItemProps) { - - - + openDialog("DeleteVersionDialog", { version })} + size="icon" + variant="outline" + > + From f036a566d747de97ba56d085b8708fb9cb96c940 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 14:59:25 +0100 Subject: [PATCH 013/100] =?UTF-8?q?feat(world-item):=20=E2=9C=A8=20refacto?= =?UTF-8?q?r=20`WorldItem`=20to=20utilize=20`Group`,=20`GroupItem`,=20and?= =?UTF-8?q?=20`GroupSeparator`=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improved structure and readability by replacing inline elements with `Group` components. * Enhanced tooltip triggers with `GroupItem` for better organization of action buttons. * Maintained existing functionality while streamlining the component's layout. --- src/components/items/world.item.tsx | 197 +++++++++++++++------------- 1 file changed, 106 insertions(+), 91 deletions(-) diff --git a/src/components/items/world.item.tsx b/src/components/items/world.item.tsx index 5834230..8be873a 100644 --- a/src/components/items/world.item.tsx +++ b/src/components/items/world.item.tsx @@ -22,6 +22,7 @@ import type { World } from "@/lib/types"; import { cn } from "@/lib/utils"; import { useDialogStore } from "@/stores/dialogs"; import { useInstallations } from "@/stores/installations"; +import { Group, GroupItem, GroupSeparator } from "../ui/group"; export const WorldItem = ({ world }: { world: World }) => { const { installations } = useInstallations(); @@ -115,117 +116,131 @@ export const WorldItem = ({ world }: { world: World }) => { : "Never"}

-
+ - - {version ? ( - - ) : ( - - )} - + {version ? ( + - {world.has_map ? ( - - - - - View Map - - ) : ( - - - - - - No map available for {worldData.world_name} - - - )} - - - - + + } + /> Edit + - - - + openDialog("DeleteWorldDialog", { world })} + size="icon" + variant="outline" + /> + } + > + -
+ ); }; From 160dac0ddf3b3055189c063eff96674296e44dab Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 14:59:32 +0100 Subject: [PATCH 014/100] =?UTF-8?q?feat(installation-row):=20=E2=9C=A8=20r?= =?UTF-8?q?efactor=20`InstallationRow`=20to=20utilize=20`Group`,=20`GroupI?= =?UTF-8?q?tem`,=20and=20`GroupSeparator`=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improved structure and readability by replacing inline button elements with `Group` components. * Enhanced the organization of action buttons related to installations. --- src/components/rows/installation.row.tsx | 350 +++++++++++++---------- 1 file changed, 202 insertions(+), 148 deletions(-) diff --git a/src/components/rows/installation.row.tsx b/src/components/rows/installation.row.tsx index a90599c..0b50e18 100644 --- a/src/components/rows/installation.row.tsx +++ b/src/components/rows/installation.row.tsx @@ -24,6 +24,7 @@ import { useRevealInFolder } from "@/hooks/use-reveal-in-folder"; import { cn, exportInstallation } from "@/lib/utils"; import { useDialogStore } from "@/stores/dialogs"; import { type Installation, useInstallations } from "@/stores/installations"; +import { Group, GroupItem, GroupSeparator } from "../ui/group"; export type InstallationRowProps = { installation: Installation; @@ -68,184 +69,237 @@ export function InstallationRow({ installation }: InstallationRowProps) {
-
+ - - {version ? ( - - ) : ( - - )} - + {version ? ( + + - - - + toggleFavorite(installation.id)} + size="icon" + variant="outline" + /> + } + > + + - - - + + router.navigate({ + params: { id: installation.id.toString() }, + to: "/install-mods/$id", + viewTransition: { + types: ["warp"], + }, + }) + } + size="icon" + variant="outline" + /> + } + > + + - - - + + router.navigate({ + params: { id: installation.id.toString() }, + to: "/mod-configs/$id", + viewTransition: { + types: ["warp"], + }, + }) + } + size="icon" + variant="outline" + /> + } + > + + - - - + openFolder(installation.path)} + size="icon" + variant="outline" + /> + } + > + + - - - + exportInstallation({ installation })} + size="icon" + variant="outline" + /> + } + > + + - - - + + openDialog("EditInstallationDialog", { installation }) + } + size="icon" + variant="outline" + /> + } + > + + - - - + + openDialog("DeleteInstallationDialog", { installation }) + } + size="icon" + variant="outline" + /> + } + > + -
+ ); } From fe701788c5a1339bca4089d95b01d3db87ee8708 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 14:59:57 +0100 Subject: [PATCH 015/100] =?UTF-8?q?feat(server-row):=20=E2=9C=A8=20refacto?= =?UTF-8?q?r=20`ServerRow`=20to=20utilize=20`Group`,=20`GroupItem`,=20and?= =?UTF-8?q?=20`GroupSeparator`=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improved structure and readability by replacing inline button elements with `Group` components. * Enhanced tooltip functionality by integrating `GroupItem` for better organization of action buttons. * Maintained existing functionality while streamlining the component's layout. --- bun.lock | 10 -- package.json | 4 - src/components/rows/server.row.tsx | 178 ++++++++++++++++------------- 3 files changed, 101 insertions(+), 91 deletions(-) diff --git a/bun.lock b/bun.lock index 90a5be3..e07816b 100644 --- a/bun.lock +++ b/bun.lock @@ -11,18 +11,14 @@ "@dnd-kit/utilities": "^3.2.2", "@monaco-editor/react": "^4.7.0", "@radix-ui/react-context-menu": "^2.2.16", - "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", "@radix-ui/react-label": "^2.1.7", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-select": "^2.2.6", - "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-tabs": "^1.1.13", - "@radix-ui/react-toggle": "^1.1.10", - "@radix-ui/react-toggle-group": "^1.1.11", "@tailwindcss/vite": "^4.1.16", "@tanstack/react-devtools": "^0.7.8", "@tanstack/react-form": "^1.23.8", @@ -291,18 +287,12 @@ "@radix-ui/react-select": ["@radix-ui/react-select@2.2.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ=="], - "@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA=="], - "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], "@radix-ui/react-switch": ["@radix-ui/react-switch@1.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ=="], "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="], - "@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ=="], - - "@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q=="], - "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], diff --git a/package.json b/package.json index 626abd3..a379f5e 100644 --- a/package.json +++ b/package.json @@ -7,18 +7,14 @@ "@dnd-kit/utilities": "^3.2.2", "@monaco-editor/react": "^4.7.0", "@radix-ui/react-context-menu": "^2.2.16", - "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", "@radix-ui/react-label": "^2.1.7", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-select": "^2.2.6", - "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-tabs": "^1.1.13", - "@radix-ui/react-toggle": "^1.1.10", - "@radix-ui/react-toggle-group": "^1.1.11", "@tailwindcss/vite": "^4.1.16", "@tanstack/react-devtools": "^0.7.8", "@tanstack/react-form": "^1.23.8", diff --git a/src/components/rows/server.row.tsx b/src/components/rows/server.row.tsx index a3f1a0e..a0437fa 100644 --- a/src/components/rows/server.row.tsx +++ b/src/components/rows/server.row.tsx @@ -19,6 +19,7 @@ import { useDialogStore } from "@/stores/dialogs"; import { useInstallations } from "@/stores/installations"; import { type Server, useServerStore } from "@/stores/servers"; import { useSettingsStore } from "@/stores/settings"; +import { Group, GroupItem, GroupSeparator } from "../ui/group"; type ServerRowProps = { server: Server; @@ -59,103 +60,126 @@ export function ServerRow({ server }: ServerRowProps) {

-
+ - - {versions?.includes(installation?.version ?? "") ? ( - - ) : ( - - )} - + {versions?.includes(installation?.version ?? "") ? ( + + - - - + toggleFavorite(server.id)} + variant="outline" + /> + } + > + + - - - + openDialog("EditServerDialog", { server })} + variant="outline" + /> + } + > + + - - - + openDialog("DeleteServerDialog", { server })} + size="icon" + variant="outline" + /> + } + > + -
+ ); } From 25eb00df9edb9af6dd8dc7a987f5ffcc027ce69c Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 15:00:04 +0100 Subject: [PATCH 016/100] =?UTF-8?q?feat(version-row):=20=E2=9C=A8=20refact?= =?UTF-8?q?or=20`VersionRow`=20to=20utilize=20`Group`,=20`GroupItem`,=20an?= =?UTF-8?q?d=20`GroupSeparator`=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improved structure and readability by replacing div with `Group`. * Enhanced tooltip trigger implementation using `GroupItem`. --- src/components/rows/version.row.tsx | 82 ++++++++++++++++++----------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/src/components/rows/version.row.tsx b/src/components/rows/version.row.tsx index 424bd84..7627e68 100644 --- a/src/components/rows/version.row.tsx +++ b/src/components/rows/version.row.tsx @@ -10,6 +10,7 @@ import { useRevealInFolder } from "@/hooks/use-reveal-in-folder"; import { pathDelimiter } from "@/lib/utils"; import { useDialogStore } from "@/stores/dialogs"; import { useSettingsStore } from "@/stores/settings"; +import { Group, GroupItem, GroupSeparator } from "../ui/group"; export function VersionRow({ version }: { version: string }) { const { appFolder } = useAppFolder(); @@ -31,44 +32,61 @@ export function VersionRow({ version }: { version: string }) { )} -
+ - - - + + openFolder( + `${versionsParent ?? appFolder}${pathDelimiter}${versionsSubdir}${pathDelimiter}${version}`, + ) + } + size="icon" + variant="outline" + /> + } + > + + - - - + + openDialog("DeleteVersionDialog", { version }) + } + size="icon" + variant="outline" + /> + } + > + -
+ ); } From 897fc2143e34a6fef4f17c60c488b3a947d06eed Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 15:00:14 +0100 Subject: [PATCH 017/100] =?UTF-8?q?feat(group):=20=E2=9C=A8=20add=20`Group?= =?UTF-8?q?`,=20`GroupItem`,=20and=20`GroupSeparator`=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Introduced new components to enhance UI grouping functionality. * `Group` provides a flexible container for child elements. * `GroupItem` allows for customizable items within the group. * `GroupSeparator` adds visual separation between grouped items. --- src/components/ui/group.tsx | 62 +++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/components/ui/group.tsx diff --git a/src/components/ui/group.tsx b/src/components/ui/group.tsx new file mode 100644 index 0000000..025313f --- /dev/null +++ b/src/components/ui/group.tsx @@ -0,0 +1,62 @@ +import { mergeProps } from "@base-ui-components/react/merge-props"; +import { useRender } from "@base-ui-components/react/use-render"; +import type * as React from "react"; +import { Separator } from "@/components/ui/separator"; +import { cn } from "@/lib/utils"; + +function Group({ + className, + children, + ...props +}: { + className?: string; + children: React.ReactNode; +}) { + return ( + // biome-ignore lint/a11y/useSemanticElements: Needed +
+ {children} +
+ ); +} + +function GroupItem({ + className, + render, + ...props +}: useRender.ComponentProps<"div">) { + const defaultProps = { + className: cn( + "border-x-0 not-first:rounded-s-none not-last:rounded-e-none before:[clip-path:inset(-1rem_var(--clip-end)_-1rem_var(--clip-start))] not-first:before:-start-0.5 not-first:before:rounded-s-none not-first:before:[--clip-start:2px] not-last:before:-end-0.5 not-last:before:rounded-e-none not-last:before:[--clip-end:2px] first:border-s last:border-e focus-visible:z-10 has-focus-visible:z-10 not-last:has-[+[data-slot=separator]]:before:[--clip-end:1.5px] [[data-slot=separator]+&]:before:[--clip-start:1.5px]", + className, + ), + }; + return useRender({ + defaultTagName: "div", + props: mergeProps(defaultProps, props), + render, + }); +} + +function GroupSeparator({ className, ...props }: { className?: string }) { + return ( + + ); +} + +export { Group, GroupItem, GroupSeparator }; From c9308ff73baa5a9ac6eafd6d5a5080e39f875a13 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 15:00:20 +0100 Subject: [PATCH 018/100] =?UTF-8?q?feat(toggle-group):=20=E2=9C=A8=20refac?= =?UTF-8?q?tor=20`ToggleGroup`=20and=20`Toggle`=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated `ToggleGroup` to use `ToggleGroupPrimitive` directly. * Refactored `Toggle` to utilize `ToggleComponent` for better consistency. * Improved context handling for `variant` and `size` props. --- src/components/ui/toggle-group.tsx | 57 ++++++++++++++++++------------ 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/src/components/ui/toggle-group.tsx b/src/components/ui/toggle-group.tsx index ed897bb..7dd564e 100644 --- a/src/components/ui/toggle-group.tsx +++ b/src/components/ui/toggle-group.tsx @@ -1,7 +1,12 @@ -import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"; +import type { Toggle as TogglePrimitive } from "@base-ui-components/react/toggle"; +import { ToggleGroup as ToggleGroupPrimitive } from "@base-ui-components/react/toggle-group"; import type { VariantProps } from "class-variance-authority"; import * as React from "react"; -import { toggleVariants } from "@/components/ui/toggle"; +import { Separator } from "@/components/ui/separator"; +import { + Toggle as ToggleComponent, + type toggleVariants, +} from "@/components/ui/toggle"; import { cn } from "@/lib/utils"; const ToggleGroupContext = React.createContext< @@ -13,16 +18,18 @@ const ToggleGroupContext = React.createContext< function ToggleGroup({ className, - variant, - size, + variant = "default", + size = "default", children, ...props -}: React.ComponentProps & - VariantProps) { +}: ToggleGroupPrimitive.Props & VariantProps) { return ( - {children} - + ); } -function ToggleGroupItem({ +function Toggle({ className, children, variant, size, ...props -}: React.ComponentProps & - VariantProps) { +}: TogglePrimitive.Props & VariantProps) { const context = React.useContext(ToggleGroupContext); + const resolvedVariant = context.variant || variant; + const resolvedSize = context.size || size; + return ( - {children} - + ); } -export { ToggleGroup, ToggleGroupItem }; +function ToggleGroupSeparator({ className, ...props }: { className?: string }) { + return ; +} + +export { ToggleGroup, Toggle, Toggle as ToggleGroupItem, ToggleGroupSeparator }; From 53df5c0f45b8e0e3624ec0b72324b23ca768c982 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 15:00:30 +0100 Subject: [PATCH 019/100] =?UTF-8?q?feat(tabs):=20=E2=9C=A8=20refactor=20`T?= =?UTF-8?q?abs`,=20`TabsList`,=20`TabsTab`,=20and=20`TabsPanel`=20componen?= =?UTF-8?q?ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated imports to use `@base-ui-components/react/tabs`. * Enhanced `TabsList` to include a tab indicator for better UX. * Improved styling and structure for better responsiveness and visual consistency. --- src/components/ui/tabs.tsx | 68 ++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/src/components/ui/tabs.tsx b/src/components/ui/tabs.tsx index bd83bd2..026a4cc 100644 --- a/src/components/ui/tabs.tsx +++ b/src/components/ui/tabs.tsx @@ -1,15 +1,16 @@ -import * as TabsPrimitive from "@radix-ui/react-tabs"; -import type * as React from "react"; +import { Tabs as TabsPrimitive } from "@base-ui-components/react/tabs"; import { cn } from "@/lib/utils"; -function Tabs({ - className, - ...props -}: React.ComponentProps) { +type TabsVariant = "default" | "underline"; + +function Tabs({ className, ...props }: TabsPrimitive.Root.Props) { return ( @@ -17,29 +18,48 @@ function Tabs({ } function TabsList({ + variant = "default", className, + children, ...props -}: React.ComponentProps) { +}: TabsPrimitive.List.Props & { + variant?: TabsVariant; +}) { return ( + > + {children} + + ); } -function TabsTrigger({ - className, - ...props -}: React.ComponentProps) { +function TabsTab({ className, ...props }: TabsPrimitive.Tab.Props) { return ( - ) { +function TabsPanel({ className, ...props }: TabsPrimitive.Panel.Props) { return ( - Date: Mon, 27 Oct 2025 15:00:35 +0100 Subject: [PATCH 020/100] =?UTF-8?q?feat(toggle):=20=E2=9C=A8=20refactor=20?= =?UTF-8?q?`Toggle`=20component=20to=20use=20`@base-ui-components/react/to?= =?UTF-8?q?ggle`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated import statement to use `Toggle` from `@base-ui-components/react/toggle`. * Enhanced styling and variant definitions for improved UI consistency. * Adjusted component props to align with the new toggle implementation. --- src/components/ui/toggle.tsx | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/components/ui/toggle.tsx b/src/components/ui/toggle.tsx index 8d2a4a0..30239d5 100644 --- a/src/components/ui/toggle.tsx +++ b/src/components/ui/toggle.tsx @@ -1,11 +1,10 @@ -import * as TogglePrimitive from "@radix-ui/react-toggle"; +import { Toggle as TogglePrimitive } from "@base-ui-components/react/toggle"; import { cva, type VariantProps } from "class-variance-authority"; -import type * as React from "react"; import { cn } from "@/lib/utils"; const toggleVariants = cva( - "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap", + "relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 rounded-lg border text-sm font-medium whitespace-nowrap transition-shadow outline-none select-none before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-lg)-1px)] hover:bg-accent/50 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 data-pressed:bg-accent data-pressed:text-accent-foreground data-pressed:transition-none dark:hover:bg-accent dark:data-pressed:bg-input/80 pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", { defaultVariants: { size: "default", @@ -13,14 +12,14 @@ const toggleVariants = cva( }, variants: { size: { - default: "h-9 px-2 min-w-9", - lg: "h-10 px-2.5 min-w-10", - sm: "h-8 px-1.5 min-w-8", + default: "h-8 min-w-8 px-[calc(--spacing(2)-1px)]", + lg: "h-9 min-w-9 px-[calc(--spacing(2.5)-1px)]", + sm: "h-7 min-w-7 px-[calc(--spacing(1.5)-1px)]", }, variant: { - default: "bg-transparent", + default: "border-transparent", outline: - "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground", + "border-border bg-clip-padding shadow-xs not-disabled:not-active:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] dark:bg-input/32 dark:not-disabled:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/4%)] dark:not-disabled:not-active:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/8%)] dark:hover:bg-input/64 [&:is(:disabled,:active,[data-pressed])]:shadow-none", }, }, }, @@ -31,10 +30,9 @@ function Toggle({ variant, size, ...props -}: React.ComponentProps & - VariantProps) { +}: TogglePrimitive.Props & VariantProps) { return ( - Date: Mon, 27 Oct 2025 15:00:40 +0100 Subject: [PATCH 021/100] =?UTF-8?q?feat(route):=20=E2=9C=A8=20update=20`Bu?= =?UTF-8?q?tton`=20component=20to=20use=20`render`=20prop=20for=20navigati?= =?UTF-8?q?on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactored the `Button` component in `RouteComponent` to utilize the `render` prop for the `Link` element. * This change improves the flexibility of the `Button` component while maintaining the same functionality. --- src/routes/mod-configs/$id.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/routes/mod-configs/$id.tsx b/src/routes/mod-configs/$id.tsx index 03bcd26..e411756 100644 --- a/src/routes/mod-configs/$id.tsx +++ b/src/routes/mod-configs/$id.tsx @@ -76,8 +76,11 @@ function RouteComponent() { >
- {modConfigs?.map((config) => ( From 72b7eef4ef1e03b8036ba4fc95a379b7d1f098f5 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 15:00:46 +0100 Subject: [PATCH 022/100] =?UTF-8?q?feat(toggle-group):=20=E2=9C=A8=20refac?= =?UTF-8?q?tor=20`SideToggleGroup`=20to=20simplify=20state=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Removed unused type import for `ModsFilters`. * Updated `onValueChange` to directly set the selected side value. * Changed `multiple` prop to `false` for single selection. --- src/components/toggle-groups/side.toggle-group.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/toggle-groups/side.toggle-group.tsx b/src/components/toggle-groups/side.toggle-group.tsx index 11e503f..3623345 100644 --- a/src/components/toggle-groups/side.toggle-group.tsx +++ b/src/components/toggle-groups/side.toggle-group.tsx @@ -1,5 +1,5 @@ import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"; -import { type ModsFilters, useModsFilters } from "@/stores/modsFilters"; +import { useModsFilters } from "@/stores/modsFilters"; export default function SideToggleGroup() { const { side, setSide } = useModsFilters(); @@ -7,11 +7,9 @@ export default function SideToggleGroup() { return ( { - if (value) setSide(value); - }} - type="single" - value={side} + multiple={false} + onValueChange={(v) => setSide(v[0])} + value={[side]} > Any From 4155e9de99f6d65dddd51e3147c12164cdde1f51 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 18:05:29 +0100 Subject: [PATCH 023/100] =?UTF-8?q?feat(number-field):=20=E2=9C=A8=20add?= =?UTF-8?q?=20`NumberField`=20component=20with=20increment=20and=20decreme?= =?UTF-8?q?nt=20functionality?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Introduced `NumberField`, `NumberFieldGroup`, `NumberFieldDecrement`, `NumberFieldIncrement`, `NumberFieldInput`, and `NumberFieldScrubArea` components. * Utilized `@base-ui-components/react/number-field` for base functionality. * Implemented context for managing field ID and accessibility. * Added icons for increment and decrement actions. --- src/components/ui/number-field.tsx | 158 +++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 src/components/ui/number-field.tsx diff --git a/src/components/ui/number-field.tsx b/src/components/ui/number-field.tsx new file mode 100644 index 0000000..f828983 --- /dev/null +++ b/src/components/ui/number-field.tsx @@ -0,0 +1,158 @@ +import { NumberField as NumberFieldPrimitive } from "@base-ui-components/react/number-field"; +import { MinusIcon, PlusIcon } from "lucide-react"; +import * as React from "react"; +import { Label } from "@/components/ui/label"; +import { cn } from "@/lib/utils"; + +const NumberFieldContext = React.createContext<{ + fieldId: string; +} | null>(null); + +function NumberField({ + id, + className, + size = "default", + ...props +}: NumberFieldPrimitive.Root.Props & { + size?: "sm" | "default" | "lg"; +}) { + const generatedId = React.useId(); + const fieldId = id ?? generatedId; + + return ( + + + + ); +} + +function NumberFieldGroup({ + className, + ...props +}: NumberFieldPrimitive.Group.Props) { + return ( + + ); +} + +function NumberFieldDecrement({ + className, + ...props +}: NumberFieldPrimitive.Decrement.Props) { + return ( + + + + ); +} + +function NumberFieldIncrement({ + className, + ...props +}: NumberFieldPrimitive.Increment.Props) { + return ( + + + + ); +} + +function NumberFieldInput({ + className, + ...props +}: NumberFieldPrimitive.Input.Props) { + return ( + + ); +} + +function NumberFieldScrubArea({ + className, + label, + ...props +}: NumberFieldPrimitive.ScrubArea.Props & { + label: string; +}) { + const context = React.useContext(NumberFieldContext); + + if (!context) { + throw new Error( + "NumberFieldScrubArea must be used within a NumberField component for accessibility.", + ); + } + + return ( + + + + + + + ); +} + +function CursorGrowIcon(props: React.ComponentProps<"svg">) { + return ( + + Resize Cursor + + + ); +} + +export { + NumberField, + NumberFieldScrubArea, + NumberFieldDecrement, + NumberFieldIncrement, + NumberFieldGroup, + NumberFieldInput, +}; From b34ce5d7635639e7a66370432252d21c1410e537 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 18:05:39 +0100 Subject: [PATCH 024/100] =?UTF-8?q?refactor(label):=20=E2=9C=A8=20simplify?= =?UTF-8?q?=20`Label`=20component=20by=20removing=20dependency=20on=20`@ra?= =?UTF-8?q?dix-ui/react-label`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Changed from using `LabelPrimitive.Root` to a standard `label` element. * Maintained existing styling and accessibility features. --- src/components/ui/label.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/components/ui/label.tsx b/src/components/ui/label.tsx index 7fef7f3..2faa7eb 100644 --- a/src/components/ui/label.tsx +++ b/src/components/ui/label.tsx @@ -1,16 +1,13 @@ -import * as LabelPrimitive from "@radix-ui/react-label"; import type * as React from "react"; import { cn } from "@/lib/utils"; -function Label({ - className, - ...props -}: React.ComponentProps) { +function Label({ className, ...props }: React.ComponentProps<"label">) { return ( - Date: Mon, 27 Oct 2025 18:05:45 +0100 Subject: [PATCH 025/100] =?UTF-8?q?refactor(switch):=20=E2=9C=A8=20update?= =?UTF-8?q?=20`Switch`=20component=20to=20use=20`@base-ui-components/react?= =?UTF-8?q?/switch`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Removed dependency on `@radix-ui/react-switch`. * Simplified class names for better styling consistency. --- src/components/ui/switch.tsx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/components/ui/switch.tsx b/src/components/ui/switch.tsx index 848fee2..4b0705f 100644 --- a/src/components/ui/switch.tsx +++ b/src/components/ui/switch.tsx @@ -1,16 +1,12 @@ -import * as SwitchPrimitive from "@radix-ui/react-switch"; -import type * as React from "react"; +import { Switch as SwitchPrimitive } from "@base-ui-components/react/switch"; import { cn } from "@/lib/utils"; -function Switch({ - className, - ...props -}: React.ComponentProps) { +function Switch({ className, ...props }: SwitchPrimitive.Root.Props) { return ( From 35dda887d9fb32f9ea009780df76f102d6004549 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 18:05:51 +0100 Subject: [PATCH 026/100] =?UTF-8?q?refactor(tabs):=20=E2=9C=A8=20update=20?= =?UTF-8?q?`TabsList`=20styling=20for=20improved=20appearance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Changed background color and border for the default variant. * Adjusted height to enhance layout consistency. --- src/components/ui/tabs.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ui/tabs.tsx b/src/components/ui/tabs.tsx index 026a4cc..dc2df58 100644 --- a/src/components/ui/tabs.tsx +++ b/src/components/ui/tabs.tsx @@ -31,7 +31,7 @@ function TabsList({ "relative z-0 flex w-fit items-center justify-center gap-x-0.5 text-muted-foreground", "data-[orientation=vertical]:flex-col", variant === "default" - ? "rounded-lg bg-muted p-0.5 text-muted-foreground/64" + ? "rounded-lg bg-background border h-8 text-muted-foreground/64" : "data-[orientation=horizontal]:py-1 data-[orientation=vertical]:px-1 *:data-[slot=tabs-trigger]:hover:bg-accent", className, )} From cff2d0f35986f572d86cb6653a05d108720b14dc Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 18:06:08 +0100 Subject: [PATCH 027/100] =?UTF-8?q?refactor(switch):=20=E2=9C=A8=20update?= =?UTF-8?q?=20`TextSwitch`=20to=20use=20`@base-ui-components/react/switch`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Changed import from `@radix-ui/react-switch` to `@base-ui-components/react/switch`. * Updated `TextSwitch` component to handle checked state change with event details. * Improved styling classes for better visual representation. * Removed deprecated `SideToggleGroup` component and replaced its usage with `SideToggleGroup` from `tabs`. --- src/components/switches/text.switch.tsx | 21 +++++++------ src/components/tabs/side.tab.tsx | 31 +++++++++++++++++++ .../toggle-groups/side.toggle-group.tsx | 31 ------------------- src/routes/install-mods/$id.tsx | 2 +- 4 files changed, 44 insertions(+), 41 deletions(-) create mode 100644 src/components/tabs/side.tab.tsx delete mode 100644 src/components/toggle-groups/side.toggle-group.tsx diff --git a/src/components/switches/text.switch.tsx b/src/components/switches/text.switch.tsx index 898c66a..1a88504 100644 --- a/src/components/switches/text.switch.tsx +++ b/src/components/switches/text.switch.tsx @@ -1,4 +1,4 @@ -import type { SwitchProps } from "@radix-ui/react-switch"; +import type { Switch as SwitchPrimitive } from "@base-ui-components/react/switch"; import { clsx } from "clsx"; import { forwardRef, useId, useState } from "react"; import { Switch } from "@/components/ui/switch"; @@ -7,9 +7,9 @@ type TextSwitchProps = { textChecked?: string; textUnchecked?: string; className?: string | ((active: boolean) => string); -} & Omit; +} & Omit; -export const TextSwitch = forwardRef( +export const TextSwitch = forwardRef( ( { className, @@ -24,9 +24,12 @@ export const TextSwitch = forwardRef( const id = useId(); const [internalChecked, setInternalChecked] = useState(false); - const handleCheckedChange = (checked: boolean) => { + const handleCheckedChange = ( + checked: boolean, + event: SwitchPrimitive.Root.ChangeEventDetails, + ) => { setInternalChecked(checked); - onCheckedChange?.(checked); + onCheckedChange?.(checked, event); }; const active = checked ?? internalChecked; @@ -39,20 +42,20 @@ export const TextSwitch = forwardRef( - + {textUnchecked ?? "Off"} - + {textChecked ?? "On"} diff --git a/src/components/tabs/side.tab.tsx b/src/components/tabs/side.tab.tsx new file mode 100644 index 0000000..3522732 --- /dev/null +++ b/src/components/tabs/side.tab.tsx @@ -0,0 +1,31 @@ +import { useModsFilters } from "@/stores/modsFilters"; +import { Tabs, TabsList, TabsTab } from "../ui/tabs"; + +export default function SideToggleGroup() { + const { side, setSide } = useModsFilters(); + + return ( + + + + Any + + + Client + + + Server + + + Both + + + Installed + + + Side + + + + ); +} diff --git a/src/components/toggle-groups/side.toggle-group.tsx b/src/components/toggle-groups/side.toggle-group.tsx deleted file mode 100644 index 3623345..0000000 --- a/src/components/toggle-groups/side.toggle-group.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"; -import { useModsFilters } from "@/stores/modsFilters"; - -export default function SideToggleGroup() { - const { side, setSide } = useModsFilters(); - - return ( - setSide(v[0])} - value={[side]} - > - - Any - - - Client - - - Server - - - Both - - - Installed - - - ); -} diff --git a/src/routes/install-mods/$id.tsx b/src/routes/install-mods/$id.tsx index a09d298..c609069 100644 --- a/src/routes/install-mods/$id.tsx +++ b/src/routes/install-mods/$id.tsx @@ -7,7 +7,7 @@ import { AuthorCombobox } from "@/components/comboboxes/author.combobox"; import { SearchInput } from "@/components/inputs"; import { ModList } from "@/components/lists/mod.list"; import { TextSwitch } from "@/components/switches/text.switch"; -import SideToggleGroup from "@/components/toggle-groups/side.toggle-group"; +import SideToggleGroup from "@/components/tabs/side.tab"; import { DropdownMenu, DropdownMenuCheckboxItem, From e664fde125d6a82ff338752a25bd4ac3d08e6d16 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Mon, 27 Oct 2025 18:06:20 +0100 Subject: [PATCH 028/100] =?UTF-8?q?refactor(input):=20=E2=9C=A8=20update?= =?UTF-8?q?=20`Input`=20component=20to=20use=20`@base-ui-components/react/?= =?UTF-8?q?input`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactored the `Input` component to utilize the new `InputPrimitive` from `@base-ui-components/react/input`. * Enhanced styling and structure for better integration with the UI framework. * Removed unnecessary props and streamlined the component's API. --- bun.lock | 6 --- package.json | 2 - src/components/comboboxes/author.combobox.tsx | 2 +- src/components/ui/input.tsx | 38 ++++++++++++++----- src/routes/mod-configs/$id.tsx | 32 ++++++++++++---- 5 files changed, 53 insertions(+), 27 deletions(-) diff --git a/bun.lock b/bun.lock index e07816b..be43c5c 100644 --- a/bun.lock +++ b/bun.lock @@ -12,12 +12,10 @@ "@monaco-editor/react": "^4.7.0", "@radix-ui/react-context-menu": "^2.2.16", "@radix-ui/react-dropdown-menu": "^2.1.16", - "@radix-ui/react-label": "^2.1.7", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "^1.2.3", - "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-tabs": "^1.1.13", "@tailwindcss/vite": "^4.1.16", "@tanstack/react-devtools": "^0.7.8", @@ -267,8 +265,6 @@ "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="], - "@radix-ui/react-label": ["@radix-ui/react-label@2.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ=="], - "@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg=="], "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA=="], @@ -289,8 +285,6 @@ "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - "@radix-ui/react-switch": ["@radix-ui/react-switch@1.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ=="], - "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="], "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], diff --git a/package.json b/package.json index a379f5e..c468293 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,10 @@ "@monaco-editor/react": "^4.7.0", "@radix-ui/react-context-menu": "^2.2.16", "@radix-ui/react-dropdown-menu": "^2.1.16", - "@radix-ui/react-label": "^2.1.7", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "^1.2.3", - "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-tabs": "^1.1.13", "@tailwindcss/vite": "^4.1.16", "@tanstack/react-devtools": "^0.7.8", diff --git a/src/components/comboboxes/author.combobox.tsx b/src/components/comboboxes/author.combobox.tsx index 467637c..6cb3d67 100644 --- a/src/components/comboboxes/author.combobox.tsx +++ b/src/components/comboboxes/author.combobox.tsx @@ -68,7 +68,7 @@ export const AuthorCombobox = ( role="combobox" variant="outline" > - + Author {actualValue ? actualValue : "Select author..."} diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx index d2c03e6..2ef2b33 100644 --- a/src/components/ui/input.tsx +++ b/src/components/ui/input.tsx @@ -1,20 +1,38 @@ -import type * as React from "react"; +import { Input as InputPrimitive } from "@base-ui-components/react/input"; import { cn } from "@/lib/utils"; -function Input({ className, type, ...props }: React.ComponentProps<"input">) { +function Input({ + className, + size = "default", + ...props +}: Omit & { + size?: "sm" | "default" | "lg" | number; +}) { return ( - + data-slot="input-control" + > + + ); } diff --git a/src/routes/mod-configs/$id.tsx b/src/routes/mod-configs/$id.tsx index e411756..1b6e527 100644 --- a/src/routes/mod-configs/$id.tsx +++ b/src/routes/mod-configs/$id.tsx @@ -7,6 +7,13 @@ import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { ErrorComponent } from "@/components/ui/error"; import { Input } from "@/components/ui/input"; +import { + NumberField, + NumberFieldDecrement, + NumberFieldGroup, + NumberFieldIncrement, + NumberFieldInput, +} from "@/components/ui/number-field"; import { Switch } from "@/components/ui/switch"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { modConfigsQueryKey, useModConfigs } from "@/hooks/use-mod-configs"; @@ -71,10 +78,11 @@ function RouteComponent() {
-
+
@@ -352,13 +360,21 @@ function LiveBlock({ > {keyLabel} - handlePrimitiveChange(path, e.target.value, value)} - type="number" + onValueChange={(v) => + handlePrimitiveChange(path, v?.toString() ?? "0", value) + } + size="sm" value={value} - /> + > + + + + + +
); } From aff0e53c3936ec2c5e5e87430fefc86e0c8826c1 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:23:46 +0100 Subject: [PATCH 029/100] =?UTF-8?q?feat(autocomplete):=20=E2=9C=A8=20add?= =?UTF-8?q?=20`Autocomplete`=20component=20with=20various=20subcomponents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Implemented `AutocompleteInput`, `AutocompletePopup`, `AutocompleteItem`, and others. * Integrated `@base-ui-components/react/autocomplete` for enhanced functionality. * Added support for custom triggers and clear actions. --- src/components/ui/auto-complete.tsx | 279 ++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 src/components/ui/auto-complete.tsx diff --git a/src/components/ui/auto-complete.tsx b/src/components/ui/auto-complete.tsx new file mode 100644 index 0000000..f8cd142 --- /dev/null +++ b/src/components/ui/auto-complete.tsx @@ -0,0 +1,279 @@ +import { Autocomplete as AutocompletePrimitive } from "@base-ui-components/react/autocomplete"; +import { ChevronsUpDownIcon, XIcon } from "lucide-react"; +import { Input } from "@/components/ui/input"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { cn } from "@/lib/utils"; + +const Autocomplete = AutocompletePrimitive.Root; + +function AutocompleteInput({ + className, + showTrigger = false, + showClear = false, + size, + ...props +}: Omit & { + showTrigger?: boolean; + showClear?: boolean; + size?: "sm" | "default" | "lg" | number; +}) { + const sizeValue = (size ?? "default") as "sm" | "default" | "lg" | number; + + return ( +
+ } + {...props} + /> + {showTrigger && ( + + + + )} + {showClear && ( + + + + )} +
+ ); +} + +function AutocompletePopup({ + className, + children, + sideOffset = 4, + ...props +}: AutocompletePrimitive.Popup.Props & { + sideOffset?: number; +}) { + return ( + + + + + {children} + + + + + ); +} + +function AutocompleteItem({ + className, + children, + ...props +}: AutocompletePrimitive.Item.Props) { + return ( + + {children} + + ); +} + +function AutocompleteSeparator({ + className, + ...props +}: AutocompletePrimitive.Separator.Props) { + return ( + + ); +} + +function AutocompleteGroup({ + className, + ...props +}: AutocompletePrimitive.Group.Props) { + return ( + + ); +} + +function AutocompleteGroupLabel({ + className, + ...props +}: AutocompletePrimitive.GroupLabel.Props) { + return ( + + ); +} + +function AutocompleteEmpty({ + className, + ...props +}: AutocompletePrimitive.Empty.Props) { + return ( + + ); +} + +function AutocompleteRow({ + className, + ...props +}: AutocompletePrimitive.Row.Props) { + return ( + + ); +} + +function AutocompleteValue({ ...props }: AutocompletePrimitive.Value.Props) { + return ( + + ); +} + +function AutocompleteList({ + className, + ...props +}: AutocompletePrimitive.List.Props) { + return ( + + + + ); +} + +function AutocompleteClear({ + className, + ...props +}: AutocompletePrimitive.Clear.Props) { + return ( + + + + ); +} + +function AutocompleteStatus({ + className, + ...props +}: AutocompletePrimitive.Status.Props) { + return ( + + ); +} + +function AutocompleteCollection({ + ...props +}: AutocompletePrimitive.Collection.Props) { + return ( + + ); +} + +function AutocompleteTrigger({ + className, + ...props +}: AutocompletePrimitive.Trigger.Props) { + return ( + + ); +} + +export { + Autocomplete, + AutocompleteInput, + AutocompleteTrigger, + AutocompletePopup, + AutocompleteItem, + AutocompleteSeparator, + AutocompleteGroup, + AutocompleteGroupLabel, + AutocompleteEmpty, + AutocompleteValue, + AutocompleteList, + AutocompleteClear, + AutocompleteStatus, + AutocompleteRow, + AutocompleteCollection, +}; From 6ba11866c3193e739d20e49dd41d8e6075de64d8 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:36:06 +0100 Subject: [PATCH 030/100] =?UTF-8?q?feat(autocomplete):=20=E2=9C=A8=20add?= =?UTF-8?q?=20`AuthorAutocomplete`=20component=20and=20remove=20`AuthorCom?= =?UTF-8?q?bobox`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Introduced `AuthorAutocomplete` for improved author selection. * Replaced `AuthorCombobox` with `AuthorAutocomplete` in the route component. * Enhanced filtering and virtualized rendering for better performance. --- .../auto-completes/author.auto-complete.tsx | 162 ++++++++++++++++++ src/components/comboboxes/author.combobox.tsx | 126 -------------- src/routes/install-mods/$id.tsx | 5 +- 3 files changed, 165 insertions(+), 128 deletions(-) create mode 100644 src/components/auto-completes/author.auto-complete.tsx delete mode 100644 src/components/comboboxes/author.combobox.tsx diff --git a/src/components/auto-completes/author.auto-complete.tsx b/src/components/auto-completes/author.auto-complete.tsx new file mode 100644 index 0000000..b58879c --- /dev/null +++ b/src/components/auto-completes/author.auto-complete.tsx @@ -0,0 +1,162 @@ +import { Autocomplete as AutocompletePrimitive } from "@base-ui-components/react/autocomplete"; +import { useQueryClient } from "@tanstack/react-query"; +import { useVirtualizer } from "@tanstack/react-virtual"; +import { useCallback, useMemo, useRef, useState } from "react"; +import type { Mod } from "@/components/lists/mod.list"; +import { + Autocomplete, + AutocompleteInput, + AutocompleteItem, + AutocompleteList, + AutocompletePopup, +} from "@/components/ui/auto-complete"; +import { useModsFilters } from "@/stores/modsFilters"; + +export const AuthorAutocomplete = ( + props: React.InputHTMLAttributes, +) => { + const { contains } = AutocompletePrimitive.useFilter({ + sensitivity: "base", + usage: "search", + }); + const [internalValue, setInternalValue] = useState(""); + const actualValue = props.value || internalValue; + const { searchText, selectedGameVersions } = useModsFilters(); + const scrollElementRef = useRef(null); + + const handleValueChange = (value: string) => { + setInternalValue(value); + props.onChange?.({ + target: { value }, + } as React.ChangeEvent); + }; + + const queryClient = useQueryClient(); + const mods = queryClient.getQueryData([ + "mods", + { + search: searchText, + versions: selectedGameVersions, + }, + ]); + const modAuthors = useMemo( + () => + mods?.reduce( + (acc, mod) => { + // Extract unique authors with how many mods they have + if (mod.author) { + acc[mod.author] = (acc[mod.author] || 0) + 1; + } + return acc; + }, + {} as Record, + ), + [mods], + ); + + // biome-ignore lint/correctness/useExhaustiveDependencies: Shouldn't recompute on every function change + const filteredItems = useMemo(() => { + return modAuthors + ? Object.entries(modAuthors) + .filter(([author]) => contains(author, actualValue as string)) + .sort(([_authorA, countA], [_authorB, countB]) => countB - countA) + .map(([author]) => author) + : []; + }, [modAuthors, actualValue]); + + const shouldRenderPopup = actualValue !== ""; + + const virtualizer = useVirtualizer({ + count: filteredItems.length, + enabled: shouldRenderPopup, + estimateSize: () => 40, + getScrollElement: () => scrollElementRef.current, + overscan: 20, + }); + + const handleScrollElementRef = useCallback( + (element: HTMLDivElement) => { + scrollElementRef.current = element; + if (element) { + virtualizer.measure(); + } + }, + [virtualizer], + ); + + const totalSize = virtualizer.getTotalSize(); + const totalSizePx = `${totalSize}px`; + + return ( +
+ author as string} + onValueChange={handleValueChange} + value={actualValue as string} + virtualized + > + + {shouldRenderPopup && ( + + + {filteredItems.length > 0 && ( +
+
+ {virtualizer.getVirtualItems().map((virtualItem) => { + const author = filteredItems[virtualItem.index]; + if (!author) return null; + if (!modAuthors) return null; + const modCount = modAuthors[author]; + return ( + +
+
{author}
+
+ {modCount} mod{modCount > 1 ? "s" : ""} +
+
+
+ ); + })} +
+
+ )} +
+
+ )} +
+
+ ); +}; diff --git a/src/components/comboboxes/author.combobox.tsx b/src/components/comboboxes/author.combobox.tsx deleted file mode 100644 index 6cb3d67..0000000 --- a/src/components/comboboxes/author.combobox.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import { useQuery } from "@tanstack/react-query"; -import { invoke } from "@tauri-apps/api/core"; -import { clsx } from "clsx"; -import { CheckIcon, ChevronsUpDownIcon } from "lucide-react"; -import { useState } from "react"; -import { Button } from "@/components/ui/button"; -import { - Command, - CommandEmpty, - CommandInput, - CommandItem, - CommandList, - CommandLoading, -} from "@/components/ui/command"; -import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/components/ui/popover"; -import { cn } from "@/lib/utils"; - -type AuthorResponse = { - [key: string]: string; -}; - -const authorQuery = (search: string) => ({ - keepPreviousData: true, - queryFn: () => invoke("fetch_authors", { search }) as Promise, - queryKey: ["authors", search], - refetchOnWindowFocus: false, -}); - -export const AuthorCombobox = ( - props: React.InputHTMLAttributes, -) => { - const [open, setOpen] = useState(false); - const [internalValue, setInternalValue] = useState(""); - const [search, setSearch] = useState(""); - - const actualValue = props.value || internalValue; - - const handleValueChange = (value: string) => { - setInternalValue(value); - props.onChange?.({ - target: { value }, - } as React.ChangeEvent); - }; - - const { data: authors, isLoading } = useQuery( - authorQuery(search.toLowerCase()), - ); - - return ( - { - setOpen(v); - setSearch(""); - }} - open={open} - > - - - ) : ( - - )} - - - - - - - {authors && !isLoading && Object.entries(authors).length === 0 && ( - No authors found. - )} - {isLoading && Hang on…} - {authors && - Object.entries(authors).map(([key, value]) => ( - - v === actualValue - ? handleValueChange("") - : handleValueChange(value) - } - value={value} - > - {value} - {value === actualValue && ( -
- -
- )} -
- ))} -
-
-
-
- ); -}; diff --git a/src/routes/install-mods/$id.tsx b/src/routes/install-mods/$id.tsx index c609069..b84e726 100644 --- a/src/routes/install-mods/$id.tsx +++ b/src/routes/install-mods/$id.tsx @@ -2,8 +2,8 @@ import { useQuery } from "@tanstack/react-query"; import { createFileRoute } from "@tanstack/react-router"; import { ChevronDownIcon } from "lucide-react"; import { useRef } from "react"; +import { AuthorAutocomplete } from "@/components/auto-completes/author.auto-complete"; import { UpdateAllButton } from "@/components/buttons/update-all.button"; -import { AuthorCombobox } from "@/components/comboboxes/author.combobox"; import { SearchInput } from "@/components/inputs"; import { ModList } from "@/components/lists/mod.list"; import { TextSwitch } from "@/components/switches/text.switch"; @@ -119,6 +119,7 @@ function RouteComponent() { >
setSearchText(e.target.value)} placeholder="Search mods..." value={searchText} @@ -271,7 +272,7 @@ function RouteComponent() { textChecked="Asc" textUnchecked="Desc" /> - setAuthor(e.target.value)} value={author} /> From eb4b6034dd67ecc37c24496b4b413800ab469a2f Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:36:15 +0100 Subject: [PATCH 031/100] =?UTF-8?q?fix(button):=20=F0=9F=90=9B=20correct?= =?UTF-8?q?=20import=20path=20for=20`Button`=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated the import statement for the `Button` component to ensure proper functionality. * Removed the duplicate import to maintain code clarity. --- src/components/buttons/update-all.button.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/buttons/update-all.button.tsx b/src/components/buttons/update-all.button.tsx index 367b764..ef9286c 100644 --- a/src/components/buttons/update-all.button.tsx +++ b/src/components/buttons/update-all.button.tsx @@ -2,6 +2,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; import { invoke } from "@tauri-apps/api/core"; import { useState } from "react"; import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; import { useAddModUpdateToInstallation } from "@/hooks/use-add-mod-update-to-installation"; import { installedModsQueryKey } from "@/hooks/use-installed-mods"; import { @@ -11,7 +12,6 @@ import { } from "@/hooks/use-mod-updates"; import type { OutputMod } from "@/routes/install-mods/$id"; import type { Installation } from "@/stores/installations"; -import { Button } from "../ui/button"; export const UpdateAllButton = ({ installation, From 47eba2b47fab64444eba72049c12acd63421b2d5 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:36:35 +0100 Subject: [PATCH 032/100] =?UTF-8?q?refactor(installation.card):=20?= =?UTF-8?q?=E2=9C=A8=20reorganize=20imports=20for=20`InstallationCard`=20c?= =?UTF-8?q?omponent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated import paths for `Group` and `Tooltip` components to maintain consistency. * Removed redundant import statements to streamline the code. --- src/components/cards/installation.card.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/cards/installation.card.tsx b/src/components/cards/installation.card.tsx index 82595a3..f021392 100644 --- a/src/components/cards/installation.card.tsx +++ b/src/components/cards/installation.card.tsx @@ -7,12 +7,16 @@ import { Star, } from "lucide-react"; import { Button } from "@/components/ui/button"; +import { Group, GroupItem } from "@/components/ui/group"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; import { useDownloadVersion } from "@/hooks/use-download-version"; import { useInstalledVersions } from "@/hooks/use-installed-versions"; import { cn } from "@/lib/utils"; import type { Installation } from "@/stores/installations"; -import { Group, GroupItem } from "../ui/group"; -import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; interface InstallationCardProps { installation: Installation; From 65a45863c505211519aee1f28d56a7daea9263c5 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:36:45 +0100 Subject: [PATCH 033/100] =?UTF-8?q?refactor(server.card):=20=E2=9C=A8=20re?= =?UTF-8?q?organize=20import=20statements=20for=20`ServerCard`=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Consolidated import paths for `Group` and `Tooltip` components. * Improved code readability and maintainability. --- src/components/cards/server.card.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/cards/server.card.tsx b/src/components/cards/server.card.tsx index a7cdc5d..70d9e5c 100644 --- a/src/components/cards/server.card.tsx +++ b/src/components/cards/server.card.tsx @@ -1,13 +1,17 @@ import { DownloadCloudIcon, Lock, Pencil, Play, Star } from "lucide-react"; import { Button } from "@/components/ui/button"; +import { Group, GroupItem } from "@/components/ui/group"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; import { useDownloadVersion } from "@/hooks/use-download-version"; import { useInstalledVersions } from "@/hooks/use-installed-versions"; import { cn } from "@/lib/utils"; import { useInstallations } from "@/stores/installations"; import type { Server } from "@/stores/servers"; import { useSettingsStore } from "@/stores/settings"; -import { Group, GroupItem } from "../ui/group"; -import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; interface ServerCardProps { server: Server; From 96f2f60d96a357f590d6093fd0d1ccf41c8138c4 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:36:50 +0100 Subject: [PATCH 034/100] =?UTF-8?q?refactor(dialog.addinstallation):=20?= =?UTF-8?q?=E2=9C=A8=20update=20`TooltipTrigger`=20usage=20for=20improved?= =?UTF-8?q?=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactored `TooltipTrigger` components to use `render` prop for `Label` rendering. * Enhanced code clarity by reducing nesting and improving structure. --- .../dialogs/addinstallation.dialog.tsx | 148 ++++++++++-------- 1 file changed, 79 insertions(+), 69 deletions(-) diff --git a/src/components/dialogs/addinstallation.dialog.tsx b/src/components/dialogs/addinstallation.dialog.tsx index c3b8991..24c6f0d 100644 --- a/src/components/dialogs/addinstallation.dialog.tsx +++ b/src/components/dialogs/addinstallation.dialog.tsx @@ -168,19 +168,21 @@ export function AddInstallationDialog({ {(field) => (
- - + + } + > + Name + *

Enter server name

@@ -232,21 +234,23 @@ export function AddInstallationDialog({
- - + + } + > + Start parameters + + (optional) +

Enter start parameters

@@ -281,19 +285,21 @@ export function AddInstallationDialog({ {(field) => (
- - + + } + > + Path + *

Enter installation path

@@ -323,21 +329,23 @@ export function AddInstallationDialog({ {(field) => (
- - + + } + > + Icon + + (optional) +

Enter installation icon

@@ -373,19 +381,21 @@ export function AddInstallationDialog({ {(field) => (
- - + + } + > + Version + *

Pick game version

From 2aa2718e09d6099eb5730f4cc7af6fa11caa60b5 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:36:55 +0100 Subject: [PATCH 035/100] =?UTF-8?q?refactor(dialog.addserver):=20=E2=9C=A8?= =?UTF-8?q?=20update=20`TooltipTrigger`=20usage=20for=20improved=20structu?= =?UTF-8?q?re?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactored `TooltipTrigger` components to use `render` prop for better readability. * Enhanced the organization of label elements within tooltips for clarity. --- src/components/dialogs/addserver.dialog.tsx | 144 +++++++++++--------- 1 file changed, 77 insertions(+), 67 deletions(-) diff --git a/src/components/dialogs/addserver.dialog.tsx b/src/components/dialogs/addserver.dialog.tsx index 61c7d17..db41b09 100644 --- a/src/components/dialogs/addserver.dialog.tsx +++ b/src/components/dialogs/addserver.dialog.tsx @@ -137,19 +137,21 @@ export function AddServerDialog({ {(field) => (
- - + + } + > + Name + *

Enter server name

@@ -186,21 +188,23 @@ export function AddServerDialog({
- - + + } + > + Password + + (optional) +

Enter password

@@ -236,19 +240,21 @@ export function AddServerDialog({ {(field) => (
- - + + } + > + IP Address + *

Enter server IP address

@@ -284,19 +290,21 @@ export function AddServerDialog({ {(field) => (
- - + + } + > + Port + *

Enter server port

@@ -344,19 +352,21 @@ export function AddServerDialog({ {(field) => (
- - + + } + > + Installation + *

Pick game installation

From 20c4a690ca890ce7712e6505de6904e93189d9bf Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:37:01 +0100 Subject: [PATCH 036/100] =?UTF-8?q?refactor(dialog.adduser):=20=E2=9C=A8?= =?UTF-8?q?=20update=20`TooltipTrigger`=20usage=20for=20improved=20structu?= =?UTF-8?q?re?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactored `TooltipTrigger` to use `render` prop for better readability. * Enhanced the structure of the `AddUserDialog` component. --- src/components/dialogs/adduser.dialog.tsx | 56 ++++++++++++----------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/components/dialogs/adduser.dialog.tsx b/src/components/dialogs/adduser.dialog.tsx index 5931b0d..431f51d 100644 --- a/src/components/dialogs/adduser.dialog.tsx +++ b/src/components/dialogs/adduser.dialog.tsx @@ -168,19 +168,21 @@ export function AddUserDialog({ open }: { open: boolean }) { {(field) => (
- - + + } + > + Email + *

Enter email address

@@ -228,19 +230,21 @@ export function AddUserDialog({ open }: { open: boolean }) {
- - + + } + > + Password + *

Enter password

From 932b9771798dafe0e944b7f878311c0a0ede16d0 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:37:07 +0100 Subject: [PATCH 037/100] =?UTF-8?q?refactor(dialog.addversion):=20?= =?UTF-8?q?=E2=9C=A8=20update=20`TooltipTrigger`=20usage=20for=20improved?= =?UTF-8?q?=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactored the `TooltipTrigger` component to use the `render` prop for better readability and maintainability. * Enhanced the structure of the label within the tooltip for clearer error handling. --- src/components/dialogs/addversion.dialog.tsx | 28 +++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/components/dialogs/addversion.dialog.tsx b/src/components/dialogs/addversion.dialog.tsx index c14827d..ea8e4a0 100644 --- a/src/components/dialogs/addversion.dialog.tsx +++ b/src/components/dialogs/addversion.dialog.tsx @@ -104,19 +104,21 @@ export function AddVersionDialog({ open }: { open: boolean }) { {(field) => (
- - + + } + > + Version + *

Pick game version

From ac0639034e53b11f74053673b4434d016d1db4c8 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:37:16 +0100 Subject: [PATCH 038/100] =?UTF-8?q?refactor(dialog.connectserver):=20?= =?UTF-8?q?=E2=9C=A8=20update=20import=20statements=20for=20improved=20str?= =?UTF-8?q?ucture?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Organized imports for `ConnectServerDialog` component. * Enhanced readability by consolidating import paths. --- src/components/dialogs/connectserver.dialog.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/dialogs/connectserver.dialog.tsx b/src/components/dialogs/connectserver.dialog.tsx index f456499..6b73a70 100644 --- a/src/components/dialogs/connectserver.dialog.tsx +++ b/src/components/dialogs/connectserver.dialog.tsx @@ -1,4 +1,5 @@ import { useState } from "react"; +import { PasswordInput } from "@/components/inputs"; import { AlertDialog, AlertDialogContent, @@ -7,13 +8,17 @@ import { AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; +import { Button } from "@/components/ui/button"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, +} from "@/components/ui/select"; import { useConnectToServer } from "@/hooks/use-connect-to-server"; import type { PublicServer } from "@/hooks/use-public-servers"; import { useDialogStore } from "@/stores/dialogs"; import { useInstallations } from "@/stores/installations"; -import { PasswordInput } from "../inputs"; -import { Button } from "../ui/button"; -import { Select, SelectContent, SelectItem, SelectTrigger } from "../ui/select"; export type ConnectServerDialogProps = { server: PublicServer; From 6c31bbeb20b849dd92bf88f3461fceaccc975f0c Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:37:21 +0100 Subject: [PATCH 039/100] =?UTF-8?q?refactor(dialog.deleteinstallation):=20?= =?UTF-8?q?=E2=9C=A8=20update=20`AlertDialogClose`=20usage=20for=20improve?= =?UTF-8?q?d=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Replaced the direct `Button` usage with `AlertDialogClose` for better encapsulation. * Enhanced the dialog's close functionality while maintaining the disabled state during pending operations. --- src/components/dialogs/deleteinstallation.dialog.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/dialogs/deleteinstallation.dialog.tsx b/src/components/dialogs/deleteinstallation.dialog.tsx index 72449bf..d9ba0d4 100644 --- a/src/components/dialogs/deleteinstallation.dialog.tsx +++ b/src/components/dialogs/deleteinstallation.dialog.tsx @@ -5,17 +5,18 @@ import { MapIcon, MapPinXIcon } from "lucide-react"; import { toast } from "sonner"; import { AlertDialog, + AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; +import { Button } from "@/components/ui/button"; import { useSavesFromInstallation } from "@/hooks/use-saves"; import { useDialogStore } from "@/stores/dialogs"; import { type Installation, useInstallations } from "@/stores/installations"; import { useServerStore } from "@/stores/servers"; -import { Button } from "../ui/button"; export type DeleteInstallationDialogProps = { installation: Installation; @@ -145,9 +146,12 @@ export function DeleteInstallationDialog({ )} - + + From 06db8b5ed31cc2c9de94b2b916bf6310ce069b0a Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:37:42 +0100 Subject: [PATCH 041/100] =?UTF-8?q?refactor(dialog.deleteversion):=20?= =?UTF-8?q?=E2=9C=A8=20update=20`AlertDialogClose`=20usage=20for=20improve?= =?UTF-8?q?d=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Replaced the direct `Button` usage with `AlertDialogClose` for better dialog management. * Enhanced the structure and readability of the `DeleteVersionDialog` component. --- src/components/dialogs/deleteversion.dialog.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/dialogs/deleteversion.dialog.tsx b/src/components/dialogs/deleteversion.dialog.tsx index 4cd4bdb..7e61270 100644 --- a/src/components/dialogs/deleteversion.dialog.tsx +++ b/src/components/dialogs/deleteversion.dialog.tsx @@ -4,15 +4,16 @@ import { motion } from "framer-motion"; import { toast } from "sonner"; import { AlertDialog, + AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; +import { Button } from "@/components/ui/button"; import { installedVersionsQueryKey } from "@/hooks/use-installed-versions"; import { useDialogStore } from "@/stores/dialogs"; -import { Button } from "../ui/button"; export type DeleteVersionDialogProps = { version: string; @@ -83,9 +84,12 @@ export function DeleteVersionDialog({ - + From 67558edc1b1ca71ec3fbe0321872ebf655871da9 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:37:50 +0100 Subject: [PATCH 042/100] =?UTF-8?q?refactor(dialog.deleteworld):=20?= =?UTF-8?q?=E2=9C=A8=20update=20`AlertDialogClose`=20usage=20for=20improve?= =?UTF-8?q?d=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Replaced the `Button` component with `AlertDialogClose` for better dialog management. * Enhanced the structure and readability of the `DeleteWorldDialog` component. --- src/components/dialogs/deleteworld.dialog.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/dialogs/deleteworld.dialog.tsx b/src/components/dialogs/deleteworld.dialog.tsx index 0327726..fa6277f 100644 --- a/src/components/dialogs/deleteworld.dialog.tsx +++ b/src/components/dialogs/deleteworld.dialog.tsx @@ -6,16 +6,17 @@ import { useId, useState } from "react"; import { toast } from "sonner"; import { AlertDialog, + AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; +import { Button } from "@/components/ui/button"; +import { Checkbox } from "@/components/ui/checkbox"; import type { World } from "@/lib/types"; import { useDialogStore } from "@/stores/dialogs"; -import { Button } from "../ui/button"; -import { Checkbox } from "../ui/checkbox"; export type DeleteWorldDialogProps = { world: World; @@ -151,9 +152,12 @@ export function DeleteWorldDialog({ - + + + } + > +
Connect to {server?.serverName} @@ -207,20 +213,22 @@ export function PublicServerList({ (i) => i.version === server.gameVersion, ) ? ( - - + } + > + Download {server?.gameVersion} @@ -228,24 +236,26 @@ export function PublicServerList({ ) : ( - - + } + > + Add installation for {server?.gameVersion} From b97f28061c84353a79620e9df9eda66978c42c4c Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:40:32 +0100 Subject: [PATCH 057/100] =?UTF-8?q?refactor(installation.row):=20=E2=9C=A8?= =?UTF-8?q?=20reorganize=20import=20statements=20for=20`Group`,=20`GroupIt?= =?UTF-8?q?em`,=20and=20`GroupSeparator`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Removed duplicate import of `Group`, `GroupItem`, and `GroupSeparator`. * Updated import path for better structure and clarity. --- src/components/rows/installation.row.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/rows/installation.row.tsx b/src/components/rows/installation.row.tsx index 0b50e18..d604bff 100644 --- a/src/components/rows/installation.row.tsx +++ b/src/components/rows/installation.row.tsx @@ -12,6 +12,7 @@ import { TrashIcon, } from "lucide-react"; import { Button } from "@/components/ui/button"; +import { Group, GroupItem, GroupSeparator } from "@/components/ui/group"; import { Tooltip, TooltipContent, @@ -24,7 +25,6 @@ import { useRevealInFolder } from "@/hooks/use-reveal-in-folder"; import { cn, exportInstallation } from "@/lib/utils"; import { useDialogStore } from "@/stores/dialogs"; import { type Installation, useInstallations } from "@/stores/installations"; -import { Group, GroupItem, GroupSeparator } from "../ui/group"; export type InstallationRowProps = { installation: Installation; From 4f1df7f79744d1e81a67d9a083a4275225724f3a Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:40:56 +0100 Subject: [PATCH 058/100] =?UTF-8?q?refactor(server.row):=20=E2=9C=A8=20reo?= =?UTF-8?q?rganize=20import=20statements=20for=20`Group`,=20`GroupItem`,?= =?UTF-8?q?=20and=20`GroupSeparator`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Removed redundant import path for `Group`, `GroupItem`, and `GroupSeparator`. * Improved code clarity and structure by consolidating imports. --- src/components/rows/server.row.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/rows/server.row.tsx b/src/components/rows/server.row.tsx index a0437fa..34876e2 100644 --- a/src/components/rows/server.row.tsx +++ b/src/components/rows/server.row.tsx @@ -6,6 +6,7 @@ import { TrashIcon, } from "lucide-react"; import { Button } from "@/components/ui/button"; +import { Group, GroupItem, GroupSeparator } from "@/components/ui/group"; import { Tooltip, TooltipContent, @@ -19,7 +20,6 @@ import { useDialogStore } from "@/stores/dialogs"; import { useInstallations } from "@/stores/installations"; import { type Server, useServerStore } from "@/stores/servers"; import { useSettingsStore } from "@/stores/settings"; -import { Group, GroupItem, GroupSeparator } from "../ui/group"; type ServerRowProps = { server: Server; From 465d3b08f87951a1c32410996f6c278ee9dbf1f7 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:41:04 +0100 Subject: [PATCH 059/100] =?UTF-8?q?refactor(version.row):=20=E2=9C=A8=20re?= =?UTF-8?q?organize=20import=20statement=20for=20`Group`,=20`GroupItem`,?= =?UTF-8?q?=20and=20`GroupSeparator`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated import path for `Group`, `GroupItem`, and `GroupSeparator` to maintain consistency across components. --- src/components/rows/version.row.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/rows/version.row.tsx b/src/components/rows/version.row.tsx index 7627e68..db6e174 100644 --- a/src/components/rows/version.row.tsx +++ b/src/components/rows/version.row.tsx @@ -1,5 +1,6 @@ import { FolderOpenIcon, TrashIcon } from "lucide-react"; import { Button } from "@/components/ui/button"; +import { Group, GroupItem, GroupSeparator } from "@/components/ui/group"; import { Tooltip, TooltipContent, @@ -10,7 +11,6 @@ import { useRevealInFolder } from "@/hooks/use-reveal-in-folder"; import { pathDelimiter } from "@/lib/utils"; import { useDialogStore } from "@/stores/dialogs"; import { useSettingsStore } from "@/stores/settings"; -import { Group, GroupItem, GroupSeparator } from "../ui/group"; export function VersionRow({ version }: { version: string }) { const { appFolder } = useAppFolder(); From 9f92b2d4b8329ac89dcdcc3ac4aef63177b9f601 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:41:10 +0100 Subject: [PATCH 060/100] =?UTF-8?q?refactor(app.sidebar):=20=E2=9C=A8=20re?= =?UTF-8?q?organize=20import=20statements=20and=20update=20`TooltipTrigger?= =?UTF-8?q?`=20usage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Consolidated import statements for `DropdownMenu` and `Tooltip`. * Updated `TooltipTrigger` to use the `render` prop for better structure. * Improved readability and maintainability of the `AppSidebar` component. --- src/components/sidebars/app.sidebar.tsx | 86 ++++++++++++++----------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/src/components/sidebars/app.sidebar.tsx b/src/components/sidebars/app.sidebar.tsx index 5ee8f62..7942285 100644 --- a/src/components/sidebars/app.sidebar.tsx +++ b/src/components/sidebars/app.sidebar.tsx @@ -16,6 +16,11 @@ import { import { toast } from "sonner"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; import { Sidebar, SidebarContent, @@ -30,18 +35,17 @@ import { SidebarMenuSubButton, SidebarMenuSubItem, } from "@/components/ui/sidebar"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; import { useInstalledVersions } from "@/hooks/use-installed-versions"; import { useVerifyAuth } from "@/hooks/use-verify-auth"; import { useAccountStore } from "@/stores/accounts"; import { useDialogStore } from "@/stores/dialogs"; import { useInstallations } from "@/stores/installations"; import { useServerStore } from "@/stores/servers"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuTrigger, -} from "../ui/dropdown-menu"; -import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; export function AppSidebar() { const { selectedUser, users, removeUser, setSelectedUser } = @@ -132,50 +136,54 @@ export function AppSidebar() { )} - - + }} + onKeyUp={(e) => { + if (e.key === "Enter") { + verifyAuth({ + sessionkey: user.sessionkey || "", + uid: user.uid || "", + }); + } + }} + size="icon" + variant="outline" + /> + } + > + Verify {user.playername}'s auth - - + }} + onKeyUp={(e) => { + if (e.key === "Enter") { + removeUser(user.uid); + } + }} + size="icon" + variant="outline" + /> + } + > + Remove {user.playername} From 58fcb012bf8f7fa79ce27fb90d7e6e32e1efafc4 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:41:25 +0100 Subject: [PATCH 061/100] =?UTF-8?q?refactor(side.tab):=20=E2=9C=A8=20updat?= =?UTF-8?q?e=20import=20statement=20for=20`Tabs`,=20`TabsList`,=20and=20`T?= =?UTF-8?q?absTab`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Changed import path for `Tabs`, `TabsList`, and `TabsTab` to use absolute path. * Improves consistency and maintainability of the codebase. --- src/components/tabs/side.tab.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/tabs/side.tab.tsx b/src/components/tabs/side.tab.tsx index 3522732..1b1b06d 100644 --- a/src/components/tabs/side.tab.tsx +++ b/src/components/tabs/side.tab.tsx @@ -1,5 +1,5 @@ +import { Tabs, TabsList, TabsTab } from "@/components/ui/tabs"; import { useModsFilters } from "@/stores/modsFilters"; -import { Tabs, TabsList, TabsTab } from "../ui/tabs"; export default function SideToggleGroup() { const { side, setSide } = useModsFilters(); From 0ffa42abc86b64a2f5682865866209881b8dbadf Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:41:34 +0100 Subject: [PATCH 062/100] =?UTF-8?q?refactor(installations.row):=20?= =?UTF-8?q?=E2=9C=A8=20update=20`TooltipTrigger`=20usage=20for=20improved?= =?UTF-8?q?=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Changed `TooltipTrigger` to use `render` prop instead of `asChild`. * This enhances the clarity of the component structure. --- src/routes/installations.tsx | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/routes/installations.tsx b/src/routes/installations.tsx index 3a6121c..f68cfe0 100644 --- a/src/routes/installations.tsx +++ b/src/routes/installations.tsx @@ -36,16 +36,18 @@ function RouteComponent() { - - + openDialog("ImportInstallationDialog")} + size="icon" + variant="outline" + /> + } + > + Import Installation From f71b663909b49b4b78bd895be69484c1d7dc3244 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:41:40 +0100 Subject: [PATCH 063/100] =?UTF-8?q?refactor(settings.row):=20=E2=9C=A8=20u?= =?UTF-8?q?pdate=20`TooltipTrigger`=20usage=20for=20improved=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactored `TooltipTrigger` to use `render` prop for better readability. * Enhanced the organization of the label components within the tooltip. --- src/routes/settings.tsx | 60 ++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/src/routes/settings.tsx b/src/routes/settings.tsx index 412111d..b6ed672 100644 --- a/src/routes/settings.tsx +++ b/src/routes/settings.tsx @@ -320,20 +320,22 @@ function RouteComponent() { {(field) => (
- - + + } + > + Installations Parent Directory

Defaults to the app data directory

@@ -375,20 +377,22 @@ function RouteComponent() { {(field) => (
- - + + } + > + Versions Parent Directory

Defaults to the app data directory

From cc92c235d4a28dca9aaea283e2a1bc18ff1bbc31 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 10:52:30 +0100 Subject: [PATCH 064/100] =?UTF-8?q?refactor(app.sidebar):=20=E2=9C=A8=20up?= =?UTF-8?q?date=20`DropdownMenu`=20items=20to=20use=20`Group`=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Replaced `div` elements with `Group` and `GroupItem` for better structure. * Improved readability and maintainability of the `DropdownMenu` content. * Added `GroupSeparator` for visual clarity between items. --- bun.lock | 3 - package.json | 1 - src/components/sidebars/app.sidebar.tsx | 115 +++++++++++++----------- 3 files changed, 65 insertions(+), 54 deletions(-) diff --git a/bun.lock b/bun.lock index be43c5c..736b31a 100644 --- a/bun.lock +++ b/bun.lock @@ -16,7 +16,6 @@ "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "^1.2.3", - "@radix-ui/react-tabs": "^1.1.13", "@tailwindcss/vite": "^4.1.16", "@tanstack/react-devtools": "^0.7.8", "@tanstack/react-form": "^1.23.8", @@ -285,8 +284,6 @@ "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="], - "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], diff --git a/package.json b/package.json index c468293..c413077 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "^1.2.3", - "@radix-ui/react-tabs": "^1.1.13", "@tailwindcss/vite": "^4.1.16", "@tanstack/react-devtools": "^0.7.8", "@tanstack/react-form": "^1.23.8", diff --git a/src/components/sidebars/app.sidebar.tsx b/src/components/sidebars/app.sidebar.tsx index 7942285..3b72f61 100644 --- a/src/components/sidebars/app.sidebar.tsx +++ b/src/components/sidebars/app.sidebar.tsx @@ -21,6 +21,7 @@ import { DropdownMenuContent, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import { Group, GroupItem, GroupSeparator } from "@/components/ui/group"; import { Sidebar, SidebarContent, @@ -112,17 +113,21 @@ export function AppSidebar() { {users.map((user) => ( -
- + + { - verifyAuth({ - sessionkey: user.sessionkey || "", - uid: user.uid || "", - }); - }} - onKeyUp={(e) => { - if (e.key === "Enter") { - verifyAuth({ - sessionkey: user.sessionkey || "", - uid: user.uid || "", - }); - } - }} - size="icon" - variant="outline" - /> + { + verifyAuth({ + sessionkey: user.sessionkey || "", + uid: user.uid || "", + }); + }} + onKeyUp={(e) => { + if (e.key === "Enter") { + verifyAuth({ + sessionkey: user.sessionkey || "", + uid: user.uid || "", + }); + } + }} + size="icon" + variant="outline" + /> + } + > + + } - > - - + /> Verify {user.playername}'s auth + { - removeUser(user.uid); - }} - onKeyUp={(e) => { - if (e.key === "Enter") { - removeUser(user.uid); - } - }} - size="icon" - variant="outline" - /> + { + removeUser(user.uid); + }} + onKeyUp={(e) => { + if (e.key === "Enter") { + removeUser(user.uid); + } + }} + size="icon" + variant="destructive-outline" + /> + } + > + + } - > - - + /> Remove {user.playername} -
+ ))}
{filteredWorlds && (
From 8881ad801402c47a5466907f714867217dd35f62 Mon Sep 17 00:00:00 2001 From: Mike Kold Hermann Date: Tue, 28 Oct 2025 13:17:12 +0100 Subject: [PATCH 071/100] =?UTF-8?q?refactor(install-mods):=20=E2=9C=A8=20r?= =?UTF-8?q?eplace=20`DropdownMenu`=20with=20`Select`=20for=20game=20versio?= =?UTF-8?q?n=20and=20mod=20tag=20selection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improved UI consistency by using `Select` components instead of `DropdownMenu`. * Enhanced user experience with better handling of multiple selections for game versions and mod tags. --- src/routes/install-mods/$id.tsx | 116 +++++++++++++------------------- 1 file changed, 45 insertions(+), 71 deletions(-) diff --git a/src/routes/install-mods/$id.tsx b/src/routes/install-mods/$id.tsx index b84e726..68572ea 100644 --- a/src/routes/install-mods/$id.tsx +++ b/src/routes/install-mods/$id.tsx @@ -1,6 +1,5 @@ import { useQuery } from "@tanstack/react-query"; import { createFileRoute } from "@tanstack/react-router"; -import { ChevronDownIcon } from "lucide-react"; import { useRef } from "react"; import { AuthorAutocomplete } from "@/components/auto-completes/author.auto-complete"; import { UpdateAllButton } from "@/components/buttons/update-all.button"; @@ -8,12 +7,6 @@ import { SearchInput } from "@/components/inputs"; import { ModList } from "@/components/lists/mod.list"; import { TextSwitch } from "@/components/switches/text.switch"; import SideToggleGroup from "@/components/tabs/side.tab"; -import { - DropdownMenu, - DropdownMenuCheckboxItem, - DropdownMenuContent, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; import { ErrorComponent } from "@/components/ui/error"; import { Label } from "@/components/ui/label"; import { @@ -21,6 +14,7 @@ import { SelectContent, SelectItem, SelectTrigger, + SelectValue, } from "@/components/ui/select"; import { useInstalledMods } from "@/hooks/use-installed-mods"; import { useModUpdates } from "@/hooks/use-mod-updates"; @@ -124,15 +118,8 @@ function RouteComponent() { placeholder="Search mods..." value={searchText} /> - - 0 - ? "text-foreground" - : "text-transparent", - )} - > + +