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
+
+ {
if (selectedInstallation === null) return;
@@ -93,7 +94,7 @@ export function ConnectServerDialog({
}}
>
Connect
-
+
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
+
+ deleteInstallation(installation.id)}
>
{isPending ? "Deleting..." : "Delete"}
-
+
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
+
+
mutate({
installationId: server.installationId,
@@ -60,7 +61,7 @@ export function DeleteServerDialog({
}
>
Delete
-
+
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)}
- >
+ closeDialog()} variant="outline">
+ Cancel
+
+ removeVersion(version)}>
{isPending ? "Deleting..." : "Delete"}
-
+
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
+
+ removeWorld(world)}
>
{isPending ? "Deleting..." : "Delete"}
-
+
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
+
+
removeModFromInstallation({
@@ -94,7 +95,7 @@ export function RemoveModDialog({
}
>
Remove
-
+
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}
-
-
+ onPlay(installation)}
+ size="icon"
+ variant="ghost"
+ />
+ }
+ >
+
+ Play {installation.name}
+
+ }
+ />
Play {installation.name}
>
) : (
<>
-
- installVersion(installation.version)}
- size="icon"
- variant="ghost"
- >
-
-
- Download version {installation.version}
-
-
-
+ 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}
-
-
+ onAddMods(installation)}
+ size="icon"
+ variant="ghost"
+ />
+ }
+ >
+
+ Add mods to {installation.name}
+
+ }
+ />
Add mods
-
- onEdit(installation)}
- size="icon"
- variant="ghost"
- >
-
- Edit {installation.name}
-
-
+ onEdit(installation)}
+ size="icon"
+ variant="ghost"
+ />
+ }
+ >
+
+ Edit {installation.name}
+
+ }
+ />
Edit {installation.name}
-
- onUnfavorite(installation)}
- size="icon"
- variant="ghost"
- >
-
-
- {installation.favorite ? "Unfavorite" : "Favorite"}{" "}
- {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) ? (
- <>
-
- onConnect(server)}
- size="icon"
- variant="ghost"
- >
-
- Play {server.name}
-
-
- Connect to {server.name}
- >
- ) : (
- <>
-
- installVersion(installation.version)}
- size="icon"
- variant="ghost"
- >
-
-
- Download version {installation.version}
-
-
-
-
- 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}
-
-
+ onEdit(server)}
+ size="icon"
+ variant="ghost"
+ />
+ }
+ >
+
+ Edit {server.name}
+
+ }
+ />
Edit {server.name}
-
- onUnfavorite(server)}
- size="icon"
- variant="ghost"
- >
-
-
- {server.favorite ? "Unfavorite" : "Favorite"} {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"
- >
-
-
-
+
+ removeModFromInstallation({
+ modpath: installedMod?.path ?? "",
+ path: installation.path,
+ })
+ }
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
{installedMod.version} → {updateMod.modversion ?? "Unknown"}
@@ -237,95 +249,134 @@ export function ModItem({
Install latest version
+
)}
{!installedMod && installation && (
-
-
- downloadLatestModVersion({
- path: `${installation.path}${pathDelimiter}Mods`,
- })
- }
- size="icon"
- variant="outline"
- >
-
-
-
+
+ downloadLatestModVersion({
+ path: `${installation.path}${pathDelimiter}Mods`,
+ })
+ }
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Install latest version
+
)}
{installation && installedMod && (
-
-
- openDialog("UpdateModDialog", {
- installation,
- mod: installedMod,
- versionFrom: installedMod.version,
- })
- }
- size="icon"
- variant="outline"
- >
-
-
-
+
+ openDialog("UpdateModDialog", {
+ installation,
+ mod: installedMod,
+ versionFrom: installedMod.version,
+ })
+ }
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Look through available versions
+
)}
{installation &&
(installedMod ? (
-
-
- openDialog("RemoveModDialog", {
- installation,
- name: mod.name,
- path: installedMod.path ?? "",
- })
- }
- size="icon"
- variant="destructive"
- >
-
-
-
+
+ openDialog("RemoveModDialog", {
+ installation,
+ name: mod.name,
+ path: installedMod.path ?? "",
+ })
+ }
+ size="icon"
+ variant="destructive-outline"
+ />
+ }
+ >
+
+
+ }
+ />
Remove
) : (
-
-
- openDialog("AddModDialog", {
- installation,
- modid: mod.modid,
- })
- }
- size="icon"
- variant="outline"
- >
-
-
-
+
+ openDialog("AddModDialog", {
+ installation,
+ modid: mod.modid,
+ })
+ }
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Add Mod
))}
-
+
);
}
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"
- >
-
-
-
+ openDialog("DeleteVersionDialog", { version })}
+ size="icon"
+ variant="outline"
+ >
+
+
+ }
+ />
Delete
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 ? (
- {
- invoke("play_game", {
- options: {
- installation_id: installation.id,
- save: world.path.split("/").pop()?.replace(".vcdbs", ""),
- },
- });
- toast.success(
- `Launching ${installation.name} on ${worldData.world_name}...`,
- );
- }}
- variant="outline"
+ {
+ if (version) {
+ invoke("play_game", {
+ options: {
+ installation_id: installation.id,
+ save: world.path
+ .split("/")
+ .pop()
+ ?.replace(".vcdbs", ""),
+ },
+ });
+ toast.success(
+ `Launching ${installation.name} on ${worldData.world_name}...`,
+ );
+ } else {
+ installVersion(installation.version);
+ }
+ }}
+ variant="outline"
+ />
+ }
>
-
-
- ) : (
- installVersion(installation.version)}
- variant="outline"
- >
-
-
- )}
-
+ {version ? (
+
+ ) : (
+
+ )}
+
+ }
+ />
{version ? "Play" : `Install ${installation.version}`}
- {world.has_map ? (
-
-
- openDialog("ViewMapDialog", { world })}
- variant="outline"
+
+ openDialog("ViewMapDialog", { world })}
+ variant="outline"
+ />
+ }
>
-
-
- View Map
-
- ) : (
-
-
-
+ }
+ />
+
+ {world.has_map
+ ? "View Map"
+ : `No Map Available for ${worldData.world_name}`}
+
+
+
+ openDialog("EditWorldDialog", { world })}
+ variant="outline"
+ />
+ }
>
-
-
-
-
- No map available for {worldData.world_name}
-
-
- )}
-
-
- openDialog("EditWorldDialog", { world })}
- variant="outline"
- >
-
-
-
+
+ }
+ />
Edit
+
-
- openDialog("DeleteWorldDialog", { world })}
- size="icon"
- variant="outline"
- >
-
-
-
+ openDialog("DeleteWorldDialog", { world })}
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Delete
-
+
);
};
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 ? (
-
- playWithInstallation({
- id: installation.id,
- })
+
+ version
+ ? playWithInstallation({
+ id: installation.id,
+ })
+ : downloadVersion(installation.version)
+ }
+ size="icon"
+ variant="outline"
+ />
}
- variant="outline"
>
-
-
- ) : (
- downloadVersion(installation.version)}
- variant="outline"
- >
-
-
- )}
-
+ {version ? (
+
+ ) : (
+
+ )}
+
+ }
+ />
{version ? "Launch" : `Download ${installation.version}`}
+
-
- toggleFavorite(installation.id)}
- variant="outline"
- >
-
-
-
+ toggleFavorite(installation.id)}
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
{installation.favorite ? "Unfavorite" : "Favorite"}
+
-
-
- router.navigate({
- params: { id: installation.id.toString() },
- to: "/install-mods/$id",
- viewTransition: {
- types: ["warp"],
- },
- })
- }
- variant="outline"
- >
-
-
-
+
+ router.navigate({
+ params: { id: installation.id.toString() },
+ to: "/install-mods/$id",
+ viewTransition: {
+ types: ["warp"],
+ },
+ })
+ }
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Manage Mods
+
-
-
- router.navigate({
- params: { id: installation.id.toString() },
- to: "/mod-configs/$id",
- viewTransition: {
- types: ["warp"],
- },
- })
- }
- variant="outline"
- >
-
-
-
+
+ router.navigate({
+ params: { id: installation.id.toString() },
+ to: "/mod-configs/$id",
+ viewTransition: {
+ types: ["warp"],
+ },
+ })
+ }
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Configure Mods
+
-
- openFolder(installation.path)}
- size="icon"
- variant="outline"
- >
-
-
-
+ openFolder(installation.path)}
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Open Folder
+
-
- exportInstallation({ installation })}
- variant="outline"
- >
-
-
-
+ exportInstallation({ installation })}
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Export
+
-
-
- openDialog("EditInstallationDialog", { installation })
- }
- variant="outline"
- >
-
-
-
+
+ openDialog("EditInstallationDialog", { installation })
+ }
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Edit
+
-
-
- openDialog("DeleteInstallationDialog", { installation })
- }
- size="icon"
- variant="outline"
- >
-
-
-
+
+ openDialog("DeleteInstallationDialog", { installation })
+ }
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Delete
-
+
>
);
}
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 ?? "") ? (
-
- connectToServer({
- installationId: server.installationId,
- ip: `${server.ip}${server.port ? `:${server.port}` : ""}`,
- name: server.name,
- password: server.password,
- })
+
+ versions?.includes(installation?.version ?? "")
+ ? connectToServer({
+ installationId: server.installationId,
+ ip: `${server.ip}${server.port ? `:${server.port}` : ""}`,
+ name: server.name,
+ password: server.password,
+ })
+ : installVersion(installation?.version ?? "")
+ }
+ variant="outline"
+ />
}
- variant="outline"
>
-
-
- ) : (
- installVersion(installation?.version ?? "")}
- variant="outline"
- >
-
-
- )}
-
+ {versions?.includes(installation?.version ?? "") ? (
+
+ ) : (
+
+ )}
+
+ }
+ />
{versions?.includes(installation?.version ?? "")
? "Connect"
: `Install ${installation?.version ?? ""}`}
+
-
- toggleFavorite(server.id)}
- variant="outline"
- >
-
-
-
+ toggleFavorite(server.id)}
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
{server.favorite ? "Unfavorite" : "Favorite"}
+
-
- openDialog("EditServerDialog", { server })}
- variant="outline"
- >
-
-
-
+ openDialog("EditServerDialog", { server })}
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Edit
+
-
- openDialog("DeleteServerDialog", { server })}
- size="icon"
- variant="outline"
- >
-
-
-
+ openDialog("DeleteServerDialog", { server })}
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Delete
-
+
);
}
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"
- >
-
-
-
+
+ openFolder(
+ `${versionsParent ?? appFolder}${pathDelimiter}${versionsSubdir}${pathDelimiter}${version}`,
+ )
+ }
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Open Folder
+
-
- openDialog("DeleteVersionDialog", { version })}
- size="icon"
- variant="outline"
- >
-
-
-
+
+ openDialog("DeleteVersionDialog", { version })
+ }
+ size="icon"
+ variant="outline"
+ />
+ }
+ >
+
+
+ }
+ />
Delete
-
+
>
);
}
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() {
>
-
- ← Back to Installations
+ }
+ >
+ ← Back to Installations
{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 (
+
+
+ {label}
+
+
+
+
+
+ );
+}
+
+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() {
-
+
removeArrayItem(path, idx)}
size="sm"
- variant="destructive"
+ variant="destructive-outline"
>
Remove
@@ -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}
- >
-
-
-
- Author
-
- {actualValue ? actualValue : "Select author..."}
-
- {actualValue ? (
- handleValueChange("")}
- size="xs"
- variant="ghost"
- >
- x
-
- ) : (
-
- )}
-
-
-
-
-
-
- {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
- *
-
+
+ }
+ >
+ Name
+ *
Enter server name
@@ -232,21 +234,23 @@ export function AddInstallationDialog({
-
-
- Start parameters
-
- (optional)
-
-
+
+ }
+ >
+ Start parameters
+
+ (optional)
+
Enter start parameters
@@ -281,19 +285,21 @@ export function AddInstallationDialog({
{(field) => (
-
-
- Path
- *
-
+
+ }
+ >
+ Path
+ *
Enter installation path
@@ -323,21 +329,23 @@ export function AddInstallationDialog({
{(field) => (
-
-
- Icon
-
- (optional)
-
-
+
+ }
+ >
+ Icon
+
+ (optional)
+
Enter installation icon
@@ -373,19 +381,21 @@ export function AddInstallationDialog({
{(field) => (
-
-
- Version
- *
-
+
+ }
+ >
+ 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
- *
-
+
+ }
+ >
+ Name
+ *
Enter server name
@@ -186,21 +188,23 @@ export function AddServerDialog({
-
-
- Password
-
- (optional)
-
-
+
+ }
+ >
+ Password
+
+ (optional)
+
Enter password
@@ -236,19 +240,21 @@ export function AddServerDialog({
{(field) => (
-
-
- IP Address
- *
-
+
+ }
+ >
+ IP Address
+ *
Enter server IP address
@@ -284,19 +290,21 @@ export function AddServerDialog({
{(field) => (
-
-
- Port
- *
-
+
+ }
+ >
+ Port
+ *
Enter server port
@@ -344,19 +352,21 @@ export function AddServerDialog({
{(field) => (
-
-
- Installation
- *
-
+
+ }
+ >
+ 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
- *
-
+
+ }
+ >
+ Email
+ *
Enter email address
@@ -228,19 +230,21 @@ export function AddUserDialog({ open }: { open: boolean }) {
-
-
- Password
- *
-
+
+ }
+ >
+ 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
- *
-
+
+ }
+ >
+ 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({
)}
- closeDialog()} variant="outline">
+ }
+ >
Cancel
-
+
deleteInstallation(installation.id)}
From 914401da5da1db7bab800fa0c47061996ccf88c2 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:37:27 +0100
Subject: [PATCH 040/100] =?UTF-8?q?refactor(dialog.deleteserver):=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
* Refactored the `DeleteServerDialog` component to utilize `AlertDialogClose` for the cancel action.
* Improved the import structure by moving `Button` import to the correct location.
* Added `isPending` state handling to the cancel button for better user feedback.
---
src/components/dialogs/deleteserver.dialog.tsx | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/components/dialogs/deleteserver.dialog.tsx b/src/components/dialogs/deleteserver.dialog.tsx
index fb093a7..5014809 100644
--- a/src/components/dialogs/deleteserver.dialog.tsx
+++ b/src/components/dialogs/deleteserver.dialog.tsx
@@ -1,16 +1,17 @@
import { toast } from "sonner";
import {
AlertDialog,
+ AlertDialogClose,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
+import { Button } from "@/components/ui/button";
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;
@@ -22,7 +23,7 @@ export function DeleteServerDialog({
}: {
open: boolean;
} & DeleteServerDialogProps) {
- const { mutate } = useRemoveServerFromInstallation({
+ const { mutate, isPending } = useRemoveServerFromInstallation({
onError: (error) => {
toast.error(`Error removing server: ${error}`, {
id: `server-remove-${server.id}`,
@@ -49,10 +50,14 @@ export function DeleteServerDialog({
- closeDialog()} variant="outline">
+ }
+ >
Cancel
-
+
mutate({
installationId: server.installationId,
@@ -60,7 +65,7 @@ export function DeleteServerDialog({
})
}
>
- Delete
+ {isPending ? "Deleting..." : "Delete"}
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({
- closeDialog()} variant="outline">
+ }
+ >
Cancel
-
+
removeVersion(version)}>
{isPending ? "Deleting..." : "Delete"}
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({
- closeDialog()} variant="outline">
+ }
+ >
Cancel
-
+
removeWorld(world)}
From ec859470a9dd6c0dd1b3a757927094b7aa6d8e72 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:37:55 +0100
Subject: [PATCH 043/100] =?UTF-8?q?refactor(dialog.editinstallation):=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 `TooltipTrigger` components to use `render` prop for better readability.
* Enhanced the structure of labels associated with input fields.
---
.../dialogs/editinstallation.dialog.tsx | 148 ++++++++++--------
1 file changed, 79 insertions(+), 69 deletions(-)
diff --git a/src/components/dialogs/editinstallation.dialog.tsx b/src/components/dialogs/editinstallation.dialog.tsx
index 69f1dbe..ab8a576 100644
--- a/src/components/dialogs/editinstallation.dialog.tsx
+++ b/src/components/dialogs/editinstallation.dialog.tsx
@@ -120,19 +120,21 @@ export function EditInstallationDialog({
{(field) => (
-
-
- Name
- *
-
+
+ }
+ >
+ Name
+ *
Enter server name
@@ -184,21 +186,23 @@ export function EditInstallationDialog({
-
-
- Start parameters
-
- (optional)
-
-
+
+ }
+ >
+ Start parameters
+
+ (optional)
+
Enter start parameters
@@ -233,19 +237,21 @@ export function EditInstallationDialog({
{(field) => (
-
-
- Path
- *
-
+
+ }
+ >
+ Path
+ *
Enter installation path
@@ -275,21 +281,23 @@ export function EditInstallationDialog({
{(field) => (
-
-
- Icon
-
- (optional)
-
-
+
+ }
+ >
+ Icon
+
+ (optional)
+
Enter installation icon
@@ -325,19 +333,21 @@ export function EditInstallationDialog({
{(field) => (
-
-
- Version
- *
-
+
+ }
+ >
+ Version
+ *
Pick game version
From 80a122020cec330bc959c00b9e21801b51ddc3be Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:38:01 +0100
Subject: [PATCH 044/100] =?UTF-8?q?refactor(dialog.editserver):=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 `TooltipTrigger` to use `render` prop for better readability.
* Enhanced the structure of tooltip labels for fields: `name`, `password`, `ip`, `port`, and `installationId`.
---
src/components/dialogs/editserver.dialog.tsx | 148 ++++++++++---------
1 file changed, 79 insertions(+), 69 deletions(-)
diff --git a/src/components/dialogs/editserver.dialog.tsx b/src/components/dialogs/editserver.dialog.tsx
index d283f40..c802c06 100644
--- a/src/components/dialogs/editserver.dialog.tsx
+++ b/src/components/dialogs/editserver.dialog.tsx
@@ -95,19 +95,21 @@ export function EditServerDialog({
{(field) => (
-
-
- Name
- *
-
+
+ }
+ >
+ Name
+ *
Enter server name
@@ -144,21 +146,23 @@ export function EditServerDialog({
-
-
- Password
-
- (optional)
-
-
+
+ }
+ >
+ Password
+
+ (optional)
+
Enter password
@@ -194,19 +198,21 @@ export function EditServerDialog({
{(field) => (
-
-
- IP Address
- *
-
+
+ }
+ >
+ IP Address
+ *
Enter server IP address
@@ -242,21 +248,23 @@ export function EditServerDialog({
{(field) => (
-
-
- Port
-
- (optional)
-
-
+
+ }
+ >
+ Port
+
+ (optional)
+
Enter server port
@@ -293,19 +301,21 @@ export function EditServerDialog({
{(field) => (
-
-
- Installation
- *
-
+
+ }
+ >
+ Installation
+ *
Pick game installation
From 2cabb848e0d0bf9a3e83f09080339ea8ba634e74 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:38:09 +0100
Subject: [PATCH 045/100] =?UTF-8?q?refactor(dialog.editworld):=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 tooltip labels for `name` and `installationId` fields.
---
src/components/dialogs/editworld.dialog.tsx | 56 +++++++++++----------
1 file changed, 30 insertions(+), 26 deletions(-)
diff --git a/src/components/dialogs/editworld.dialog.tsx b/src/components/dialogs/editworld.dialog.tsx
index 2cee877..57186b3 100644
--- a/src/components/dialogs/editworld.dialog.tsx
+++ b/src/components/dialogs/editworld.dialog.tsx
@@ -104,19 +104,21 @@ export function EditWorldDialog({
{(field) => (
-
-
- Name
- *
-
+
+ }
+ >
+ Name
+ *
Enter world name
@@ -152,19 +154,21 @@ export function EditWorldDialog({
{(field) => (
-
-
- Installation
- *
-
+
+ }
+ >
+ Installation
+ *
Pick game installation
From d4fb2a627bb523b94df2033f1a80418417444ebb Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:38:15 +0100
Subject: [PATCH 046/100] =?UTF-8?q?refactor(dialog.importinstallation):=20?=
=?UTF-8?q?=E2=9C=A8=20update=20`Button`=20import=20for=20improved=20struc?=
=?UTF-8?q?ture?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Removed redundant import of `Button` from relative path.
* Added import of `Button` from the absolute path for consistency.
---
src/components/dialogs/importinstallation.dialog.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/dialogs/importinstallation.dialog.tsx b/src/components/dialogs/importinstallation.dialog.tsx
index 1f60e76..475a1ff 100644
--- a/src/components/dialogs/importinstallation.dialog.tsx
+++ b/src/components/dialogs/importinstallation.dialog.tsx
@@ -4,6 +4,7 @@ import { listen } from "@tauri-apps/api/event";
import { useRef, useState } from "react";
import { toast } from "sonner";
import { z } from "zod";
+import { Button } from "@/components/ui/button";
import {
Dialog,
DialogClose,
@@ -22,7 +23,6 @@ import { buildInstallationPath, makeStringFolderSafe } from "@/lib/utils";
import { useDialogStore } from "@/stores/dialogs";
import { useInstallations } from "@/stores/installations";
import { useSettingsStore } from "@/stores/settings";
-import { Button } from "../ui/button";
const installationSchema = z.object({
mods: z.array(
From fd83d9ff01bfc96daa0701d238792c6a2991154b Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:38:54 +0100
Subject: [PATCH 047/100] =?UTF-8?q?refactor(dialog.removemod):=20=E2=9C=A8?=
=?UTF-8?q?=20update=20`AlertDialogClose`=20usage=20for=20improved=20struc?=
=?UTF-8?q?ture?=
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.
* Ensured the `Cancel` button is properly integrated with the dialog's close functionality.
---
src/components/dialogs/removemod.dialog.tsx | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/components/dialogs/removemod.dialog.tsx b/src/components/dialogs/removemod.dialog.tsx
index 8252a87..518592e 100644
--- a/src/components/dialogs/removemod.dialog.tsx
+++ b/src/components/dialogs/removemod.dialog.tsx
@@ -3,16 +3,17 @@ import { invoke } from "@tauri-apps/api/core";
import { toast } from "sonner";
import {
AlertDialog,
+ AlertDialogClose,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
+import { Button } from "@/components/ui/button";
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;
@@ -82,9 +83,12 @@ export function RemoveModDialog({
- closeDialog()} variant="outline">
+ }
+ >
Cancel
-
+
From bc9c578146f6fbc3a8b440f9a8469ca8988b24a2 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:38:59 +0100
Subject: [PATCH 048/100] =?UTF-8?q?refactor(dialog.viewmap):=20=E2=9C=A8?=
=?UTF-8?q?=20update=20imports=20for=20improved=20structure?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Consolidated imports for `Checkbox` and `Select` components.
* Enhanced code organization and readability.
---
src/components/dialogs/viewmap.dialog.tsx | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/components/dialogs/viewmap.dialog.tsx b/src/components/dialogs/viewmap.dialog.tsx
index 4297589..6c6341f 100644
--- a/src/components/dialogs/viewmap.dialog.tsx
+++ b/src/components/dialogs/viewmap.dialog.tsx
@@ -1,5 +1,6 @@
import { useMemo, useState } from "react";
import { WorldMapViewer } from "@/components/maps/world-map-viewer";
+import { Checkbox } from "@/components/ui/checkbox";
import {
Dialog,
DialogClose,
@@ -8,10 +9,14 @@ import {
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+} from "@/components/ui/select";
import type { World } from "@/lib/types";
import { useDialogStore } from "@/stores/dialogs";
-import { Checkbox } from "../ui/checkbox";
-import { Select, SelectContent, SelectItem, SelectTrigger } from "../ui/select";
export type ViewMapDialogProps = {
world: World;
From 0564f59b6139ae053f7df8f393627c86da837283 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:39:05 +0100
Subject: [PATCH 049/100] =?UTF-8?q?refactor(inputs.email):=20=E2=9C=A8=20r?=
=?UTF-8?q?emove=20unused=20`ref`=20prop=20from=20`EmailInput`?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Simplified the `EmailInput` component by removing the `ref` prop.
* This change improves the component's structure and aligns with the current usage pattern.
---
src/components/inputs/email.input.tsx | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/components/inputs/email.input.tsx b/src/components/inputs/email.input.tsx
index 3437f8f..76a361d 100644
--- a/src/components/inputs/email.input.tsx
+++ b/src/components/inputs/email.input.tsx
@@ -6,7 +6,7 @@ import { Input } from "@/components/ui/input";
const EmailInput = forwardRef<
HTMLInputElement,
React.InputHTMLAttributes
->(({ className, ...rest }, ref) => {
+>(({ className, ...rest }) => {
const id = useId();
return (
@@ -14,7 +14,6 @@ const EmailInput = forwardRef<
className={clsx(["peer pe-9", className])}
id={id}
placeholder="me@example.com"
- ref={ref}
type="email"
{...rest}
/>
From 684e7373f34cf2e52dec8955ee1078b50287cbd4 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:39:11 +0100
Subject: [PATCH 050/100] =?UTF-8?q?refactor(inputs.password):=20=E2=9C=A8?=
=?UTF-8?q?=20remove=20unused=20`ref`=20prop=20from=20`PasswordInput`?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Simplified the `PasswordInput` component by removing the unused `ref` prop.
* This change improves the component's structure and readability.
---
src/components/inputs/password.input.tsx | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/components/inputs/password.input.tsx b/src/components/inputs/password.input.tsx
index dd51c3b..c18720f 100644
--- a/src/components/inputs/password.input.tsx
+++ b/src/components/inputs/password.input.tsx
@@ -8,7 +8,7 @@ type PasswordInputProps = {
} & Omit, "className">;
const PasswordInput = forwardRef(
- ({ className, ...rest }, ref) => {
+ ({ className, ...rest }) => {
const id = useId();
const [visible, setVisible] = useState(false);
@@ -25,7 +25,6 @@ const PasswordInput = forwardRef(
className={clsx(["pe-9", computedClassName])}
id={id}
placeholder={visible ? "p4zzw0rd" : "········"}
- ref={ref}
type={visible ? "text" : "password"}
{...rest}
/>
From 22971d6b8b2984a0b27be1c5d35ab083b2dc16e9 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:39:16 +0100
Subject: [PATCH 051/100] =?UTF-8?q?refactor(inputs.search):=20=E2=9C=A8=20?=
=?UTF-8?q?remove=20unused=20`ref`=20handling=20in=20`SearchInput`?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Simplified the `SearchInput` component by removing the custom `ref` handling.
* The component now directly uses the `Input` without managing the `ref`, improving readability and maintainability.
---
src/components/inputs/search.input.tsx | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/src/components/inputs/search.input.tsx b/src/components/inputs/search.input.tsx
index 5a26ce4..aa5a3aa 100644
--- a/src/components/inputs/search.input.tsx
+++ b/src/components/inputs/search.input.tsx
@@ -8,7 +8,7 @@ type SearchInputProps = {
} & Omit, "className">;
export const SearchInput = forwardRef(
- ({ className, ...rest }, ref) => {
+ ({ className, ...rest }) => {
const id = useId();
const searchRef = useRef(null);
useEffect(() => {
@@ -31,14 +31,6 @@ export const SearchInput = forwardRef(
className={clsx(["pe-11", className])}
id={id}
placeholder="Search..."
- ref={(el) => {
- searchRef.current = el;
- if (typeof ref === "function") {
- ref(el);
- } else if (ref) {
- ref.current = el;
- }
- }}
type="search"
{...rest}
/>
From 6e7683afaadd0a0b9ecd09ba12c3b2e635815699 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:39:21 +0100
Subject: [PATCH 052/100] =?UTF-8?q?refactor(items.mod):=20=E2=9C=A8=20remo?=
=?UTF-8?q?ve=20duplicate=20import=20of=20`Group`,=20`GroupItem`,=20and=20?=
=?UTF-8?q?`GroupSeparator`?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Cleaned up import statements for better readability and structure.
---
src/components/items/mod.item.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/items/mod.item.tsx b/src/components/items/mod.item.tsx
index 1144498..2165253 100644
--- a/src/components/items/mod.item.tsx
+++ b/src/components/items/mod.item.tsx
@@ -12,6 +12,7 @@ import { useRef } from "react";
import { toast } from "sonner";
import type { Mod } from "@/components/lists/mod.list";
import { Button } from "@/components/ui/button";
+import { Group, GroupItem, GroupSeparator } from "@/components/ui/group";
import {
Tooltip,
TooltipContent,
@@ -30,7 +31,6 @@ 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,
From fcf4cb67e2d39af4068dad96c8e941b3c197a114 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:39:47 +0100
Subject: [PATCH 053/100] =?UTF-8?q?refactor(version.item):=20=E2=9C=A8=20u?=
=?UTF-8?q?pdate=20imports=20for=20improved=20structure?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Removed duplicate imports of `Button`, `Tooltip`, `TooltipContent`, and `TooltipTrigger`.
* Organized imports to enhance readability and maintainability.
---
src/components/items/version.item.tsx | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/components/items/version.item.tsx b/src/components/items/version.item.tsx
index 2fb8ef3..ece6468 100644
--- a/src/components/items/version.item.tsx
+++ b/src/components/items/version.item.tsx
@@ -1,8 +1,12 @@
import { Download, XIcon } from "lucide-react";
import { Badge } from "@/components/ui/badge";
+import { Button } from "@/components/ui/button";
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
+} from "@/components/ui/tooltip";
import { useDialogStore } from "@/stores/dialogs";
-import { Button } from "../ui/button";
-import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
interface VersionItemProps {
version: string;
From 0ecdef47d6ea40e707cf6630eba6439c9236cce6 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:39:57 +0100
Subject: [PATCH 054/100] =?UTF-8?q?refactor(world.item):=20=E2=9C=A8=20upd?=
=?UTF-8?q?ate=20import=20statements=20for=20`Group`,=20`GroupItem`,=20and?=
=?UTF-8?q?=20`GroupSeparator`?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Removed duplicate import from `../ui/group`
* Improved import structure for better readability
---
src/components/items/world.item.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/items/world.item.tsx b/src/components/items/world.item.tsx
index 8be873a..6dc8ff5 100644
--- a/src/components/items/world.item.tsx
+++ b/src/components/items/world.item.tsx
@@ -10,6 +10,7 @@ import {
} from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
+import { Group, GroupItem, GroupSeparator } from "@/components/ui/group";
import {
Tooltip,
TooltipContent,
@@ -22,7 +23,6 @@ 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();
From f190486fa4880647eb68d6eeeedc5d55a31eee0e Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:40:02 +0100
Subject: [PATCH 055/100] =?UTF-8?q?refactor(lists.mod):=20=E2=9C=A8=20upda?=
=?UTF-8?q?te=20author=20filter=20to=20be=20case-insensitive?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Modified the author filter in `ModList` to use `toLowerCase()` for case-insensitive matching.
* This improves user experience by allowing more flexible searches for mod authors.
---
src/components/lists/mod.list.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/lists/mod.list.tsx b/src/components/lists/mod.list.tsx
index 22e66bb..30355a7 100644
--- a/src/components/lists/mod.list.tsx
+++ b/src/components/lists/mod.list.tsx
@@ -86,7 +86,7 @@ export function ModList({
})
?.filter((mod) => {
if (author) {
- return mod.author === author;
+ return mod.author.toLowerCase().includes(author.toLowerCase());
}
return true;
})
From a08281c3032923a150664fdf230ccb3d8a79757f Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 10:40:07 +0100
Subject: [PATCH 056/100] =?UTF-8?q?refactor(public.servers.list):=20?=
=?UTF-8?q?=E2=9C=A8=20reorganize=20imports=20and=20update=20`TooltipTrigg?=
=?UTF-8?q?er`=20usage?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Removed duplicate imports for `Badge`, `Button`, and `Tooltip` components.
* Updated `TooltipTrigger` to use `render` prop for better structure and readability.
---
src/components/lists/public.servers.list.tsx | 106 ++++++++++---------
1 file changed, 58 insertions(+), 48 deletions(-)
diff --git a/src/components/lists/public.servers.list.tsx b/src/components/lists/public.servers.list.tsx
index d8a46d0..ed4b058 100644
--- a/src/components/lists/public.servers.list.tsx
+++ b/src/components/lists/public.servers.list.tsx
@@ -8,6 +8,13 @@ import {
Users2Icon,
} from "lucide-react";
import { useCallback } from "react";
+import { Badge } from "@/components/ui/badge";
+import { Button } from "@/components/ui/button";
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
+} from "@/components/ui/tooltip";
import { useDownloadVersion } from "@/hooks/use-download-version";
import { useInstalledVersions } from "@/hooks/use-installed-versions";
import type { PublicServer } from "@/hooks/use-public-servers";
@@ -15,9 +22,6 @@ import { useDialogStore } from "@/stores/dialogs";
import { useInstallations } from "@/stores/installations";
import { useServersFilters } from "@/stores/serversFilters";
import { MotionPublicServerContextMenu } from "../context-menus/public-server.context-menu";
-import { Badge } from "../ui/badge";
-import { Button } from "../ui/button";
-import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
export function PublicServerList({
parentRef,
@@ -182,22 +186,24 @@ export function PublicServerList({
{installedVersions.includes(server.gameVersion) ? (
-
-
- openDialog("ConnectServerDialog", { server })
- }
- size="icon"
- variant="outline"
- >
-
+ openDialog("ConnectServerDialog", { server })
+ }
+ size="icon"
+ variant="outline"
/>
-
+ }
+ >
+
Connect to {server?.serverName}
@@ -207,20 +213,22 @@ export function PublicServerList({
(i) => i.version === server.gameVersion,
) ? (
-
- downloadVersion(server.gameVersion)}
- size="icon"
- variant="outline"
- >
- downloadVersion(server.gameVersion)}
+ size="icon"
+ variant="outline"
/>
-
+ }
+ >
+
Download {server?.gameVersion}
@@ -228,24 +236,26 @@ export function PublicServerList({
) : (
-
-
- openDialog("AddInstallationDialog", {
- version: server.gameVersion,
- })
- }
- size="icon"
- variant="outline"
- >
-
+ openDialog("AddInstallationDialog", {
+ version: server.gameVersion,
+ })
+ }
+ size="icon"
+ variant="outline"
/>
-
+ }
+ >
+
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() {
)}
-
- {
- verifyAuth({
- sessionkey: user.sessionkey || "",
- uid: user.uid || "",
- });
- }}
- onKeyUp={(e) => {
- if (e.key === "Enter") {
+ {
verifyAuth({
sessionkey: user.sessionkey || "",
uid: user.uid || "",
});
- }
- }}
- size="icon"
- variant="outline"
- >
-
-
+ }}
+ 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"
- >
-
-
+ }}
+ 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"
- >
-
-
+ 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
-
+
+ }
+ >
+ Installations Parent Directory
Defaults to the app data directory
@@ -375,20 +377,22 @@ function RouteComponent() {
{(field) => (
-
-
- Versions Parent Directory
-
+
+ }
+ >
+ 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) => (
-
-
setSelectedUser(user.uid)}
- onKeyUp={(e) => {
- if (e.key === "Enter") setSelectedUser(user.uid);
- }}
- variant="outline"
+ setSelectedUser(user.uid)}
+ onKeyUp={(e) => {
+ if (e.key === "Enter") setSelectedUser(user.uid);
+ }}
+ variant="outline"
+ />
+ }
>
@@ -134,63 +139,73 @@ export function AppSidebar() {
{user.uid === selectedUser.uid && (
)}
-
+
+
{
- 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}
-
+
))}
openDialog("AddUserDialog")}
variant="outline"
>
From 2e37419cf58608230dea7b7f784089ee50c83046 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 11:28:48 +0100
Subject: [PATCH 065/100] =?UTF-8?q?refactor(context-menu):=20=E2=9C=A8=20u?=
=?UTF-8?q?pdate=20`ContextMenuPrimitive`=20imports=20for=20consistency?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Changed imports from `@radix-ui/react-context-menu` to `@base-ui-components/react/context-menu` across multiple context menu components.
* Updated type references for `Trigger` and `Sub` components to align with the new import structure.
---
bun.lock | 3 -
package.json | 1 -
.../installation.context-menu.tsx | 4 +-
.../public-server.context-menu.tsx | 6 +-
.../context-menus/server.context-menu.tsx | 6 +-
.../context-menus/version.context-menu.tsx | 4 +-
.../context-menus/world.context-menu.tsx | 4 +-
src/components/ui/context-menu.tsx | 97 +++++++++++--------
8 files changed, 67 insertions(+), 58 deletions(-)
diff --git a/bun.lock b/bun.lock
index 736b31a..c3d28bf 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-context-menu": "^2.2.16",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-scroll-area": "^1.2.10",
@@ -248,8 +247,6 @@
"@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="],
- "@radix-ui/react-context-menu": ["@radix-ui/react-context-menu@2.2.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@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-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww=="],
-
"@radix-ui/react-dialog": ["@radix-ui/react-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-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-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-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="],
"@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="],
diff --git a/package.json b/package.json
index c413077..b7ab955 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-context-menu": "^2.2.16",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-scroll-area": "^1.2.10",
diff --git a/src/components/context-menus/installation.context-menu.tsx b/src/components/context-menus/installation.context-menu.tsx
index 1ed2f69..1ca091c 100644
--- a/src/components/context-menus/installation.context-menu.tsx
+++ b/src/components/context-menus/installation.context-menu.tsx
@@ -1,4 +1,4 @@
-import type * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
+import type { ContextMenu as ContextMenuPrimitive } from "@base-ui-components/react/context-menu";
import { useNavigate } from "@tanstack/react-router";
import {
DownloadCloudIcon,
@@ -29,7 +29,7 @@ import { type Installation, useInstallations } from "@/stores/installations";
export const InstallationContextMenu = ({
installation,
...props
-}: React.ComponentProps & {
+}: ContextMenuPrimitive.Trigger.Props & {
installation: Installation;
}) => {
const navigate = useNavigate();
diff --git a/src/components/context-menus/public-server.context-menu.tsx b/src/components/context-menus/public-server.context-menu.tsx
index ea0bf73..626ab5d 100644
--- a/src/components/context-menus/public-server.context-menu.tsx
+++ b/src/components/context-menus/public-server.context-menu.tsx
@@ -1,6 +1,6 @@
-import type * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
-import { motion } from "framer-motion";
+import type { ContextMenu as ContextMenuPrimitive } from "@base-ui-components/react/context-menu";
import { DownloadCloudIcon, FolderPlusIcon, PlugIcon } from "lucide-react";
+import { motion } from "motion/react";
import {
ContextMenu,
ContextMenuContent,
@@ -16,7 +16,7 @@ import { useInstallations } from "@/stores/installations";
export const PublicServerContextMenu = ({
server,
...props
-}: React.ComponentProps & {
+}: ContextMenuPrimitive.Trigger.Props & {
server: PublicServer;
}) => {
// Stores
diff --git a/src/components/context-menus/server.context-menu.tsx b/src/components/context-menus/server.context-menu.tsx
index d626676..4713972 100644
--- a/src/components/context-menus/server.context-menu.tsx
+++ b/src/components/context-menus/server.context-menu.tsx
@@ -1,6 +1,5 @@
-import type * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
+import type { ContextMenu as ContextMenuPrimitive } from "@base-ui-components/react/context-menu";
import { useNavigate } from "@tanstack/react-router";
-import { motion } from "framer-motion";
import {
DownloadCloudIcon,
FolderOpenIcon,
@@ -11,6 +10,7 @@ import {
StarIcon,
TrashIcon,
} from "lucide-react";
+import { motion } from "motion/react";
import {
ContextMenu,
ContextMenuContent,
@@ -29,7 +29,7 @@ import { type Server, useServerStore } from "@/stores/servers";
export const ServerContextMenu = ({
server,
...props
-}: React.ComponentProps & {
+}: ContextMenuPrimitive.Trigger.Props & {
server: Server;
}) => {
const navigate = useNavigate();
diff --git a/src/components/context-menus/version.context-menu.tsx b/src/components/context-menus/version.context-menu.tsx
index ef67da2..e30af37 100644
--- a/src/components/context-menus/version.context-menu.tsx
+++ b/src/components/context-menus/version.context-menu.tsx
@@ -1,4 +1,4 @@
-import type * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
+import type { ContextMenu as ContextMenuPrimitive } from "@base-ui-components/react/context-menu";
import { FolderOpenIcon, TrashIcon } from "lucide-react";
import { motion } from "motion/react";
import {
@@ -16,7 +16,7 @@ import { useSettingsStore } from "@/stores/settings";
export const VersionContextMenu = ({
version,
...props
-}: React.ComponentProps & {
+}: ContextMenuPrimitive.Trigger.Props & {
version: string;
}) => {
const { appFolder } = useAppFolder();
diff --git a/src/components/context-menus/world.context-menu.tsx b/src/components/context-menus/world.context-menu.tsx
index c4d816f..028a30e 100644
--- a/src/components/context-menus/world.context-menu.tsx
+++ b/src/components/context-menus/world.context-menu.tsx
@@ -1,4 +1,4 @@
-import type * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
+import type { ContextMenu as ContextMenuPrimitive } from "@base-ui-components/react/context-menu";
import { useNavigate } from "@tanstack/react-router";
import {
DownloadCloudIcon,
@@ -28,7 +28,7 @@ import { useInstallations } from "@/stores/installations";
export const WorldContextMenu = ({
world,
...props
-}: React.ComponentProps & {
+}: ContextMenuPrimitive.Trigger.Props & {
world: World;
}) => {
const navigate = useNavigate();
diff --git a/src/components/ui/context-menu.tsx b/src/components/ui/context-menu.tsx
index 944339a..1e810f9 100644
--- a/src/components/ui/context-menu.tsx
+++ b/src/components/ui/context-menu.tsx
@@ -1,20 +1,36 @@
-import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
+import { ContextMenu as ContextMenuPrimitive } from "@base-ui-components/react/context-menu";
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
import type * as React from "react";
-
+import { createContext, useContext, useRef } from "react";
import { cn } from "@/lib/utils";
+const ContextMenuContext = createContext<{
+ triggerRef: React.RefObject | null;
+}>({
+ triggerRef: null,
+});
+
function ContextMenu({
...props
}: React.ComponentProps) {
- return ;
+ const triggerRef = useRef(null);
+ return (
+
+
+
+ );
}
function ContextMenuTrigger({
...props
}: React.ComponentProps) {
+ const { triggerRef } = useContext(ContextMenuContext);
return (
-
+
);
}
@@ -34,12 +50,6 @@ function ContextMenuPortal({
);
}
-function ContextMenuSub({
- ...props
-}: React.ComponentProps) {
- return ;
-}
-
function ContextMenuRadioGroup({
...props
}: React.ComponentProps) {
@@ -56,13 +66,13 @@ function ContextMenuSubTrigger({
inset,
children,
...props
-}: React.ComponentProps & {
+}: React.ComponentProps & {
inset?: boolean;
}) {
return (
-
{children}
-
+
);
}
-function ContextMenuSubContent({
- className,
+function ContextMenuSub({
...props
-}: React.ComponentProps) {
+}: React.ComponentProps) {
return (
-
+
);
}
function ContextMenuContent({
className,
+ sideOffset = 4,
...props
-}: React.ComponentProps) {
+}: ContextMenuPrimitive.Popup.Props & {
+ sideOffset?: number;
+}) {
+ const { triggerRef } = useContext(ContextMenuContext);
+
return (
-
+
+
+
);
}
@@ -149,9 +163,9 @@ function ContextMenuCheckboxItem({
{...props}
>
-
-
-
+
+
+
{children}
@@ -173,9 +187,9 @@ function ContextMenuRadioItem({
{...props}
>
-
+
-
+
{children}
@@ -186,11 +200,11 @@ function ContextMenuLabel({
className,
inset,
...props
-}: React.ComponentProps & {
+}: React.ComponentProps & {
inset?: boolean;
}) {
return (
-
Date: Tue, 28 Oct 2025 12:39:43 +0100
Subject: [PATCH 066/100] =?UTF-8?q?refactor(context-menu):=20=E2=9C=A8=20e?=
=?UTF-8?q?nhance=20context=20menu=20structure=20with=20`ContextMenuGroup`?=
=?UTF-8?q?=20and=20`ContextMenuLabel`?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Introduced `ContextMenuGroup` and `ContextMenuLabel` for better organization of context menu items across multiple components.
* Improved readability and maintainability of context menus in `installation`, `public-server`, `server`, `version`, and `world` components.
* Updated styles for context menu items to ensure consistent appearance.
---
.../installation.context-menu.tsx | 161 +++++++++---------
.../public-server.context-menu.tsx | 67 ++++----
.../context-menus/server.context-menu.tsx | 149 ++++++++--------
.../context-menus/version.context-menu.tsx | 45 ++---
.../context-menus/world.context-menu.tsx | 145 ++++++++--------
src/components/ui/context-menu.tsx | 18 +-
6 files changed, 318 insertions(+), 267 deletions(-)
diff --git a/src/components/context-menus/installation.context-menu.tsx b/src/components/context-menus/installation.context-menu.tsx
index 1ca091c..5faca4c 100644
--- a/src/components/context-menus/installation.context-menu.tsx
+++ b/src/components/context-menus/installation.context-menu.tsx
@@ -15,7 +15,9 @@ import { motion } from "motion/react";
import {
ContextMenu,
ContextMenuContent,
+ ContextMenuGroup,
ContextMenuItem,
+ ContextMenuLabel,
ContextMenuTrigger,
} from "@/components/ui/context-menu";
import { useDownloadVersion } from "@/hooks/use-download-version";
@@ -50,90 +52,97 @@ export const InstallationContextMenu = ({
- {installedVersions?.includes(installation.version) ? (
+
+
+ {installation.name}
+
+ {installedVersions?.includes(installation.version) ? (
+ launchInstallation({ id: installation.id })}
+ >
+ Launch
+
+
+ ) : (
+ downloadVersion(installation.version)}
+ >
+ Download {installation.version}
+
+
+ )}
launchInstallation({ id: installation.id })}
+ onClick={() => toggleFavorite(installation.id)}
>
- Launch
-
+ {installation.favorite ? "Unfavorite" : "Favorite"}
+
- ) : (
downloadVersion(installation.version)}
+ onClick={() =>
+ navigate({
+ params: { id: installation.id.toString() },
+ to: "/install-mods/$id",
+ })
+ }
>
- Download {installation.version}
-
+ Manage Mods
+
- )}
- toggleFavorite(installation.id)}
- >
- {installation.favorite ? "Unfavorite" : "Favorite"}
-
-
-
- navigate({
- params: { id: installation.id.toString() },
- to: "/install-mods/$id",
- })
- }
- >
- Manage Mods
-
-
-
- navigate({
- params: { id: installation.id.toString() },
- to: "/mod-configs/$id",
- })
- }
- >
- Configure Mods
-
-
- revealInstallationInFolder(installation.path)}
- >
- Open Folder
-
-
- exportInstallation({ installation })}
- >
- Export
-
-
- openDialog("EditInstallationDialog", { installation })}
- >
- Edit
-
-
-
- openDialog("DeleteInstallationDialog", { installation })
- }
- variant="destructive"
- >
- Delete
-
-
+
+ navigate({
+ params: { id: installation.id.toString() },
+ to: "/mod-configs/$id",
+ })
+ }
+ >
+ Configure Mods
+
+
+ revealInstallationInFolder(installation.path)}
+ >
+ Open Folder
+
+
+ exportInstallation({ installation })}
+ >
+ Export
+
+
+
+ openDialog("EditInstallationDialog", { installation })
+ }
+ >
+ Edit
+
+
+
+ openDialog("DeleteInstallationDialog", { installation })
+ }
+ variant="destructive"
+ >
+ Delete
+
+
+
);
diff --git a/src/components/context-menus/public-server.context-menu.tsx b/src/components/context-menus/public-server.context-menu.tsx
index 626ab5d..5ade848 100644
--- a/src/components/context-menus/public-server.context-menu.tsx
+++ b/src/components/context-menus/public-server.context-menu.tsx
@@ -4,7 +4,9 @@ import { motion } from "motion/react";
import {
ContextMenu,
ContextMenuContent,
+ ContextMenuGroup,
ContextMenuItem,
+ ContextMenuLabel,
ContextMenuTrigger,
} from "@/components/ui/context-menu";
import { useDownloadVersion } from "@/hooks/use-download-version";
@@ -33,36 +35,41 @@ export const PublicServerContextMenu = ({
- {installedVersions?.includes(server.gameVersion) ? (
- openDialog("ConnectServerDialog", { server })}
- >
- Connect
-
-
- ) : installations.find((i) => i.version === server.gameVersion) ? (
- downloadVersion(server.gameVersion)}
- >
- Download {server.gameVersion}
-
-
- ) : (
-
- server &&
- openDialog("AddInstallationDialog", {
- version: server.gameVersion,
- })
- }
- >
- Add Installation
-
-
- )}
+
+
+ {server.serverName}
+
+ {installedVersions?.includes(server.gameVersion) ? (
+ openDialog("ConnectServerDialog", { server })}
+ >
+ Connect
+
+
+ ) : installations.find((i) => i.version === server.gameVersion) ? (
+ downloadVersion(server.gameVersion)}
+ >
+ Download {server.gameVersion}
+
+
+ ) : (
+
+ server &&
+ openDialog("AddInstallationDialog", {
+ version: server.gameVersion,
+ })
+ }
+ >
+ Add Installation
+
+
+ )}
+
);
diff --git a/src/components/context-menus/server.context-menu.tsx b/src/components/context-menus/server.context-menu.tsx
index 4713972..3ce2ec0 100644
--- a/src/components/context-menus/server.context-menu.tsx
+++ b/src/components/context-menus/server.context-menu.tsx
@@ -14,7 +14,9 @@ import { motion } from "motion/react";
import {
ContextMenu,
ContextMenuContent,
+ ContextMenuGroup,
ContextMenuItem,
+ ContextMenuLabel,
ContextMenuTrigger,
} from "@/components/ui/context-menu";
import { useConnectToServer } from "@/hooks/use-connect-to-server";
@@ -54,87 +56,92 @@ export const ServerContextMenu = ({
- {installation && installedVersions?.includes(installation.version) ? (
+
+
+ {server.name}
+
+ {installation && installedVersions?.includes(installation.version) ? (
+ connectToServer(server)}
+ >
+ Connect
+
+
+ ) : (
+
+ installation && downloadVersion(installation.version)
+ }
+ >
+ Download {installation?.version}
+
+
+ )}
connectToServer(server)}
+ onClick={() => toggleFavorite(server.id)}
>
- Connect
-
+ {server.favorite ? "Unfavorite" : "Favorite"}
+
- ) : (
- installation && downloadVersion(installation.version)
+ installation &&
+ navigate({
+ params: { id: installation?.id.toString() },
+ to: "/install-mods/$id",
+ })
}
>
- Download {installation?.version}
-
+ Manage Mods
+
- )}
- toggleFavorite(server.id)}
- >
- {server.favorite ? "Unfavorite" : "Favorite"}
-
-
-
- installation &&
- navigate({
- params: { id: installation?.id.toString() },
- to: "/install-mods/$id",
- })
- }
- >
- Manage Mods
-
-
-
- installation &&
- navigate({
- params: { id: installation.id.toString() },
- to: "/mod-configs/$id",
- })
- }
- >
- Configure Mods
-
-
-
- installation && revealInstallationInFolder(installation.path)
- }
- >
- Open Installation Folder
-
-
- openDialog("EditServerDialog", { server })}
- >
- Edit
-
-
- openDialog("DeleteServerDialog", { server })}
- variant="destructive"
- >
- Delete
-
-
+
+ installation &&
+ navigate({
+ params: { id: installation.id.toString() },
+ to: "/mod-configs/$id",
+ })
+ }
+ >
+ Configure Mods
+
+
+
+ installation && revealInstallationInFolder(installation.path)
+ }
+ >
+ Open Installation Folder
+
+
+ openDialog("EditServerDialog", { server })}
+ >
+ Edit
+
+
+ openDialog("DeleteServerDialog", { server })}
+ variant="destructive"
+ >
+ Delete
+
+
+
);
diff --git a/src/components/context-menus/version.context-menu.tsx b/src/components/context-menus/version.context-menu.tsx
index e30af37..b8fadd7 100644
--- a/src/components/context-menus/version.context-menu.tsx
+++ b/src/components/context-menus/version.context-menu.tsx
@@ -4,7 +4,9 @@ import { motion } from "motion/react";
import {
ContextMenu,
ContextMenuContent,
+ ContextMenuGroup,
ContextMenuItem,
+ ContextMenuLabel,
ContextMenuTrigger,
} from "@/components/ui/context-menu";
import { useAppFolder } from "@/hooks/use-app-folder";
@@ -32,25 +34,30 @@ export const VersionContextMenu = ({
-
- openFolder(
- `${versionsParent ?? appFolder}${pathDelimiter}${versionsSubdir}${pathDelimiter}${version}`,
- )
- }
- >
- Open Folder
-
-
- openDialog("DeleteVersionDialog", { version })}
- variant="destructive"
- >
- Delete
-
-
+
+
+ {version}
+
+
+ openFolder(
+ `${versionsParent ?? appFolder}${pathDelimiter}${versionsSubdir}${pathDelimiter}${version}`,
+ )
+ }
+ >
+ Open Folder
+
+
+ openDialog("DeleteVersionDialog", { version })}
+ variant="destructive"
+ >
+ Delete
+
+
+
);
diff --git a/src/components/context-menus/world.context-menu.tsx b/src/components/context-menus/world.context-menu.tsx
index 028a30e..dab1063 100644
--- a/src/components/context-menus/world.context-menu.tsx
+++ b/src/components/context-menus/world.context-menu.tsx
@@ -14,7 +14,9 @@ import { motion } from "motion/react";
import {
ContextMenu,
ContextMenuContent,
+ ContextMenuGroup,
ContextMenuItem,
+ ContextMenuLabel,
ContextMenuTrigger,
} from "@/components/ui/context-menu";
import { useDownloadVersion } from "@/hooks/use-download-version";
@@ -53,85 +55,90 @@ export const WorldContextMenu = ({
- {installation && installedVersions?.includes(installation.version) ? (
+
+
+ {world.data.world_name}
+
+ {installation && installedVersions?.includes(installation.version) ? (
+ launchInstallation({ id: installation.id })}
+ >
+ Launch
+
+
+ ) : (
+
+ installation && downloadVersion(installation.version)
+ }
+ >
+ Download {installation?.version}
+
+
+ )}
launchInstallation({ id: installation.id })}
+ disabled={!world.has_map}
+ onClick={() =>
+ world.has_map && openDialog("ViewMapDialog", { world })
+ }
+ >
+ View Map
+
+
+
+ installation &&
+ navigate({
+ params: { id: installation.id.toString() },
+ to: "/install-mods/$id",
+ })
+ }
+ >
+ Manage Mods
+
+
+
+ installation &&
+ navigate({
+ params: { id: installation.id.toString() },
+ to: "/mod-configs/$id",
+ })
+ }
>
- Launch
-
+ Configure Mods
+
- ) : (
- installation && downloadVersion(installation.version)
+ installation && revealInstallationInFolder(installation.path)
}
>
- Download {installation?.version}
-
+ Open Folder
+
+
+ openDialog("EditWorldDialog", { world })}
+ >
+ Edit
+
+
+ openDialog("DeleteWorldDialog", { world })}
+ variant="destructive"
+ >
+ Delete
+
- )}
-
- world.has_map && openDialog("ViewMapDialog", { world })
- }
- >
- View Map
-
-
-
- installation &&
- navigate({
- params: { id: installation.id.toString() },
- to: "/install-mods/$id",
- })
- }
- >
- Manage Mods
-
-
-
- installation &&
- navigate({
- params: { id: installation.id.toString() },
- to: "/mod-configs/$id",
- })
- }
- >
- Configure Mods
-
-
-
- installation && revealInstallationInFolder(installation.path)
- }
- >
- Open Folder
-
-
- openDialog("EditWorldDialog", { world })}
- >
- Edit
-
-
- openDialog("DeleteWorldDialog", { world })}
- variant="destructive"
- >
- Delete
-
-
+
);
diff --git a/src/components/ui/context-menu.tsx b/src/components/ui/context-menu.tsx
index 1e810f9..025ba67 100644
--- a/src/components/ui/context-menu.tsx
+++ b/src/components/ui/context-menu.tsx
@@ -112,7 +112,7 @@ function ContextMenuContent({
>
+ );
+}
+
function ContextMenuItem({
className,
inset,
variant = "default",
...props
-}: React.ComponentProps & {
+}: ContextMenuPrimitive.Item.Props & {
inset?: boolean;
variant?: "default" | "destructive";
}) {
@@ -247,6 +260,7 @@ function ContextMenuShortcut({
export {
ContextMenu,
+ ContextMenuArrow,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
From a07111e4d905b38c138ef087c9673264ac090cf2 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:16:44 +0100
Subject: [PATCH 067/100] =?UTF-8?q?refactor(select):=20=E2=9C=A8=20update?=
=?UTF-8?q?=20`SelectPrimitive`=20imports=20and=20enhance=20component=20st?=
=?UTF-8?q?ructure?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Refactored imports from `@radix-ui/react-select` to `@base-ui-components/react/select`.
* Improved the structure of `SelectTrigger`, `SelectPopup`, and `SelectItem` components for better readability and maintainability.
* Updated icon usage in `SelectTrigger` and `SelectItem` for consistency.
---
src/components/ui/select.tsx | 214 +++++++++++++++++------------------
1 file changed, 105 insertions(+), 109 deletions(-)
diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx
index c6a5656..c69eaad 100644
--- a/src/components/ui/select.tsx
+++ b/src/components/ui/select.tsx
@@ -1,121 +1,140 @@
-import * as SelectPrimitive from "@radix-ui/react-select";
-import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
-import type * as React from "react";
+import { Select as SelectPrimitive } from "@base-ui-components/react/select";
+import {
+ ChevronDownIcon,
+ ChevronsUpDownIcon,
+ ChevronUpIcon,
+} from "lucide-react";
import { cn } from "@/lib/utils";
-function Select({
- ...props
-}: React.ComponentProps) {
- return ;
-}
-
-function SelectGroup({
- ...props
-}: React.ComponentProps) {
- return ;
-}
-
-function SelectValue({
- ...props
-}: React.ComponentProps) {
- return ;
-}
+const Select = SelectPrimitive.Root;
function SelectTrigger({
className,
size = "default",
children,
...props
-}: React.ComponentProps & {
- size?: "sm" | "default";
+}: SelectPrimitive.Trigger.Props & {
+ size?: "sm" | "default" | "lg";
}) {
return (
{children}
-
-
+
+
);
}
-function SelectContent({
+function SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {
+ return (
+
+ );
+}
+
+function SelectPopup({
className,
children,
- position = "popper",
+ sideOffset = 4,
+ align = "center",
+ alignItemWithTrigger = true,
...props
-}: React.ComponentProps) {
+}: SelectPrimitive.Popup.Props & {
+ sideOffset?: SelectPrimitive.Positioner.Props["sideOffset"];
+ alignItemWithTrigger?: SelectPrimitive.Positioner.Props["alignItemWithTrigger"];
+ align?: SelectPrimitive.Positioner.Props["align"];
+}) {
return (
-
-
-
- {children}
-
-
-
+
+
+
+
+
+ {children}
+
+
+
+
+
+
+
);
}
-function SelectLabel({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
function SelectItem({
className,
children,
...props
-}: React.ComponentProps) {
+}: SelectPrimitive.Item.Props) {
return (
-
-
-
-
-
- {children}
+
+
+ Check Icon
+
+
+
+
+ {children}
+
);
}
@@ -123,61 +142,38 @@ function SelectItem({
function SelectSeparator({
className,
...props
-}: React.ComponentProps) {
+}: SelectPrimitive.Separator.Props) {
return (
);
}
-function SelectScrollUpButton({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
-
-
- );
+function SelectGroup(props: SelectPrimitive.Group.Props) {
+ return ;
}
-function SelectScrollDownButton({
- className,
- ...props
-}: React.ComponentProps) {
+function SelectGroupLabel(props: SelectPrimitive.GroupLabel.Props) {
return (
-
-
-
+ />
);
}
export {
Select,
- SelectContent,
- SelectGroup,
- SelectItem,
- SelectLabel,
- SelectScrollDownButton,
- SelectScrollUpButton,
- SelectSeparator,
SelectTrigger,
SelectValue,
+ SelectPopup,
+ SelectPopup as SelectContent,
+ SelectItem,
+ SelectSeparator,
+ SelectGroup,
+ SelectGroupLabel,
};
From 6bd87464d955941e73a60895c6213f79b82e8950 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:16:52 +0100
Subject: [PATCH 068/100] =?UTF-8?q?refactor(auto-complete):=20=E2=9C=A8=20?=
=?UTF-8?q?enhance=20`AutocompletePopup`=20styling=20for=20improved=20UI?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Updated background style to `bg-popover/50` with `backdrop-blur-sm` for better visual clarity.
---
src/components/ui/auto-complete.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/ui/auto-complete.tsx b/src/components/ui/auto-complete.tsx
index f8cd142..09b5965 100644
--- a/src/components/ui/auto-complete.tsx
+++ b/src/components/ui/auto-complete.tsx
@@ -71,7 +71,7 @@ function AutocompletePopup({
data-slot="autocomplete-positioner"
sideOffset={sideOffset}
>
-
+
Date: Tue, 28 Oct 2025 13:17:01 +0100
Subject: [PATCH 069/100] =?UTF-8?q?refactor(public-servers):=20=E2=9C=A8?=
=?UTF-8?q?=20replace=20`DropdownMenu`=20with=20`Select`=20for=20game=20ve?=
=?UTF-8?q?rsion=20selection?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Improved component structure by using `Select` for better UX.
* Enhanced the handling of selected game versions with cleaner logic.
---
src/routes/public-servers.tsx | 40 ++++++++++++-----------------------
1 file changed, 14 insertions(+), 26 deletions(-)
diff --git a/src/routes/public-servers.tsx b/src/routes/public-servers.tsx
index 5809f19..3d8957d 100644
--- a/src/routes/public-servers.tsx
+++ b/src/routes/public-servers.tsx
@@ -1,16 +1,9 @@
import { useQuery } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
-import { ChevronDownIcon } from "lucide-react";
import { useRef } from "react";
import { SearchInput } from "@/components/inputs";
import { PublicServerList } from "@/components/lists/public.servers.list";
import { TextSwitch } from "@/components/switches/text.switch";
-import {
- DropdownMenu,
- DropdownMenuCheckboxItem,
- DropdownMenuContent,
- DropdownMenuTrigger,
-} from "@/components/ui/dropdown-menu";
import { ErrorComponent } from "@/components/ui/error";
import {
Select,
@@ -71,34 +64,29 @@ function RouteComponent() {
placeholder="Search servers..."
value={searchText}
/>
-
-
+
+
{selectedGameVersions.length > 0
? selectedGameVersions.length > 1
? `${selectedGameVersions.length} versions`
: selectedGameVersions[0]
: "Game version(s)"}
-
-
-
+
+
{gameVersions?.sort(compareSemverDesc).map((version) => (
- v === version)}
+ {
- if (checked) {
- addGameVersion(version);
- } else {
- removeGameVersion(version);
- }
- }}
- onSelect={(e) => e.preventDefault()}
+ onClick={() =>
+ selectedGameVersions.includes(version)
+ ? removeGameVersion(version)
+ : addGameVersion(version)
+ }
>
{version}
-
+
))}
-
-
+
+
setSortBy(value as ServersFilters["sortBy"])
@@ -110,7 +98,7 @@ function RouteComponent() {
? `${sortOptions[sortBy as keyof typeof sortOptions]}`
: "Sort by"}
-
+
{Object.entries(sortOptions).map(([key, value]) => (
{value}
From fb5381c0bdfced1cafe63cdc4837912f0056b65f Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:17:07 +0100
Subject: [PATCH 070/100] =?UTF-8?q?refactor(worlds):=20=E2=9C=A8=20replace?=
=?UTF-8?q?=20`DropdownMenu`=20with=20`Select`=20for=20installation=20sele?=
=?UTF-8?q?ction?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Updated the installation selection component from `DropdownMenu` to `Select` for improved usability.
* Enhanced the styling and structure of the selection component.
---
src/routes/worlds.tsx | 40 ++++++++++++++++++++++------------------
1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/src/routes/worlds.tsx b/src/routes/worlds.tsx
index 4bc5ffb..8c9213e 100644
--- a/src/routes/worlds.tsx
+++ b/src/routes/worlds.tsx
@@ -1,16 +1,16 @@
import { createFileRoute } from "@tanstack/react-router";
-import { ChevronDownIcon } from "lucide-react";
import { useState } from "react";
import { SearchInput } from "@/components/inputs";
import { WorldList } from "@/components/lists/world.list";
-import {
- DropdownMenu,
- DropdownMenuCheckboxItem,
- DropdownMenuContent,
- DropdownMenuTrigger,
-} from "@/components/ui/dropdown-menu";
import { ErrorComponent } from "@/components/ui/error";
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+} from "@/components/ui/select";
import { useSaves } from "@/hooks/use-saves";
+import { cn } from "@/lib/utils";
import { useInstallations } from "@/stores/installations";
export const Route = createFileRoute("/worlds")({
@@ -54,29 +54,33 @@ function RouteComponent() {
placeholder="Search worlds..."
value={searchText}
/>
-
-
+
+
{selectedInstallationId
? `${installations.find((installation) => installation.id === selectedInstallationId)?.name}`
: "Select installation"}
-
-
-
+
+
{installations.map((installation) => (
-
+ onClick={() =>
setSelectedInstallationId((prev) =>
prev === installation.id ? null : installation.id,
)
}
+ value={installation.id.toString()}
>
{installation.name}
-
+
))}
-
-
+
+
{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",
- )}
- >
+
+
Game Version(s)
- {selectedGameVersions.length > 0
- ? selectedGameVersions.length > 1
- ? `${selectedGameVersions.length} versions`
- : selectedGameVersions[0]
- : "-"}
-
-
-
+
+ {selectedGameVersions.length > 0
+ ? selectedGameVersions.length > 1
+ ? `${selectedGameVersions.length} versions`
+ : selectedGameVersions[0]
+ : null}
+
+
+
{gameVersions?.sort(compareSemverDesc).map((version) => (
- v === version)}
+ {
- if (checked) {
- addGameVersion(version);
- } else {
- removeGameVersion(version);
- }
- }}
- onSelect={(e) => e.preventDefault()}
+ onClick={() =>
+ selectedGameVersions.includes(version)
+ ? removeGameVersion(version)
+ : addGameVersion(version)
+ }
+ value={version}
>
{version}
-
+
))}
-
-
-
- 0
- ? "text-foreground"
- : "text-transparent",
- )}
- >
+
+
+
+
Mod Tag(s)
- {selectedModTags.length > 0
- ? selectedModTags.length > 1
- ? `${selectedModTags.length} tags`
- : selectedModTags[0].name
- : "-"}
-
-
-
+
+ {selectedModTags.length > 0
+ ? selectedModTags.length > 1
+ ? `${selectedModTags.length} tags`
+ : selectedModTags[0].name
+ : null}
+
+
+
{modTags
?.sort((a, b) => a.name.localeCompare(b.name))
.map((tag) => (
- t.tagid === tag.tagid)
- }
+ {
- if (checked) {
- addModTag(tag);
- } else {
- removeModTag(tag);
- }
- }}
- onSelect={(e) => e.preventDefault()}
+ onClick={() =>
+ selectedModTags.includes(tag)
+ ? removeModTag(tag)
+ : addModTag(tag)
+ }
+ value={tag}
>
{tag.name}
-
+
))}
-
-
+
+
Sort by
@@ -231,7 +205,7 @@ function RouteComponent() {
? `${sortOptions[sortBy as keyof typeof sortOptions]}`
: "Sort by"}
-
+
{Object.entries(sortOptions).map(([key, value]) => (
{value}
@@ -255,7 +229,7 @@ function RouteComponent() {
? `${categoryOptions[category as keyof typeof categoryOptions]}`
: "Category"}
-
+
{Object.entries(categoryOptions).map(([key, value]) => (
{value}
From b5d3684fd8b197169a07753bad0aca66e0bff14d Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:17:16 +0100
Subject: [PATCH 072/100] =?UTF-8?q?refactor(addinstallation.dialog):=20?=
=?UTF-8?q?=E2=9C=A8=20update=20`SelectContent`=20alignment=20for=20improv?=
=?UTF-8?q?ed=20UI?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Set `alignItemWithTrigger` to `false` for better alignment of dropdown items.
---
src/components/dialogs/addinstallation.dialog.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/dialogs/addinstallation.dialog.tsx b/src/components/dialogs/addinstallation.dialog.tsx
index 24c6f0d..94ab4dc 100644
--- a/src/components/dialogs/addinstallation.dialog.tsx
+++ b/src/components/dialogs/addinstallation.dialog.tsx
@@ -429,7 +429,7 @@ export function AddInstallationDialog({
)}
-
+
{gameVersions?.sort(compareSemverDesc).map((version) => (
Date: Tue, 28 Oct 2025 13:17:21 +0100
Subject: [PATCH 073/100] =?UTF-8?q?refactor(addmod.dialog):=20=E2=9C=A8=20?=
=?UTF-8?q?update=20`SelectContent`=20alignment=20for=20improved=20UI?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Adjusted `SelectContent` to align items with the trigger for better visual consistency.
---
src/components/dialogs/addmod.dialog.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/dialogs/addmod.dialog.tsx b/src/components/dialogs/addmod.dialog.tsx
index ba3d7cf..a407450 100644
--- a/src/components/dialogs/addmod.dialog.tsx
+++ b/src/components/dialogs/addmod.dialog.tsx
@@ -160,7 +160,7 @@ export function AddModDialog({
)}
-
+
{modInfo?.mod.releases.map((release) => (
From adf1cefcf9d858ec75c5e97f1d1cf8959bce1136 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:17:26 +0100
Subject: [PATCH 074/100] =?UTF-8?q?refactor(addserver.dialog):=20=E2=9C=A8?=
=?UTF-8?q?=20update=20`SelectContent`=20alignment=20for=20consistency?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Adjusted `SelectContent` to align items with the trigger for improved UI consistency.
---
src/components/dialogs/addserver.dialog.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/dialogs/addserver.dialog.tsx b/src/components/dialogs/addserver.dialog.tsx
index db41b09..af9f0a9 100644
--- a/src/components/dialogs/addserver.dialog.tsx
+++ b/src/components/dialogs/addserver.dialog.tsx
@@ -393,7 +393,7 @@ export function AddServerDialog({
? `${installations.find((inst) => inst.id.toString() === field.state.value)?.name} (${installations.find((inst) => inst.id.toString() === field.state.value)?.version})`
: "Game installation"}
-
+
{installations
?.sort((a, b) => a.index - b.index)
.map((installation) => (
From 6ed5a424efbaef26dce34f3cdcbcae9c1ce31c9f Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:17:32 +0100
Subject: [PATCH 075/100] =?UTF-8?q?refactor(addversion.dialog):=20?=
=?UTF-8?q?=E2=9C=A8=20update=20`SelectContent`=20alignment=20for=20improv?=
=?UTF-8?q?ed=20UI?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Adjusted `SelectContent` to align items with the trigger for better visual consistency.
---
src/components/dialogs/addversion.dialog.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/dialogs/addversion.dialog.tsx b/src/components/dialogs/addversion.dialog.tsx
index ea8e4a0..96ebb07 100644
--- a/src/components/dialogs/addversion.dialog.tsx
+++ b/src/components/dialogs/addversion.dialog.tsx
@@ -141,7 +141,7 @@ export function AddVersionDialog({ open }: { open: boolean }) {
{field.state.value ?? "Game version"}
-
+
{availableVersions
?.sort(compareSemverDesc)
.map((version) => (
From cb1c0de4698bcf18fcdf7241babbac5028c3e904 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:17:41 +0100
Subject: [PATCH 076/100] =?UTF-8?q?refactor(connectserver.dialog):=20?=
=?UTF-8?q?=E2=9C=A8=20update=20`SelectContent`=20alignment=20for=20consis?=
=?UTF-8?q?tency?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Adjusted `SelectContent` to align items with the trigger for improved UI consistency.
---
src/components/dialogs/connectserver.dialog.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/dialogs/connectserver.dialog.tsx b/src/components/dialogs/connectserver.dialog.tsx
index 6b73a70..0104cc7 100644
--- a/src/components/dialogs/connectserver.dialog.tsx
+++ b/src/components/dialogs/connectserver.dialog.tsx
@@ -58,7 +58,7 @@ export function ConnectServerDialog({
{installations.find((i) => i.id === selectedInstallation)?.name ||
"Select an installation"}
-
+
{installations
.filter((i) => i.version === server.gameVersion)
.map((installation) => (
From 91f3a6660780d3d56f3067eb34e8b45d7e8264b8 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:18:25 +0100
Subject: [PATCH 077/100] =?UTF-8?q?refactor(editinstallation.dialog):=20?=
=?UTF-8?q?=E2=9C=A8=20update=20`SelectContent`=20alignment=20for=20consis?=
=?UTF-8?q?tency?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Adjusted `SelectContent` to align items with the trigger for improved UI consistency.
---
src/components/dialogs/editinstallation.dialog.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/dialogs/editinstallation.dialog.tsx b/src/components/dialogs/editinstallation.dialog.tsx
index ab8a576..51a4255 100644
--- a/src/components/dialogs/editinstallation.dialog.tsx
+++ b/src/components/dialogs/editinstallation.dialog.tsx
@@ -381,7 +381,7 @@ export function EditInstallationDialog({
)}
-
+
{gameVersions?.sort(compareSemverDesc).map((version) => (
Date: Tue, 28 Oct 2025 13:18:36 +0100
Subject: [PATCH 078/100] =?UTF-8?q?refactor(editserver.dialog):=20?=
=?UTF-8?q?=E2=9C=A8=20update=20`SelectContent`=20alignment=20for=20consis?=
=?UTF-8?q?tency?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Adjusted `SelectContent` to align items with the trigger for improved UI consistency.
---
src/components/dialogs/editserver.dialog.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/dialogs/editserver.dialog.tsx b/src/components/dialogs/editserver.dialog.tsx
index c802c06..7a0e561 100644
--- a/src/components/dialogs/editserver.dialog.tsx
+++ b/src/components/dialogs/editserver.dialog.tsx
@@ -342,7 +342,7 @@ export function EditServerDialog({
? `${installations.find((inst) => inst.id.toString() === field.state.value)?.name} (${installations.find((inst) => inst.id.toString() === field.state.value)?.version})`
: "Game installation"}
-
+
{installations
?.sort((a, b) => a.index - b.index)
.map((installation) => (
From 89f005abe9fe4437ec4f0352bffdf61047776b2b Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:18:49 +0100
Subject: [PATCH 079/100] =?UTF-8?q?refactor(editworld.dialog):=20=E2=9C=A8?=
=?UTF-8?q?=20update=20`SelectContent`=20alignment=20for=20consistency?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Adjusted `SelectContent` to align items with the trigger for improved UI consistency.
---
src/components/dialogs/editworld.dialog.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/dialogs/editworld.dialog.tsx b/src/components/dialogs/editworld.dialog.tsx
index 57186b3..42d3e45 100644
--- a/src/components/dialogs/editworld.dialog.tsx
+++ b/src/components/dialogs/editworld.dialog.tsx
@@ -195,7 +195,7 @@ export function EditWorldDialog({
? `${installations.find((inst) => inst.id.toString() === field.state.value)?.name} (${installations.find((inst) => inst.id.toString() === field.state.value)?.version})`
: "Game installation"}
-
+
{installations
?.sort((a, b) => a.index - b.index)
.map((installation) => (
From 8ac7b8c0ae8b35679b2dbf053e24a5b8d93ad18d Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:18:54 +0100
Subject: [PATCH 080/100] =?UTF-8?q?refactor(updatemod.dialog):=20=E2=9C=A8?=
=?UTF-8?q?=20update=20`SelectContent`=20alignment=20for=20consistency?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Adjusted `SelectContent` to align items with the trigger for improved UI consistency.
---
src/components/dialogs/updatemod.dialog.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/dialogs/updatemod.dialog.tsx b/src/components/dialogs/updatemod.dialog.tsx
index b3acf8b..11e488f 100644
--- a/src/components/dialogs/updatemod.dialog.tsx
+++ b/src/components/dialogs/updatemod.dialog.tsx
@@ -229,7 +229,7 @@ export function UpdateModDialog({
)}
-
+
{modInfo?.mod.releases.map((release) => (
From f45bf98570ab27a1e2e42a5f216627afa879d532 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:18:59 +0100
Subject: [PATCH 081/100] =?UTF-8?q?refactor(viewmap.dialog):=20=E2=9C=A8?=
=?UTF-8?q?=20update=20`SelectContent`=20alignment=20for=20consistency?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Adjusted `SelectContent` to align with the trigger for improved UI consistency.
---
src/components/dialogs/viewmap.dialog.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/dialogs/viewmap.dialog.tsx b/src/components/dialogs/viewmap.dialog.tsx
index 6c6341f..1e909bc 100644
--- a/src/components/dialogs/viewmap.dialog.tsx
+++ b/src/components/dialogs/viewmap.dialog.tsx
@@ -83,7 +83,7 @@ export function ViewMapDialog({
? `Viewing markers for: ${selectedPlayer}`
: "Select Player"}
-
+
{players.map((playerUid) => (
{playerUid}
From ea936c98c7ad5374a1076fb0e249ece99767beac Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:28:18 +0100
Subject: [PATCH 082/100] =?UTF-8?q?refactor(dialog):=20=E2=9C=A8=20remove?=
=?UTF-8?q?=20unused=20`"use=20client"`=20directive?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Cleaned up the code by removing the unnecessary `"use client"` directive.
* This change helps in maintaining a cleaner and more efficient codebase.
---
src/components/ui/dialog.tsx | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx
index 08b5f38..c1d863c 100644
--- a/src/components/ui/dialog.tsx
+++ b/src/components/ui/dialog.tsx
@@ -1,5 +1,3 @@
-"use client";
-
import { Dialog as DialogPrimitive } from "@base-ui-components/react/dialog";
import { XIcon } from "lucide-react";
From 9c9fa01a91e2007fa3a1cc654d06174d6c4a8120 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:41:22 +0100
Subject: [PATCH 083/100] =?UTF-8?q?refactor(dashboard):=20=E2=9C=A8=20add?=
=?UTF-8?q?=20`z-10`=20class=20to=20sticky=20links=20for=20improved=20laye?=
=?UTF-8?q?ring?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Ensures that the installation and server links remain above other content.
---
src/routes/index.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
index 937a588..2bcbea7 100644
--- a/src/routes/index.tsx
+++ b/src/routes/index.tsx
@@ -83,7 +83,7 @@ function Dashboard() {
{installations.length > 0 ? (
-
+
{servers.length > 0 ? (
-
+
Date: Tue, 28 Oct 2025 13:41:32 +0100
Subject: [PATCH 084/100] =?UTF-8?q?refactor(app.sidebar):=20=E2=9C=A8=20re?=
=?UTF-8?q?place=20`DropdownMenu`=20with=20`Menu`=20for=20improved=20UI=20?=
=?UTF-8?q?consistency?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Updated the sidebar component to use `Menu` instead of `DropdownMenu`.
* Adjusted the button rendering logic within the menu trigger.
* Enhanced the overall user experience by streamlining the menu structure.
---
src/components/sidebars/app.sidebar.tsx | 34 ++++++++++++-------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/components/sidebars/app.sidebar.tsx b/src/components/sidebars/app.sidebar.tsx
index 3b72f61..a65ed41 100644
--- a/src/components/sidebars/app.sidebar.tsx
+++ b/src/components/sidebars/app.sidebar.tsx
@@ -16,11 +16,6 @@ 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 { Group, GroupItem, GroupSeparator } from "@/components/ui/group";
import {
Sidebar,
@@ -47,6 +42,7 @@ import { useAccountStore } from "@/stores/accounts";
import { useDialogStore } from "@/stores/dialogs";
import { useInstallations } from "@/stores/installations";
import { useServerStore } from "@/stores/servers";
+import { Menu, MenuPopup, MenuTrigger } from "../ui/menu";
export function AppSidebar() {
const { selectedUser, users, removeUser, setSelectedUser } =
@@ -88,8 +84,16 @@ export function AppSidebar() {
{selectedUser ? (
-
-
+
+ !selectedUser && openDialog("AddUserDialog")}
+ variant="outline"
+ />
+ }
+ >
{selectedUser ? (
@@ -101,17 +105,13 @@ export function AppSidebar() {
{selectedUser.playername}
) : (
- openDialog("AddUserDialog")}
- variant="outline"
- >
+ <>
Sign in
-
+ >
)}
-
-
+
+
{users.map((user) => (
Add user
-
-
+
+
) : (
Date: Tue, 28 Oct 2025 13:41:39 +0100
Subject: [PATCH 085/100] =?UTF-8?q?refactor(menu):=20=E2=9C=A8=20implement?=
=?UTF-8?q?=20`Menu`=20component=20replacing=20`DropdownMenu`?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Introduced a new `Menu` component utilizing `@base-ui-components/react/menu`.
* Removed the old `DropdownMenu` implementation to streamline the UI components.
* Ensured consistent styling and functionality with the new menu structure.
---
src/components/ui/dropdown-menu.tsx | 260 ----------------------------
src/components/ui/menu.tsx | 255 +++++++++++++++++++++++++++
2 files changed, 255 insertions(+), 260 deletions(-)
delete mode 100644 src/components/ui/dropdown-menu.tsx
create mode 100644 src/components/ui/menu.tsx
diff --git a/src/components/ui/dropdown-menu.tsx b/src/components/ui/dropdown-menu.tsx
deleted file mode 100644
index 4ab5744..0000000
--- a/src/components/ui/dropdown-menu.tsx
+++ /dev/null
@@ -1,260 +0,0 @@
-import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
-import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
-import type * as React from "react";
-
-import { cn } from "@/lib/utils";
-
-function DropdownMenu({
- ...props
-}: React.ComponentProps) {
- return ;
-}
-
-function DropdownMenuPortal({
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function DropdownMenuTrigger({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function DropdownMenuContent({
- className,
- sideOffset = 4,
- ...props
-}: React.ComponentProps) {
- return (
-
-
-
- );
-}
-
-function DropdownMenuGroup({
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function DropdownMenuItem({
- className,
- inset,
- variant = "default",
- ...props
-}: React.ComponentProps & {
- inset?: boolean;
- variant?: "default" | "destructive";
-}) {
- return (
-
- );
-}
-
-function DropdownMenuCheckboxItem({
- className,
- children,
- checked,
- ...props
-}: React.ComponentProps) {
- return (
-
-
-
-
-
-
- {children}
-
- );
-}
-
-function DropdownMenuRadioGroup({
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function DropdownMenuRadioItem({
- className,
- children,
- ...props
-}: React.ComponentProps) {
- return (
-
-
-
-
-
-
- {children}
-
- );
-}
-
-function DropdownMenuLabel({
- className,
- inset,
- ...props
-}: React.ComponentProps & {
- inset?: boolean;
-}) {
- return (
-
- );
-}
-
-function DropdownMenuSeparator({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function DropdownMenuShortcut({
- className,
- ...props
-}: React.ComponentProps<"span">) {
- return (
-
- );
-}
-
-function DropdownMenuSub({
- ...props
-}: React.ComponentProps) {
- return ;
-}
-
-function DropdownMenuSubTrigger({
- className,
- inset,
- children,
- ...props
-}: React.ComponentProps & {
- inset?: boolean;
-}) {
- return (
-
- {children}
-
-
- );
-}
-
-function DropdownMenuSubContent({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-export {
- DropdownMenu,
- DropdownMenuPortal,
- DropdownMenuTrigger,
- DropdownMenuContent,
- DropdownMenuGroup,
- DropdownMenuLabel,
- DropdownMenuItem,
- DropdownMenuCheckboxItem,
- DropdownMenuRadioGroup,
- DropdownMenuRadioItem,
- DropdownMenuSeparator,
- DropdownMenuShortcut,
- DropdownMenuSub,
- DropdownMenuSubTrigger,
- DropdownMenuSubContent,
-};
diff --git a/src/components/ui/menu.tsx b/src/components/ui/menu.tsx
new file mode 100644
index 0000000..41066a4
--- /dev/null
+++ b/src/components/ui/menu.tsx
@@ -0,0 +1,255 @@
+import { Menu as MenuPrimitive } from "@base-ui-components/react/menu";
+import { CheckIcon, ChevronRightIcon } from "lucide-react";
+import type * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+const Menu = MenuPrimitive.Root;
+
+const MenuPortal = MenuPrimitive.Portal;
+
+function MenuTrigger(props: MenuPrimitive.Trigger.Props) {
+ return ;
+}
+
+function MenuPopup({
+ className,
+ sideOffset = 4,
+ align = "center",
+ alignOffset = 0,
+ side = "bottom",
+ ...props
+}: MenuPrimitive.Popup.Props & {
+ align?: MenuPrimitive.Positioner.Props["align"];
+ sideOffset?: MenuPrimitive.Positioner.Props["sideOffset"];
+ alignOffset?: MenuPrimitive.Positioner.Props["alignOffset"];
+ side?: MenuPrimitive.Positioner.Props["side"];
+}) {
+ return (
+
+
+
+
+
+
+
+ );
+}
+
+function MenuGroup(props: MenuPrimitive.Group.Props) {
+ return ;
+}
+
+function MenuItem({
+ className,
+ inset,
+ variant = "default",
+ ...props
+}: MenuPrimitive.Item.Props & {
+ inset?: boolean;
+ variant?: "default" | "destructive";
+}) {
+ return (
+
+ );
+}
+
+function MenuCheckboxItem({
+ className,
+ children,
+ checked,
+ ...props
+}: MenuPrimitive.CheckboxItem.Props) {
+ return (
+
+
+
+
+ {children}
+
+ );
+}
+
+function MenuRadioGroup(props: MenuPrimitive.RadioGroup.Props) {
+ return ;
+}
+
+function MenuRadioItem({
+ className,
+ children,
+ ...props
+}: MenuPrimitive.RadioItem.Props) {
+ return (
+
+
+
+
+ {children}
+
+ );
+}
+
+function MenuGroupLabel({
+ className,
+ inset,
+ ...props
+}: MenuPrimitive.GroupLabel.Props & {
+ inset?: boolean;
+}) {
+ return (
+
+ );
+}
+
+function MenuSeparator({ className, ...props }: MenuPrimitive.Separator.Props) {
+ return (
+
+ );
+}
+
+function MenuShortcut({ className, ...props }: React.ComponentProps<"span">) {
+ return (
+
+ );
+}
+
+function MenuSub(props: MenuPrimitive.SubmenuRoot.Props) {
+ return ;
+}
+
+function MenuSubTrigger({
+ className,
+ inset,
+ children,
+ ...props
+}: MenuPrimitive.SubmenuTrigger.Props & {
+ inset?: boolean;
+}) {
+ return (
+
+ {children}
+
+
+ );
+}
+
+function MenuSubPopup({
+ className,
+ sideOffset = 0,
+ alignOffset = -4,
+ align = "start",
+ ...props
+}: MenuPrimitive.Popup.Props & {
+ align?: MenuPrimitive.Positioner.Props["align"];
+ sideOffset?: MenuPrimitive.Positioner.Props["sideOffset"];
+ alignOffset?: MenuPrimitive.Positioner.Props["alignOffset"];
+}) {
+ return (
+
+ );
+}
+
+export {
+ Menu,
+ Menu as DropdownMenu,
+ MenuPortal,
+ MenuPortal as DropdownMenuPortal,
+ MenuTrigger,
+ MenuTrigger as DropdownMenuTrigger,
+ MenuPopup,
+ MenuPopup as DropdownMenuContent,
+ MenuGroup,
+ MenuGroup as DropdownMenuGroup,
+ MenuItem,
+ MenuItem as DropdownMenuItem,
+ MenuCheckboxItem,
+ MenuCheckboxItem as DropdownMenuCheckboxItem,
+ MenuRadioGroup,
+ MenuRadioGroup as DropdownMenuRadioGroup,
+ MenuRadioItem,
+ MenuRadioItem as DropdownMenuRadioItem,
+ MenuGroupLabel,
+ MenuGroupLabel as DropdownMenuLabel,
+ MenuSeparator,
+ MenuSeparator as DropdownMenuSeparator,
+ MenuShortcut,
+ MenuShortcut as DropdownMenuShortcut,
+ MenuSub,
+ MenuSub as DropdownMenuSub,
+ MenuSubTrigger,
+ MenuSubTrigger as DropdownMenuSubTrigger,
+ MenuSubPopup,
+ MenuSubPopup as DropdownMenuSubContent,
+};
From 9105c323353d6b8c51797c1ac972b6b10ce549e4 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:41:44 +0100
Subject: [PATCH 086/100] =?UTF-8?q?refactor(scroll-area):=20=E2=9C=A8=20up?=
=?UTF-8?q?date=20`ScrollArea`=20and=20`ScrollBar`=20components=20for=20im?=
=?UTF-8?q?proved=20functionality?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Replace `@radix-ui/react-scroll-area` with `@base-ui-components/react/scroll-area`
* Enhance `ScrollArea` to support `orientation` prop for better scroll behavior
* Refactor `ScrollBar` to improve styling and responsiveness
---
src/components/ui/scroll-area.tsx | 46 +++++++++++++++++--------------
1 file changed, 25 insertions(+), 21 deletions(-)
diff --git a/src/components/ui/scroll-area.tsx b/src/components/ui/scroll-area.tsx
index 6977416..c07c2eb 100644
--- a/src/components/ui/scroll-area.tsx
+++ b/src/components/ui/scroll-area.tsx
@@ -1,27 +1,35 @@
-import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
-import type * as React from "react";
+import { ScrollArea as ScrollAreaPrimitive } from "@base-ui-components/react/scroll-area";
import { cn } from "@/lib/utils";
function ScrollArea({
className,
children,
+ orientation,
...props
-}: React.ComponentProps) {
+}: ScrollAreaPrimitive.Root.Props & {
+ orientation?: "horizontal" | "vertical" | "both";
+}) {
return (
-
+
{children}
-
-
+ {orientation === "both" ? (
+ <>
+
+
+ >
+ ) : (
+
+ )}
+
);
}
@@ -30,26 +38,22 @@ function ScrollBar({
className,
orientation = "vertical",
...props
-}: React.ComponentProps) {
+}: ScrollAreaPrimitive.Scrollbar.Props) {
return (
-
-
-
+
);
}
From d7da90962e334f1a964176621df946760cdf96f2 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 13:44:12 +0100
Subject: [PATCH 087/100] =?UTF-8?q?refactor(popover):=20=E2=9C=A8=20remove?=
=?UTF-8?q?=20`Popover`=20component=20and=20related=20files?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Deleted the `Popover` component and its associated files to streamline the codebase.
* Updated `TooltipProvider` usage in `SidebarProvider` for consistency.
* Adjusted `TooltipTrigger` in `SidebarMenuButton` to use `render` prop instead of `asChild`.
---
bun.lock | 36 ---------------------------
package.json | 4 ---
src/components/ui/popover.tsx | 46 -----------------------------------
src/components/ui/sidebar.tsx | 4 +--
4 files changed, 2 insertions(+), 88 deletions(-)
delete mode 100644 src/components/ui/popover.tsx
diff --git a/bun.lock b/bun.lock
index c3d28bf..9c8fcf4 100644
--- a/bun.lock
+++ b/bun.lock
@@ -10,10 +10,6 @@
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@monaco-editor/react": "^4.7.0",
- "@radix-ui/react-dropdown-menu": "^2.1.16",
- "@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",
"@tailwindcss/vite": "^4.1.16",
"@tanstack/react-devtools": "^0.7.8",
@@ -235,50 +231,28 @@
"@monaco-editor/react": ["@monaco-editor/react@4.7.0", "", { "dependencies": { "@monaco-editor/loader": "^1.5.0" }, "peerDependencies": { "monaco-editor": ">= 0.25.0 < 1", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA=="],
- "@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="],
-
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
- "@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-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=="],
"@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="],
"@radix-ui/react-dialog": ["@radix-ui/react-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-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-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-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="],
- "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="],
-
"@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "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-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="],
- "@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.16", "", { "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-id": "1.1.1", "@radix-ui/react-menu": "2.1.16", "@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-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw=="],
-
"@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="],
"@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "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-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
"@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-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=="],
-
- "@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.8", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@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-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "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-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw=="],
-
"@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@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-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="],
"@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@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-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="],
"@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@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-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
- "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.11", "", { "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-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@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-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA=="],
-
- "@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.10", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@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-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@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-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A=="],
-
- "@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-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-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=="],
@@ -291,16 +265,6 @@
"@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=="],
-
- "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.1", "", { "dependencies": { "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w=="],
-
- "@radix-ui/react-use-size": ["@radix-ui/react-use-size@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-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="],
-
- "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.3", "", { "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-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug=="],
-
- "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="],
-
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.43", "", {}, "sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.50.0", "", { "os": "android", "cpu": "arm" }, "sha512-lVgpeQyy4fWN5QYebtW4buT/4kn4p4IJ+kDNB4uYNT5b8c8DLJDg6titg20NIg7E8RWwdWZORW6vUFfrLyG3KQ=="],
diff --git a/package.json b/package.json
index b7ab955..7d7f9ce 100644
--- a/package.json
+++ b/package.json
@@ -6,10 +6,6 @@
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@monaco-editor/react": "^4.7.0",
- "@radix-ui/react-dropdown-menu": "^2.1.16",
- "@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",
"@tailwindcss/vite": "^4.1.16",
"@tanstack/react-devtools": "^0.7.8",
diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover.tsx
deleted file mode 100644
index 16d3d37..0000000
--- a/src/components/ui/popover.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import * as PopoverPrimitive from "@radix-ui/react-popover";
-import type * as React from "react";
-
-import { cn } from "@/lib/utils";
-
-function Popover({
- ...props
-}: React.ComponentProps) {
- return ;
-}
-
-function PopoverTrigger({
- ...props
-}: React.ComponentProps) {
- return ;
-}
-
-function PopoverContent({
- className,
- align = "center",
- sideOffset = 4,
- ...props
-}: React.ComponentProps) {
- return (
-
-
-
- );
-}
-
-function PopoverAnchor({
- ...props
-}: React.ComponentProps) {
- return ;
-}
-
-export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx
index ed9d7df..cdc9ab5 100644
--- a/src/components/ui/sidebar.tsx
+++ b/src/components/ui/sidebar.tsx
@@ -128,7 +128,7 @@ function SidebarProvider({
return (
-
+
-
{button}
+
Date: Tue, 28 Oct 2025 13:56:23 +0100
Subject: [PATCH 088/100] =?UTF-8?q?refactor(public-servers):=20=E2=9C=A8?=
=?UTF-8?q?=20update=20`SelectTrigger`=20class=20for=20improved=20styling?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Added `className="flex gap-1 w-36 truncate"` to `SelectTrigger` for better layout and responsiveness.
---
src/routes/public-servers.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/routes/public-servers.tsx b/src/routes/public-servers.tsx
index 3d8957d..cbb75ed 100644
--- a/src/routes/public-servers.tsx
+++ b/src/routes/public-servers.tsx
@@ -93,7 +93,7 @@ function RouteComponent() {
}
value={sortBy}
>
-
+
{sortBy
? `${sortOptions[sortBy as keyof typeof sortOptions]}`
: "Sort by"}
From 429893c0e53754bcd8d516877357ca6fa3c8dc12 Mon Sep 17 00:00:00 2001
From: Mike Kold Hermann
Date: Tue, 28 Oct 2025 21:49:54 +0100
Subject: [PATCH 089/100] =?UTF-8?q?refactor(dialogs):=20=E2=9C=A8=20reorga?=
=?UTF-8?q?nize=20`DeleteVersionDialog`=20component=20structure?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Moved the `motion.div` for the note inside the `AlertDialogDescription` for better readability.
* Improved the layout of the dialog content while maintaining functionality.
---
.../dialogs/deleteversion.dialog.tsx | 28 +++++++++----------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/components/dialogs/deleteversion.dialog.tsx b/src/components/dialogs/deleteversion.dialog.tsx
index 7e61270..e4b5b84 100644
--- a/src/components/dialogs/deleteversion.dialog.tsx
+++ b/src/components/dialogs/deleteversion.dialog.tsx
@@ -67,22 +67,22 @@ export function DeleteVersionDialog({
This action cannot be undone. This will permanently delete version{" "}
{version} from Story Forge.
-
- Note:
-
- Deleting versions that are currently in use by installations will
- not harm these installations or their servers. However, you will
- not be able to create new installations with this version until
- you reinstall it.
-
+
+ Note:
+
+ Deleting versions that are currently in use by installations will not
+ harm these installations or their servers. However, you will not be
+ able to create new installations with this version until you reinstall
+ it.
+
Date: Tue, 28 Oct 2025 21:50:09 +0100
Subject: [PATCH 090/100] =?UTF-8?q?refactor(dialogs):=20=E2=9C=A8=20improv?=
=?UTF-8?q?e=20`DeleteWorldDialog`=20structure=20and=20user=20confirmation?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Reorganized the layout for better readability.
* Added detailed world information before deletion confirmation.
* Included a checkbox for user acknowledgment of irreversible action.
---
src/components/dialogs/deleteworld.dialog.tsx | 146 +++++++++---------
1 file changed, 72 insertions(+), 74 deletions(-)
diff --git a/src/components/dialogs/deleteworld.dialog.tsx b/src/components/dialogs/deleteworld.dialog.tsx
index fa6277f..f311e48 100644
--- a/src/components/dialogs/deleteworld.dialog.tsx
+++ b/src/components/dialogs/deleteworld.dialog.tsx
@@ -75,82 +75,80 @@ export function DeleteWorldDialog({
This action cannot be undone. This will permanently delete world{" "}
{world.data.world_name} {" "}
from Story Forge.
-
-
- Warning: This will delete the world from your computer.
- If you want to keep a backup, make sure to export it before
- proceeding.
-
-
- World info:
-
-
-
- World name: {world.data.world_name}
-
-
- Map identifier: {world.data.savegame_identifier}
-
-
- World type: {world.data.world_type}
-
-
- Play style: {world.data.play_style}
-
-
- Created by: {world.data.created_by_player_name}
-
-
- Last played:{" "}
-
- {world.data.last_played
- ? formatDistanceToNow(new Date(world.data.last_played), {
- addSuffix: true,
- })
- : "Never"}
-
-
-
- Last session:{" "}
-
- {formatDistance(
- new Date(),
- addSeconds(new Date(), world.data.total_seconds_played),
- )}
-
-
-
- Seed: {world.data.seed}
-
-
- Created in version: {world.data.created_game_version}
-
-
- Last saved in version:{" "}
- {world.data.last_saved_game_version}
-
-
-
- {/* Add a checkbox asking if they're absolutely sure */}
-
- setSure(!!v)}
- />
-
- I understand that this action cannot be undone.
-
-
+
+
+ Warning: This will delete the world from your computer. If
+ you want to keep a backup, make sure to export it before proceeding.
+
+
+ World info:
+
+
+
+ World name: {world.data.world_name}
+
+
+ Map identifier: {world.data.savegame_identifier}
+
+
+ World type: {world.data.world_type}
+
+
+ Play style: {world.data.play_style}
+
+
+ Created by: {world.data.created_by_player_name}
+
+
+ Last played:{" "}
+
+ {world.data.last_played
+ ? formatDistanceToNow(new Date(world.data.last_played), {
+ addSuffix: true,
+ })
+ : "Never"}
+
+
+
+ Last session:{" "}
+
+ {formatDistance(
+ new Date(),
+ addSeconds(new Date(), world.data.total_seconds_played),
+ )}
+
+
+
+ Seed: {world.data.seed}
+
+
+ Created in version: {world.data.created_game_version}
+
+
+ Last saved in version: {world.data.last_saved_game_version}
+
+
+
+ {/* Add a checkbox asking if they're absolutely sure */}
+
+ setSure(!!v)}
+ />
+
+ I understand that this action cannot be undone.
+
+
Date: Wed, 29 Oct 2025 08:10:05 +0100
Subject: [PATCH 091/100] =?UTF-8?q?refactor(command):=20=F0=9F=97=91?=
=?UTF-8?q?=EF=B8=8F=20remove=20`Command`=20component=20and=20related=20fi?=
=?UTF-8?q?les?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Eliminated the entire `Command` component and its associated functionalities.
* This cleanup helps streamline the codebase and reduces unnecessary complexity.
---
biome.json | 2 +-
bun.lock | 123 ++----
package.json | 25 +-
src/components/ui/command.tsx | 194 ---------
src/components/ui/multi-select.tsx | 653 -----------------------------
5 files changed, 48 insertions(+), 949 deletions(-)
delete mode 100644 src/components/ui/command.tsx
delete mode 100644 src/components/ui/multi-select.tsx
diff --git a/biome.json b/biome.json
index e4a0f4d..ed30ebd 100644
--- a/biome.json
+++ b/biome.json
@@ -1,5 +1,5 @@
{
- "$schema": "https://biomejs.dev/schemas/2.3.0/schema.json",
+ "$schema": "https://biomejs.dev/schemas/2.3.2/schema.json",
"assist": {
"actions": {
"source": {
diff --git a/bun.lock b/bun.lock
index 9c8fcf4..ae8d36e 100644
--- a/bun.lock
+++ b/bun.lock
@@ -31,7 +31,6 @@
"@tauri-store/zustand": "^1.0.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
- "cmdk": "^1.1.1",
"date-fns": "^4.1.0",
"input-otp": "^1.4.2",
"lucide-react": "^0.548.0",
@@ -129,23 +128,23 @@
"@base-ui-components/utils": ["@base-ui-components/utils@0.1.2", "", { "dependencies": { "@babel/runtime": "^7.28.4", "@floating-ui/utils": "^0.2.10", "reselect": "^5.1.1", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@types/react": "^17 || ^18 || ^19", "react": "^17 || ^18 || ^19", "react-dom": "^17 || ^18 || ^19" }, "optionalPeers": ["@types/react"] }, "sha512-aEitDGpMsYO2qnSpYOwZNykn9Rzn2ioyEVk2fyDRH7t+TIHVKpp9CeV7SPTq43M9mMSDxQ+7UeZJVkrj2dCVIQ=="],
- "@biomejs/biome": ["@biomejs/biome@2.3.0", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.0", "@biomejs/cli-darwin-x64": "2.3.0", "@biomejs/cli-linux-arm64": "2.3.0", "@biomejs/cli-linux-arm64-musl": "2.3.0", "@biomejs/cli-linux-x64": "2.3.0", "@biomejs/cli-linux-x64-musl": "2.3.0", "@biomejs/cli-win32-arm64": "2.3.0", "@biomejs/cli-win32-x64": "2.3.0" }, "bin": { "biome": "bin/biome" } }, "sha512-shdUY5H3S3tJVUWoVWo5ua+GdPW5lRHf+b0IwZ4OC1o2zOKQECZ6l2KbU6t89FNhtd3Qx5eg5N7/UsQWGQbAFw=="],
+ "@biomejs/biome": ["@biomejs/biome@2.3.2", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.2", "@biomejs/cli-darwin-x64": "2.3.2", "@biomejs/cli-linux-arm64": "2.3.2", "@biomejs/cli-linux-arm64-musl": "2.3.2", "@biomejs/cli-linux-x64": "2.3.2", "@biomejs/cli-linux-x64-musl": "2.3.2", "@biomejs/cli-win32-arm64": "2.3.2", "@biomejs/cli-win32-x64": "2.3.2" }, "bin": { "biome": "bin/biome" } }, "sha512-8e9tzamuDycx7fdrcJ/F/GDZ8SYukc5ud6tDicjjFqURKYFSWMl0H0iXNXZEGmcmNUmABgGuHThPykcM41INgg=="],
- "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.3.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-3cJVT0Z5pbTkoBmbjmDZTDFYxIkRcrs9sYVJbIBHU8E6qQxgXAaBfSVjjCreG56rfDuQBr43GzwzmaHPcu4vlw=="],
+ "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.3.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-4LECm4kc3If0JISai4c3KWQzukoUdpxy4fRzlrPcrdMSRFksR9ZoXK7JBcPuLBmd2SoT4/d7CQS33VnZpgBjew=="],
- "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.3.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-6LIkhglh3UGjuDqJXsK42qCA0XkD1Ke4K/raFOii7QQPbM8Pia7Qj2Hji4XuF2/R78hRmEx7uKJH3t/Y9UahtQ=="],
+ "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.3.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-jNMnfwHT4N3wi+ypRfMTjLGnDmKYGzxVr1EYAPBcauRcDnICFXN81wD6wxJcSUrLynoyyYCdfW6vJHS/IAoTDA=="],
- "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.3.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-uhAsbXySX7xsXahegDg5h3CDgfMcRsJvWLFPG0pjkylgBb9lErbK2C0UINW52zhwg0cPISB09lxHPxCau4e2xA=="],
+ "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.3.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-amnqvk+gWybbQleRRq8TMe0rIv7GHss8mFJEaGuEZYWg1Tw14YKOkeo8h6pf1c+d3qR+JU4iT9KXnBKGON4klw=="],
- "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.3.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-nDksoFdwZ2YrE7NiYDhtMhL2UgFn8Kb7Y0bYvnTAakHnqEdb4lKindtBc1f+xg2Snz0JQhJUYO7r9CDBosRU5w=="],
+ "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.3.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-2Zz4usDG1GTTPQnliIeNx6eVGGP2ry5vE/v39nT73a3cKN6t5H5XxjcEoZZh62uVZvED7hXXikclvI64vZkYqw=="],
- "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.3.0", "", { "os": "linux", "cpu": "x64" }, "sha512-uxa8reA2s1VgoH8MhbGlCmMOt3JuSE1vJBifkh1ulaPiuk0SPx8cCdpnm9NWnTe2x/LfWInWx4sZ7muaXTPGGw=="],
+ "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.3.2", "", { "os": "linux", "cpu": "x64" }, "sha512-8BG/vRAhFz1pmuyd24FQPhNeueLqPtwvZk6yblABY2gzL2H8fLQAF/Z2OPIc+BPIVPld+8cSiKY/KFh6k81xfA=="],
- "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.3.0", "", { "os": "linux", "cpu": "x64" }, "sha512-+i9UcJwl99uAhtRQDz9jUAh+Xkb097eekxs/D9j4deWDg5/yB/jPWzISe1nBHvlzTXsdUSj0VvB4Go2DSpKIMw=="],
+ "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.3.2", "", { "os": "linux", "cpu": "x64" }, "sha512-gzB19MpRdTuOuLtPpFBGrV3Lq424gHyq2lFj8wfX9tvLMLdmA/R9C7k/mqBp/spcbWuHeIEKgEs3RviOPcWGBA=="],
- "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.3.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-ynjmsJLIKrAjC3CCnKMMhzcnNy8dbQWjKfSU5YA0mIruTxBNMbkAJp+Pr2iV7/hFou+66ZSD/WV8hmLEmhUaXA=="],
+ "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.3.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-lCruqQlfWjhMlOdyf5pDHOxoNm4WoyY2vZ4YN33/nuZBRstVDuqPPjS0yBkbUlLEte11FbpW+wWSlfnZfSIZvg=="],
- "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.0", "", { "os": "win32", "cpu": "x64" }, "sha512-zOCYmCRVkWXc9v8P7OLbLlGGMxQTKMvi+5IC4v7O8DkjLCOHRzRVK/Lno2pGZNo0lzKM60pcQOhH8HVkXMQdFg=="],
+ "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.2", "", { "os": "win32", "cpu": "x64" }, "sha512-6Ee9P26DTb4D8sN9nXxgbi9Dw5vSOfH98M7UlmkjKB2vtUbrRqCbZiNfryGiwnPIpd6YUoTl7rLVD2/x1CyEHQ=="],
"@dnd-kit/accessibility": ["@dnd-kit/accessibility@3.1.1", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw=="],
@@ -231,40 +230,10 @@
"@monaco-editor/react": ["@monaco-editor/react@4.7.0", "", { "dependencies": { "@monaco-editor/loader": "^1.5.0" }, "peerDependencies": { "monaco-editor": ">= 0.25.0 < 1", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA=="],
- "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
-
"@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=="],
- "@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="],
-
- "@radix-ui/react-dialog": ["@radix-ui/react-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-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-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-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="],
-
- "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "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-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="],
-
- "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="],
-
- "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "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-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
-
- "@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-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@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-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="],
-
- "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@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-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="],
-
- "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@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-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
-
"@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-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=="],
-
- "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "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-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="],
-
- "@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-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=="],
-
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.43", "", {}, "sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.50.0", "", { "os": "android", "cpu": "arm" }, "sha512-lVgpeQyy4fWN5QYebtW4buT/4kn4p4IJ+kDNB4uYNT5b8c8DLJDg6titg20NIg7E8RWwdWZORW6vUFfrLyG3KQ=="],
@@ -351,7 +320,7 @@
"@tailwindcss/vite": ["@tailwindcss/vite@4.1.16", "", { "dependencies": { "@tailwindcss/node": "4.1.16", "@tailwindcss/oxide": "4.1.16", "tailwindcss": "4.1.16" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-bbguNBcDxsRmi9nnlWJxhfDWamY3lmcyACHcdO1crxfzuLpOhHLLtEIN/nCbbAtj5rchUgQD17QVAKi1f7IsKg=="],
- "@tanstack/devtools": ["@tanstack/devtools@0.6.22", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/keyboard": "^1.3.3", "@solid-primitives/resize-observer": "^2.1.3", "@tanstack/devtools-client": "0.0.3", "@tanstack/devtools-event-bus": "0.3.3", "@tanstack/devtools-ui": "0.4.3", "clsx": "^2.1.1", "goober": "^2.1.16", "solid-js": "^1.9.9" } }, "sha512-G7wZZiZD+pQ7OjN+lQaV7m2fhxHPUmYuOe9wM2d6QqzeI8QCDqjvKqDZLFdcNystyIw+Twf4X1jqJcR1S30ykw=="],
+ "@tanstack/devtools": ["@tanstack/devtools@0.6.23", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/keyboard": "^1.3.3", "@solid-primitives/resize-observer": "^2.1.3", "@tanstack/devtools-client": "0.0.3", "@tanstack/devtools-event-bus": "0.3.3", "@tanstack/devtools-ui": "0.4.4", "clsx": "^2.1.1", "goober": "^2.1.16", "solid-js": "^1.9.9" } }, "sha512-qfTiloj5d+bmrFOaQ/ZfY4IO3W62Ef4878FLMYq/mwZaaVjzb3AhMrar0jPWhTc/n3HOzrmPZGWru2OAdLUYmg=="],
"@tanstack/devtools-client": ["@tanstack/devtools-client@0.0.3", "", { "dependencies": { "@tanstack/devtools-event-client": "^0.3.3" } }, "sha512-kl0r6N5iIL3t9gGDRAv55VRM3UIyMKVH83esRGq7xBjYsRLe/BeCIN2HqrlJkObUXQMKhy7i8ejuGOn+bDqDBw=="],
@@ -359,13 +328,13 @@
"@tanstack/devtools-event-client": ["@tanstack/devtools-event-client@0.3.3", "", {}, "sha512-RfV+OPV/M3CGryYqTue684u10jUt55PEqeBOnOtCe6tAmHI9Iqyc8nHeDhWPEV9715gShuauFVaMc9RiUVNdwg=="],
- "@tanstack/devtools-ui": ["@tanstack/devtools-ui@0.4.3", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16", "solid-js": "^1.9.9" } }, "sha512-7QshnQIHifURyMwl/qmYm4KDpsf8UJrJ8BUu+YvPx35RJBe2EO5qHPsefzWh6MlG/dUdVMBxP9nPqchESyuNFg=="],
+ "@tanstack/devtools-ui": ["@tanstack/devtools-ui@0.4.4", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16", "solid-js": "^1.9.9" } }, "sha512-5xHXFyX3nom0UaNfiOM92o6ziaHjGo3mcSGe2HD5Xs8dWRZNpdZ0Smd0B9ddEhy0oB+gXyMzZgUJb9DmrZV0Mg=="],
"@tanstack/devtools-vite": ["@tanstack/devtools-vite@0.3.10", "", { "dependencies": { "@babel/core": "^7.28.4", "@babel/generator": "^7.28.3", "@babel/parser": "^7.28.4", "@babel/traverse": "^7.28.4", "@babel/types": "^7.28.4", "@tanstack/devtools-client": "0.0.3", "@tanstack/devtools-event-bus": "0.3.3", "chalk": "^5.6.2", "launch-editor": "^2.11.1", "picomatch": "^4.0.3" }, "peerDependencies": { "vite": "^6.0.0 || ^7.0.0" } }, "sha512-vFPYqzFU5FaK0jzMgCA26V5s244P8Ah5cG7eY2oLJrZ6DJ3Wh3UI4W4xqFKzRfQHmgjlndW3/S37eSh5MSFkgQ=="],
"@tanstack/form-core": ["@tanstack/form-core@1.24.4", "", { "dependencies": { "@tanstack/devtools-event-client": "^0.3.3", "@tanstack/pacer": "^0.15.3", "@tanstack/store": "^0.7.7" } }, "sha512-+eIR7DiDamit1zvTVgaHxuIRA02YFgJaXMUGxsLRJoBpUjGl/g/nhUocQoNkRyfXqOlh8OCMTanjwDprWSRq6w=="],
- "@tanstack/history": ["@tanstack/history@1.133.19", "", {}, "sha512-Y866qBVVprdQkmO0/W1AFBI8tiQy398vFeIwP+VrRWCOzs3VecxSVzAvaOM4iHfkJz81fFAZMhLLjDVoPikD+w=="],
+ "@tanstack/history": ["@tanstack/history@1.133.28", "", {}, "sha512-B7+x7eP2FFvi3fgd3rNH9o/Eixt+pp0zCIdGhnQbAJjFrlwIKGjGnwyJjhWJ5fMQlGks/E2LdDTqEV4W9Plx7g=="],
"@tanstack/pacer": ["@tanstack/pacer@0.15.4", "", { "dependencies": { "@tanstack/devtools-event-client": "^0.3.2", "@tanstack/store": "^0.7.5" } }, "sha512-vGY+CWsFZeac3dELgB6UZ4c7OacwsLb8hvL2gLS6hTgy8Fl0Bm/aLokHaeDIP+q9F9HUZTnp360z9uv78eg8pg=="],
@@ -373,7 +342,7 @@
"@tanstack/query-devtools": ["@tanstack/query-devtools@5.90.1", "", {}, "sha512-GtINOPjPUH0OegJExZ70UahT9ykmAhmtNVcmtdnOZbxLwT7R5OmRztR5Ahe3/Cu7LArEmR6/588tAycuaWb1xQ=="],
- "@tanstack/react-devtools": ["@tanstack/react-devtools@0.7.8", "", { "dependencies": { "@tanstack/devtools": "0.6.22" }, "peerDependencies": { "@types/react": ">=16.8", "@types/react-dom": ">=16.8", "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-/G5Z6NOK5puJHpAykD0zEvmi+v53MfwsAbgSzrlLD1+UqKKh1BA63TdTqGz52mLxfQTfvW5jDRyCFV0fHZFqEw=="],
+ "@tanstack/react-devtools": ["@tanstack/react-devtools@0.7.9", "", { "dependencies": { "@tanstack/devtools": "0.6.23" }, "peerDependencies": { "@types/react": ">=16.8", "@types/react-dom": ">=16.8", "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-zJLb/t/vjRjdUAkKcKoz1fdZw/jroTeNMqKTh+vJ5oqlekzs7ER7Fvz2+WJ/iUuQmOP41oPNuFTLeWr4Nclqng=="],
"@tanstack/react-form": ["@tanstack/react-form@1.23.8", "", { "dependencies": { "@tanstack/form-core": "1.24.4", "@tanstack/react-store": "^0.7.7", "decode-formdata": "^0.9.0", "devalue": "^5.3.2" }, "peerDependencies": { "@tanstack/react-start": "^1.130.10", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@tanstack/react-start"] }, "sha512-ivfkiOHAI3aIWkCY4FnPWVAL6SkQWGWNVjtwIZpaoJE4ulukZWZ1KB8TQKs8f4STl+egjTsMHrWJuf2fv3Xh1w=="],
@@ -381,25 +350,25 @@
"@tanstack/react-query-devtools": ["@tanstack/react-query-devtools@5.90.2", "", { "dependencies": { "@tanstack/query-devtools": "5.90.1" }, "peerDependencies": { "@tanstack/react-query": "^5.90.2", "react": "^18 || ^19" } }, "sha512-vAXJzZuBXtCQtrY3F/yUNJCV4obT/A/n81kb3+YqLbro5Z2+phdAbceO+deU3ywPw8B42oyJlp4FhO0SoivDFQ=="],
- "@tanstack/react-router": ["@tanstack/react-router@1.133.27", "", { "dependencies": { "@tanstack/history": "1.133.19", "@tanstack/react-store": "^0.7.0", "@tanstack/router-core": "1.133.27", "isbot": "^5.1.22", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-0q87mjJWhMsnP9SOD/v07lclCxrMuB20CdKi305cTZRIF858ETG0fThUF4LlstiKvxE49Wr+PBY0kwjfY4pUow=="],
+ "@tanstack/react-router": ["@tanstack/react-router@1.133.36", "", { "dependencies": { "@tanstack/history": "1.133.28", "@tanstack/react-store": "^0.8.0", "@tanstack/router-core": "1.133.36", "isbot": "^5.1.22", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-pT4d2uEucDQ3SAIQ0pLUw6RUKwkB5pHzpBB6otaoKpO0cAwHkRPi+p59DivuzSANJLHLVEiXyJCCk72EeHMRxA=="],
- "@tanstack/react-router-devtools": ["@tanstack/react-router-devtools@1.133.27", "", { "dependencies": { "@tanstack/router-devtools-core": "1.133.27", "vite": "^7.1.7" }, "peerDependencies": { "@tanstack/react-router": "^1.133.27", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-K1uDpqzvdB0bf5J00rH3pMHE0IOB0ke8Ej0VZ43loRACIY7YqqYlOFvKFVxQwI8GTGzxNs5J9uJ7Ms0+w0eH2A=="],
+ "@tanstack/react-router-devtools": ["@tanstack/react-router-devtools@1.133.36", "", { "dependencies": { "@tanstack/router-devtools-core": "1.133.36", "vite": "^7.1.7" }, "peerDependencies": { "@tanstack/react-router": "^1.133.36", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-il+DNzc8Ia54N+HOmIlY10NBk7rp0N7Nyysk8eeC1ZSIXImC3MPchdAspwioE6DI7WfK+MfpTav2m9zoOL8wSQ=="],
"@tanstack/react-store": ["@tanstack/react-store@0.7.7", "", { "dependencies": { "@tanstack/store": "0.7.7", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-qqT0ufegFRDGSof9D/VqaZgjNgp4tRPHZIJq2+QIHkMUtHjaJ0lYrrXjeIUJvjnTbgPfSD1XgOMEt0lmANn6Zg=="],
"@tanstack/react-virtual": ["@tanstack/react-virtual@3.13.12", "", { "dependencies": { "@tanstack/virtual-core": "3.13.12" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA=="],
- "@tanstack/router-core": ["@tanstack/router-core@1.133.27", "", { "dependencies": { "@tanstack/history": "1.133.19", "@tanstack/store": "^0.7.0", "cookie-es": "^2.0.0", "seroval": "^1.3.2", "seroval-plugins": "^1.3.2", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" } }, "sha512-1nb2CirHC0hZmFr8wEk0gxuExpvuk0jlKOY1+SQ7jcJCxBKHLGvAfhL6ycets3XetrTLzgBEvfuixFj3qYiFwA=="],
+ "@tanstack/router-core": ["@tanstack/router-core@1.133.36", "", { "dependencies": { "@tanstack/history": "1.133.28", "@tanstack/store": "^0.8.0", "cookie-es": "^2.0.0", "seroval": "^1.3.2", "seroval-plugins": "^1.3.2", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" } }, "sha512-VJ9kFduePsxgjhDW+uKxL6ol9ZpJlaUO2EI9Zmq8AA6uhW/LRg+0/365OZOZaVqNqvx2eKt3MZKHLN+29jd5Uw=="],
- "@tanstack/router-devtools-core": ["@tanstack/router-devtools-core@1.133.27", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16", "vite": "^7.1.7" }, "peerDependencies": { "@tanstack/router-core": "^1.133.27", "csstype": "^3.0.10", "solid-js": ">=1.9.5", "tiny-invariant": "^1.3.3" }, "optionalPeers": ["csstype"] }, "sha512-mYTQnZ8yQbIGNOmLcYv/V8q96qGH+wixgJUeNqUdbZ3/TrzVLaSENRId5ZXD8mx8o2Ljqy2BwZq5d+zDDaKseA=="],
+ "@tanstack/router-devtools-core": ["@tanstack/router-devtools-core@1.133.36", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16", "vite": "^7.1.7" }, "peerDependencies": { "@tanstack/router-core": "^1.133.36", "csstype": "^3.0.10", "solid-js": ">=1.9.5", "tiny-invariant": "^1.3.3" }, "optionalPeers": ["csstype"] }, "sha512-jgXSCfWPLukcjXDf4thpk/0QgLXv61mrvmfh9xc8+xeC5TMeLyz2xBaTghniD2PtdF6eII3vMaTWOpMHj4+cVQ=="],
- "@tanstack/router-generator": ["@tanstack/router-generator@1.133.27", "", { "dependencies": { "@tanstack/router-core": "1.133.27", "@tanstack/router-utils": "1.133.19", "@tanstack/virtual-file-routes": "1.133.19", "prettier": "^3.5.0", "recast": "^0.23.11", "source-map": "^0.7.4", "tsx": "^4.19.2", "zod": "^3.24.2" } }, "sha512-+0dq0DlKzD5fk9vRKHv+vG4ANUNnwnqTqzqTMRiZfYJ16oIfcIQgIdrHRGLdsBLQ6yQIWFszY0d5ubRx0dOK8g=="],
+ "@tanstack/router-generator": ["@tanstack/router-generator@1.133.36", "", { "dependencies": { "@tanstack/router-core": "1.133.36", "@tanstack/router-utils": "1.133.19", "@tanstack/virtual-file-routes": "1.133.19", "prettier": "^3.5.0", "recast": "^0.23.11", "source-map": "^0.7.4", "tsx": "^4.19.2", "zod": "^3.24.2" } }, "sha512-3+pJBqkm95/zV7INyhbr688lp1PklZT3wtNNwW9oIxmsBiUJg5hqHWh7z4JgP9E+0D0KAwT535wncWUFfMMZwA=="],
- "@tanstack/router-plugin": ["@tanstack/router-plugin@1.133.27", "", { "dependencies": { "@babel/core": "^7.27.7", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.27.7", "@babel/types": "^7.27.7", "@tanstack/router-core": "1.133.27", "@tanstack/router-generator": "1.133.27", "@tanstack/router-utils": "1.133.19", "@tanstack/virtual-file-routes": "1.133.19", "babel-dead-code-elimination": "^1.0.10", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.2" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.133.27", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0", "vite-plugin-solid": "^2.11.10", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-E3WdABr7Vm9UijQKSjoP2Pvq5l1m8cIm/YZIDbcJ3zVQpTKMtSVgWzP1lQUtsUBrU21PBPHsOhc1+ERt832pKQ=="],
+ "@tanstack/router-plugin": ["@tanstack/router-plugin@1.133.36", "", { "dependencies": { "@babel/core": "^7.27.7", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.27.7", "@babel/types": "^7.27.7", "@tanstack/router-core": "1.133.36", "@tanstack/router-generator": "1.133.36", "@tanstack/router-utils": "1.133.19", "@tanstack/virtual-file-routes": "1.133.19", "babel-dead-code-elimination": "^1.0.10", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.2" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.133.36", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0", "vite-plugin-solid": "^2.11.10", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-y0vttpDRFbniPk2EOS93wxfNA0SqvD/anj6kXTIl/3caW0rvOC4MzMXV09atJ+3jMSOgHFniljKQj/66AY5dZg=="],
"@tanstack/router-utils": ["@tanstack/router-utils@1.133.19", "", { "dependencies": { "@babel/core": "^7.27.4", "@babel/generator": "^7.27.5", "@babel/parser": "^7.27.5", "@babel/preset-typescript": "^7.27.1", "ansis": "^4.1.0", "diff": "^8.0.2", "pathe": "^2.0.3", "tinyglobby": "^0.2.15" } }, "sha512-WEp5D2gPxvlLDRXwD/fV7RXjYtqaqJNXKB/L6OyZEbT+9BG/Ib2d7oG9GSUZNNMGPGYAlhBUOi3xutySsk6rxA=="],
- "@tanstack/store": ["@tanstack/store@0.7.7", "", {}, "sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ=="],
+ "@tanstack/store": ["@tanstack/store@0.8.0", "", {}, "sha512-Om+BO0YfMZe//X2z0uLF2j+75nQga6TpTJgLJQBiq85aOyZNIhkCgleNcud2KQg4k4v9Y9l+Uhru3qWMPGTOzQ=="],
"@tanstack/virtual-core": ["@tanstack/virtual-core@3.13.12", "", {}, "sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA=="],
@@ -431,21 +400,21 @@
"@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.9.1", "", { "os": "win32", "cpu": "x64" }, "sha512-/JHlOzpUDhjBOO9w167bcYxfJbcMQv7ykS/Y07xjtcga8np0rzUzVGWYmLMH7orKcDMC7wjhheEW1x8cbGma/Q=="],
- "@tauri-apps/plugin-dialog": ["@tauri-apps/plugin-dialog@2.4.0", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-OvXkrEBfWwtd8tzVCEXIvRfNEX87qs2jv6SqmVPiHcJjBhSF/GUvjqUNIDmKByb5N8nvDqVUM7+g1sXwdC/S9w=="],
+ "@tauri-apps/plugin-dialog": ["@tauri-apps/plugin-dialog@2.4.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-lNIn5CZuw8WZOn8zHzmFmDSzg5zfohWoa3mdULP0YFh/VogVdMVWZPcWSHlydsiJhRQYaTNSYKN7RmZKE2lCYQ=="],
- "@tauri-apps/plugin-fs": ["@tauri-apps/plugin-fs@2.4.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-YGhmYuTgXGsi6AjoV+5mh2NvicgWBfVJHHheuck6oHD+HC9bVWPaHvCP0/Aw4pHDejwrvT8hE3+zZAaWf+hrig=="],
+ "@tauri-apps/plugin-fs": ["@tauri-apps/plugin-fs@2.4.4", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-MTorXxIRmOnOPT1jZ3w96vjSuScER38ryXY88vl5F0uiKdnvTKKTtaEjTEo8uPbl4e3gnUtfsDVwC7h77GQLvQ=="],
- "@tauri-apps/plugin-opener": ["@tauri-apps/plugin-opener@2.5.0", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-B0LShOYae4CZjN8leiNDbnfjSrTwoZakqKaWpfoH6nXiJwt6Rgj6RnVIffG3DoJiKsffRhMkjmBV9VeilSb4TA=="],
+ "@tauri-apps/plugin-opener": ["@tauri-apps/plugin-opener@2.5.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-ei/yRRoCklWHImwpCcDK3VhNXx+QXM9793aQ64YxpqVF0BDuuIlXhZgiAkc15wnPVav+IbkYhmDJIv5R326Mew=="],
- "@tauri-apps/plugin-os": ["@tauri-apps/plugin-os@2.3.1", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-ty5V8XDUIFbSnrk3zsFoP3kzN+vAufYzalJSlmrVhQTImIZa1aL1a03bOaP2vuBvfR+WDRC6NgV2xBl8G07d+w=="],
+ "@tauri-apps/plugin-os": ["@tauri-apps/plugin-os@2.3.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-n+nXWeuSeF9wcEsSPmRnBEGrRgOy6jjkSU+UVCOV8YUGKb2erhDOxis7IqRXiRVHhY8XMKks00BJ0OAdkpf6+A=="],
- "@tauri-apps/plugin-process": ["@tauri-apps/plugin-process@2.3.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-0DNj6u+9csODiV4seSxxRbnLpeGYdojlcctCuLOCgpH9X3+ckVZIEj6H7tRQ7zqWr7kSTEWnrxtAdBb0FbtrmQ=="],
+ "@tauri-apps/plugin-process": ["@tauri-apps/plugin-process@2.3.1", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA=="],
- "@tauri-apps/plugin-shell": ["@tauri-apps/plugin-shell@2.3.1", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-jjs2WGDO/9z2pjNlydY/F5yYhNsscv99K5lCmU5uKjsVvQ3dRlDhhtVYoa4OLDmktLtQvgvbQjCFibMl6tgGfw=="],
+ "@tauri-apps/plugin-shell": ["@tauri-apps/plugin-shell@2.3.3", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-Xod+pRcFxmOWFWEnqH5yZcA7qwAMuaaDkMR1Sply+F8VfBj++CGnj2xf5UoialmjZ2Cvd8qrvSCbU+7GgNVsKQ=="],
"@tauri-apps/plugin-updater": ["@tauri-apps/plugin-updater@2.9.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-j++sgY8XpeDvzImTrzWA08OqqGqgkNyxczLD7FjNJJx/uXxMZFz5nDcfkyoI/rCjYuj2101Tci/r/HFmOmoxCg=="],
- "@tauri-apps/plugin-window-state": ["@tauri-apps/plugin-window-state@2.4.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-hRSzPNi2NG0lPFthfVY0V5C1MyWN/gGaQtQYw7i9zZhLzrhZveHZ2omHG1rIiIsjfTGbO7fhjydSoeTTK9GqLw=="],
+ "@tauri-apps/plugin-window-state": ["@tauri-apps/plugin-window-state@2.4.1", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-OuvdrzyY8Q5Dbzpj+GcrnV1iCeoZbcFdzMjanZMMcAEUNy/6PH5pxZPXpaZLOR7whlzXiuzx0L9EKZbH7zpdRw=="],
"@tauri-store/shared": ["@tauri-store/shared@0.10.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0", "es-toolkit": "^1.39.10" } }, "sha512-hnEBbe/m9UG5ATSBp4yJOosLkX5QLblVsGIvz7mtBAqmzeWFfjP4+8X/T81L+bCH6+ref/0vsR9Ekex138kAfg=="],
@@ -475,8 +444,6 @@
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
- "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="],
-
"ast-types": ["ast-types@0.16.1", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg=="],
"babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.10", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-DV5bdJZTzZ0zn0DC24v3jD7Mnidh6xhKa4GfKCbq3sfW8kaWhDdZjP3i81geA8T33tdYqWKw4D3fVv0CwEgKVA=="],
@@ -497,8 +464,6 @@
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
- "cmdk": ["cmdk@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "^1.1.1", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-id": "^1.1.0", "@radix-ui/react-primitive": "^2.0.2" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg=="],
-
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
"cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="],
@@ -513,8 +478,6 @@
"detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="],
- "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="],
-
"devalue": ["devalue@5.3.2", "", {}, "sha512-UDsjUbpQn9kvm68slnrs+mfxwFkIflOhkanmyabZ8zOYk8SMEIbJ3TK+88g70hSIeytu4y18f0z/hYHMTrXIWw=="],
"diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="],
@@ -541,8 +504,6 @@
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
- "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="],
-
"get-tsconfig": ["get-tsconfig@4.10.1", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ=="],
"glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
@@ -659,12 +620,6 @@
"react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="],
- "react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="],
-
- "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="],
-
- "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="],
-
"readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
"recast": ["recast@0.23.11", "", { "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", "source-map": "~0.6.1", "tiny-invariant": "^1.3.3", "tslib": "^2.0.1" } }, "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA=="],
@@ -725,10 +680,6 @@
"update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="],
- "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="],
-
- "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="],
-
"use-sync-external-store": ["use-sync-external-store@1.5.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A=="],
"vite": ["vite@7.1.12", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug=="],
@@ -787,26 +738,20 @@
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
- "@tanstack/router-generator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
-
- "@tanstack/router-plugin/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
-
- "@tauri-apps/plugin-dialog/@tauri-apps/api": ["@tauri-apps/api@2.8.0", "", {}, "sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw=="],
+ "@tanstack/form-core/@tanstack/store": ["@tanstack/store@0.7.7", "", {}, "sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ=="],
- "@tauri-apps/plugin-fs/@tauri-apps/api": ["@tauri-apps/api@2.8.0", "", {}, "sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw=="],
+ "@tanstack/pacer/@tanstack/store": ["@tanstack/store@0.7.7", "", {}, "sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ=="],
- "@tauri-apps/plugin-opener/@tauri-apps/api": ["@tauri-apps/api@2.8.0", "", {}, "sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw=="],
+ "@tanstack/react-router/@tanstack/react-store": ["@tanstack/react-store@0.8.0", "", { "dependencies": { "@tanstack/store": "0.8.0", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow=="],
- "@tauri-apps/plugin-os/@tauri-apps/api": ["@tauri-apps/api@2.8.0", "", {}, "sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw=="],
+ "@tanstack/react-store/@tanstack/store": ["@tanstack/store@0.7.7", "", {}, "sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ=="],
- "@tauri-apps/plugin-process/@tauri-apps/api": ["@tauri-apps/api@2.8.0", "", {}, "sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw=="],
+ "@tanstack/router-generator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
- "@tauri-apps/plugin-shell/@tauri-apps/api": ["@tauri-apps/api@2.8.0", "", {}, "sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw=="],
+ "@tanstack/router-plugin/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
"@tauri-apps/plugin-updater/@tauri-apps/api": ["@tauri-apps/api@2.8.0", "", {}, "sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw=="],
- "@tauri-apps/plugin-window-state/@tauri-apps/api": ["@tauri-apps/api@2.8.0", "", {}, "sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw=="],
-
"@tauri-store/shared/@tauri-apps/api": ["@tauri-apps/api@2.8.0", "", {}, "sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw=="],
"@tauri-store/zustand/@tauri-apps/api": ["@tauri-apps/api@2.8.0", "", {}, "sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw=="],
@@ -855,6 +800,8 @@
"@babel/helper-skip-transparent-expression-wrappers/@babel/traverse/@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="],
+ "@tanstack/react-router/@tanstack/react-store/use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="],
+
"babel-dead-code-elimination/@babel/core/@babel/helpers": ["@babel/helpers@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.2" } }, "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw=="],
}
}
diff --git a/package.json b/package.json
index 7d7f9ce..461b61a 100644
--- a/package.json
+++ b/package.json
@@ -8,26 +8,25 @@
"@monaco-editor/react": "^4.7.0",
"@radix-ui/react-slot": "^1.2.3",
"@tailwindcss/vite": "^4.1.16",
- "@tanstack/react-devtools": "^0.7.8",
+ "@tanstack/react-devtools": "^0.7.9",
"@tanstack/react-form": "^1.23.8",
"@tanstack/react-query": "^5.90.5",
"@tanstack/react-query-devtools": "^5.90.2",
- "@tanstack/react-router": "^1.133.27",
- "@tanstack/react-router-devtools": "^1.133.27",
+ "@tanstack/react-router": "^1.133.36",
+ "@tanstack/react-router-devtools": "^1.133.36",
"@tanstack/react-virtual": "^3.13.12",
"@tauri-apps/api": "^2.9.0",
- "@tauri-apps/plugin-dialog": "~2",
- "@tauri-apps/plugin-fs": "~2.4.2",
- "@tauri-apps/plugin-opener": "~2",
- "@tauri-apps/plugin-os": "~2.3.1",
- "@tauri-apps/plugin-process": "~2",
- "@tauri-apps/plugin-shell": "~2.3.1",
+ "@tauri-apps/plugin-dialog": "~2.4.2",
+ "@tauri-apps/plugin-fs": "~2.4.4",
+ "@tauri-apps/plugin-opener": "~2.5.2",
+ "@tauri-apps/plugin-os": "~2.3.2",
+ "@tauri-apps/plugin-process": "~2.3.1",
+ "@tauri-apps/plugin-shell": "~2.3.3",
"@tauri-apps/plugin-updater": "~2",
- "@tauri-apps/plugin-window-state": "^2.4.0",
+ "@tauri-apps/plugin-window-state": "^2.4.1",
"@tauri-store/zustand": "^1.0.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
- "cmdk": "^1.1.1",
"date-fns": "^4.1.0",
"input-otp": "^1.4.2",
"lucide-react": "^0.548.0",
@@ -41,9 +40,9 @@
"zustand": "^5.0.8"
},
"devDependencies": {
- "@biomejs/biome": "^2.3.0",
+ "@biomejs/biome": "^2.3.2",
"@tanstack/devtools-vite": "^0.3.10",
- "@tanstack/router-plugin": "^1.133.27",
+ "@tanstack/router-plugin": "^1.133.36",
"@tauri-apps/cli": "^2.9.1",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
diff --git a/src/components/ui/command.tsx b/src/components/ui/command.tsx
deleted file mode 100644
index 7515989..0000000
--- a/src/components/ui/command.tsx
+++ /dev/null
@@ -1,194 +0,0 @@
-import { Command as CommandPrimitive } from "cmdk";
-import { SearchIcon } from "lucide-react";
-import type * as React from "react";
-import {
- Dialog,
- DialogContent,
- DialogDescription,
- DialogHeader,
- DialogTitle,
-} from "@/components/ui/dialog";
-import { cn } from "@/lib/utils";
-
-function Command({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function CommandDialog({
- title = "Command Palette",
- description = "Search for a command to run...",
- children,
- className,
- showCloseButton = true,
- ...props
-}: React.ComponentProps & {
- title?: string;
- description?: string;
- className?: string;
- showCloseButton?: boolean;
-}) {
- return (
-
-
- {title}
- {description}
-
-
-
- {children}
-
-
-
- );
-}
-
-function CommandInput({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
-
-
-
- );
-}
-
-function CommandList({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function CommandEmpty({
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function CommandGroup({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function CommandLoading({
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function CommandSeparator({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function CommandItem({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function CommandShortcut({
- className,
- ...props
-}: React.ComponentProps<"span">) {
- return (
-
- );
-}
-
-export {
- Command,
- CommandDialog,
- CommandInput,
- CommandList,
- CommandEmpty,
- CommandGroup,
- CommandItem,
- CommandShortcut,
- CommandSeparator,
- CommandLoading,
-};
diff --git a/src/components/ui/multi-select.tsx b/src/components/ui/multi-select.tsx
deleted file mode 100644
index cf35d07..0000000
--- a/src/components/ui/multi-select.tsx
+++ /dev/null
@@ -1,653 +0,0 @@
-import { Command as CommandPrimitive, useCommandState } from "cmdk";
-import { ChevronDownIcon, X } from "lucide-react";
-import * as React from "react";
-import { forwardRef, useEffect } from "react";
-
-import { Badge } from "@/components/ui/badge";
-import {
- Command,
- CommandGroup,
- CommandItem,
- CommandList,
-} from "@/components/ui/command";
-import { cn } from "@/lib/utils";
-
-export interface Option {
- value: string;
- label: string;
- disable?: boolean;
- /** fixed option that can't be removed. */
- fixed?: boolean;
- /** Group the options by providing key. */
- [key: string]: string | boolean | undefined;
-}
-interface GroupOption {
- [key: string]: Option[];
-}
-
-interface MultipleSelectorProps {
- value?: Option[];
- defaultOptions?: Option[];
- /** manually controlled options */
- options?: Option[];
- placeholder?: string;
- /** Loading component. */
- loadingIndicator?: React.ReactNode;
- /** Empty component. */
- emptyIndicator?: React.ReactNode;
- /** Debounce time for async search. Only work with `onSearch`. */
- delay?: number;
- /**
- * Only work with `onSearch` prop. Trigger search when `onFocus`.
- * For example, when user click on the input, it will trigger the search to get initial options.
- **/
- triggerSearchOnFocus?: boolean;
- /** async search */
- onSearch?: (value: string) => Promise;
- /**
- * sync search. This search will not showing loadingIndicator.
- * The rest props are the same as async search.
- * i.e.: creatable, groupBy, delay.
- **/
- onSearchSync?: (value: string) => Option[];
- onChange?: (options: Option[]) => void;
- /** Limit the maximum number of selected options. */
- maxSelected?: number;
- /** When the number of selected options exceeds the limit, the onMaxSelected will be called. */
- onMaxSelected?: (maxLimit: number) => void;
- /** Hide the placeholder when there are options selected. */
- hidePlaceholderWhenSelected?: boolean;
- disabled?: boolean;
- /** Group the options base on provided key. */
- groupBy?: string;
- className?: string;
- badgeClassName?: string;
- /**
- * First item selected is a default behavior by cmdk. That is why the default is true.
- * This is a workaround solution by add a dummy item.
- *
- * @reference: https://github.com/pacocoursey/cmdk/issues/171
- */
- selectFirstItem?: boolean;
- /** Allow user to create option when there is no option matched. */
- creatable?: boolean;
- /** Props of `Command` */
- commandProps?: React.ComponentPropsWithoutRef;
- /** Props of `CommandInput` */
- inputProps?: Omit<
- React.ComponentPropsWithoutRef,
- "value" | "placeholder" | "disabled"
- >;
- /** hide the clear all button. */
- hideClearAllButton?: boolean;
-}
-
-export interface MultipleSelectorRef {
- selectedValue: Option[];
- input: HTMLInputElement;
- focus: () => void;
- reset: () => void;
-}
-
-export function useDebounce(value: T, delay?: number): T {
- const [debouncedValue, setDebouncedValue] = React.useState(value);
-
- useEffect(() => {
- const timer = setTimeout(() => setDebouncedValue(value), delay || 500);
-
- return () => {
- clearTimeout(timer);
- };
- }, [value, delay]);
-
- return debouncedValue;
-}
-
-function transToGroupOption(options: Option[], groupBy?: string) {
- if (options.length === 0) {
- return {};
- }
- if (!groupBy) {
- return {
- "": options,
- };
- }
-
- const groupOption: GroupOption = {};
- options.forEach((option) => {
- const key = (option[groupBy] as string) || "";
- if (!groupOption[key]) {
- groupOption[key] = [];
- }
- groupOption[key].push(option);
- });
- return groupOption;
-}
-
-function removePickedOption(groupOption: GroupOption, picked: Option[]) {
- const cloneOption = JSON.parse(JSON.stringify(groupOption)) as GroupOption;
-
- for (const [key, value] of Object.entries(cloneOption)) {
- cloneOption[key] = value.filter(
- (val) => !picked.find((p) => p.value === val.value),
- );
- }
- return cloneOption;
-}
-
-function isOptionsExist(groupOption: GroupOption, targetOption: Option[]) {
- for (const [, value] of Object.entries(groupOption)) {
- if (
- value.some((option) => targetOption.find((p) => p.value === option.value))
- ) {
- return true;
- }
- }
- return false;
-}
-
-/**
- * The `CommandEmpty` of shadcn/ui will cause the cmdk empty not rendering correctly.
- * So we create one and copy the `Empty` implementation from `cmdk`.
- *
- * @reference: https://github.com/hsuanyi-chou/shadcn-ui-expansions/issues/34#issuecomment-1949561607
- **/
-const CommandEmpty = forwardRef<
- HTMLDivElement,
- React.ComponentProps
->(({ className, ...props }, forwardedRef) => {
- const render = useCommandState((state) => state.filtered.count === 0);
-
- if (!render) return null;
-
- return (
-
- );
-});
-
-CommandEmpty.displayName = "CommandEmpty";
-
-const MultipleSelector = React.forwardRef<
- MultipleSelectorRef,
- MultipleSelectorProps
->(
- (
- {
- value,
- onChange,
- placeholder,
- defaultOptions: arrayDefaultOptions = [],
- options: arrayOptions,
- delay,
- onSearch,
- onSearchSync,
- loadingIndicator,
- emptyIndicator,
- maxSelected = Number.MAX_SAFE_INTEGER,
- onMaxSelected,
- hidePlaceholderWhenSelected,
- disabled,
- groupBy,
- className,
- badgeClassName,
- selectFirstItem = true,
- creatable = false,
- triggerSearchOnFocus = false,
- commandProps,
- inputProps,
- hideClearAllButton = false,
- }: MultipleSelectorProps,
- ref: React.Ref,
- ) => {
- const inputRef = React.useRef(null);
- const [open, setOpen] = React.useState(false);
- const [onScrollbar, setOnScrollbar] = React.useState(false);
- const [isLoading, setIsLoading] = React.useState(false);
- const dropdownRef = React.useRef(null); // Added this
-
- const [selected, setSelected] = React.useState(value || []);
- const [options, setOptions] = React.useState(
- transToGroupOption(arrayDefaultOptions, groupBy),
- );
- const [inputValue, setInputValue] = React.useState("");
- const debouncedSearchTerm = useDebounce(inputValue, delay || 500);
-
- React.useImperativeHandle(
- ref,
- () => ({
- focus: () => inputRef?.current?.focus(),
- input: inputRef.current as HTMLInputElement,
- reset: () => setSelected([]),
- selectedValue: [...selected],
- }),
- [selected],
- );
-
- const handleClickOutside = (event: MouseEvent | TouchEvent) => {
- if (
- dropdownRef.current &&
- !dropdownRef.current.contains(event.target as Node) &&
- inputRef.current &&
- !inputRef.current.contains(event.target as Node)
- ) {
- setOpen(false);
- inputRef.current.blur();
- }
- };
-
- const handleUnselect = React.useCallback(
- (option: Option) => {
- const newOptions = selected.filter((s) => s.value !== option.value);
- setSelected(newOptions);
- onChange?.(newOptions);
- },
- [onChange, selected],
- );
-
- const handleKeyDown = React.useCallback(
- (e: React.KeyboardEvent